mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
WIP(teams): very janky multi status
This commit is contained in:
@@ -1,6 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<approval-modal :task="task" />
|
<div
|
||||||
|
v-if="showStatus"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="completion in completionsList"
|
||||||
|
:key="completion.userId"
|
||||||
|
class="completion-row mb-1"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span v-if="completion.completed">✅</span>
|
||||||
|
<span v-else>❎</span>
|
||||||
|
<span>@{{ completion.userName }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if='completion.completedDate'>{{ completion.completedDateString }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="claim-bottom-message d-flex align-items-center"
|
class="claim-bottom-message d-flex align-items-center"
|
||||||
>
|
>
|
||||||
@@ -55,31 +70,19 @@
|
|||||||
color: $gray-100;
|
color: $gray-100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.completion-row { // temporary
|
||||||
.approve-color {
|
height: 2rem;
|
||||||
color: $green-10 !important;
|
|
||||||
}
|
|
||||||
.claim-color {
|
|
||||||
color: $blue-10 !important;
|
|
||||||
}
|
|
||||||
.unclaim-color {
|
|
||||||
color: $red-50 !important;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import findIndex from 'lodash/findIndex';
|
import findIndex from 'lodash/findIndex';
|
||||||
import keys from 'lodash/keys';
|
import keys from 'lodash/keys';
|
||||||
|
import moment from 'moment';
|
||||||
import reduce from 'lodash/reduce';
|
import reduce from 'lodash/reduce';
|
||||||
import { mapState } from '@/libs/store';
|
import { mapState } from '@/libs/store';
|
||||||
import approvalModal from './approvalModal';
|
|
||||||
import sync from '@/mixins/sync';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
|
||||||
approvalModal,
|
|
||||||
},
|
|
||||||
mixins: [sync],
|
|
||||||
props: ['task', 'group'],
|
props: ['task', 'group'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -92,6 +95,10 @@ export default {
|
|||||||
return this.task.group.assignedUsers
|
return this.task.group.assignedUsers
|
||||||
&& Boolean(this.task.group.assignedUsers[this.user._id]);
|
&& Boolean(this.task.group.assignedUsers[this.user._id]);
|
||||||
},
|
},
|
||||||
|
userIsManager () {
|
||||||
|
return this.group
|
||||||
|
&& (this.group.leader.id === this.user._id || this.group.managers[this.user._id]);
|
||||||
|
},
|
||||||
assignedUsersKeys () {
|
assignedUsersKeys () {
|
||||||
return keys(this.task.group.assignedUsers);
|
return keys(this.task.group.assignedUsers);
|
||||||
},
|
},
|
||||||
@@ -104,6 +111,27 @@ export default {
|
|||||||
return count;
|
return count;
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
|
completionsList () {
|
||||||
|
const completionsArray = [];
|
||||||
|
for (const userId of this.assignedUsersKeys) {
|
||||||
|
const index = findIndex(this.group.members, member => member._id === userId);
|
||||||
|
const { completedDate } = this.task.group.assignedUsers[userId];
|
||||||
|
let completedDateString;
|
||||||
|
if (completedDate && moment().diff(completedDate, 'days') > 0) {
|
||||||
|
completedDateString = `Last completed ${moment(completedDate).format('M/D/YY')}`;
|
||||||
|
} else {
|
||||||
|
completedDateString = `Completed today at ${moment(completedDate).format('h:mm A')}`;
|
||||||
|
}
|
||||||
|
completionsArray.push({
|
||||||
|
userId,
|
||||||
|
userName: this.group.members[index].auth.local.username,
|
||||||
|
completed: this.task.group.assignedUsers[userId].completed,
|
||||||
|
completedDate,
|
||||||
|
completedDateString,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return completionsArray;
|
||||||
|
},
|
||||||
message () {
|
message () {
|
||||||
if (this.assignedUsersCount === 1 && !this.userIsAssigned) {
|
if (this.assignedUsersCount === 1 && !this.userIsAssigned) {
|
||||||
const index = findIndex(
|
const index = findIndex(
|
||||||
@@ -120,13 +148,6 @@ export default {
|
|||||||
} // Task is open; we shouldn't be showing message at all
|
} // Task is open; we shouldn't be showing message at all
|
||||||
return this.$t('error');
|
return this.$t('error');
|
||||||
},
|
},
|
||||||
userIsManager () {
|
|
||||||
if (
|
|
||||||
this.group
|
|
||||||
&& (this.group.leader.id === this.user._id || this.group.managers[this.user._id])
|
|
||||||
) return true;
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
<template>
|
|
||||||
<b-modal
|
|
||||||
id="approval-modal"
|
|
||||||
:title="$t('approveTask')"
|
|
||||||
size="md"
|
|
||||||
:hide-footer="true"
|
|
||||||
>
|
|
||||||
<div class="modal-body">
|
|
||||||
<!-- eslint-disable-next-line vue/require-v-for-key -->
|
|
||||||
<div
|
|
||||||
v-for="(approval, index) in task.approvals"
|
|
||||||
class="row approval"
|
|
||||||
>
|
|
||||||
<div class="col-8">
|
|
||||||
<strong>{{ approval.userId.profile.name }}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="col-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-primary"
|
|
||||||
@click="approve(index)"
|
|
||||||
>
|
|
||||||
{{ $t('approve') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary"
|
|
||||||
@click="needsWork(index)"
|
|
||||||
>
|
|
||||||
{{ $t('needsWork') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary"
|
|
||||||
@click="close()"
|
|
||||||
>
|
|
||||||
{{ $t('close') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</b-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.row.approval {
|
|
||||||
padding-top: 1em;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ['task'],
|
|
||||||
methods: {
|
|
||||||
approve (index) {
|
|
||||||
const userIdToApprove = this.task.group.assignedUsers[index];
|
|
||||||
this.$store.dispatch('tasks:approve', {
|
|
||||||
taskId: this.task._id,
|
|
||||||
userId: userIdToApprove,
|
|
||||||
});
|
|
||||||
this.task.group.assignedUsers.splice(index, 1);
|
|
||||||
this.task.approvals.splice(index, 1);
|
|
||||||
},
|
|
||||||
needsWork (index) {
|
|
||||||
if (!window.confirm(this.$t('confirmNeedsWork'))) return; // eslint-disable-line no-alert
|
|
||||||
const userIdNeedsMoreWork = this.task.group.assignedUsers[index];
|
|
||||||
this.$store.dispatch('tasks:needsWork', {
|
|
||||||
taskId: this.task._id,
|
|
||||||
userId: userIdNeedsMoreWork,
|
|
||||||
});
|
|
||||||
this.task.approvals.splice(index, 1);
|
|
||||||
},
|
|
||||||
close () {
|
|
||||||
this.$root.$emit('bv::hide::modal', 'approval-modal');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -889,6 +889,7 @@ import lockIcon from '@/assets/svg/lock.svg';
|
|||||||
import menuIcon from '@/assets/svg/menu.svg';
|
import menuIcon from '@/assets/svg/menu.svg';
|
||||||
import markdownDirective from '@/directives/markdown';
|
import markdownDirective from '@/directives/markdown';
|
||||||
import scoreTask from '@/mixins/scoreTask';
|
import scoreTask from '@/mixins/scoreTask';
|
||||||
|
import sync from '@/mixins/sync';
|
||||||
import approvalFooter from './approvalFooter';
|
import approvalFooter from './approvalFooter';
|
||||||
import MenuDropdown from '../ui/customMenuDropdown';
|
import MenuDropdown from '../ui/customMenuDropdown';
|
||||||
|
|
||||||
@@ -900,7 +901,7 @@ export default {
|
|||||||
directives: {
|
directives: {
|
||||||
markdown: markdownDirective,
|
markdown: markdownDirective,
|
||||||
},
|
},
|
||||||
mixins: [scoreTask],
|
mixins: [scoreTask, sync],
|
||||||
// @TODO: maybe we should store the group on state?
|
// @TODO: maybe we should store the group on state?
|
||||||
props: {
|
props: {
|
||||||
task: {},
|
task: {},
|
||||||
@@ -1142,7 +1143,10 @@ export default {
|
|||||||
this.task.completed = !this.task.completed;
|
this.task.completed = !this.task.completed;
|
||||||
this.playTaskScoreSound(this.task, direction);
|
this.playTaskScoreSound(this.task, direction);
|
||||||
} else {
|
} else {
|
||||||
this.taskScore(this.task, direction);
|
await this.taskScore(this.task, direction);
|
||||||
|
}
|
||||||
|
if (direction === 'down' && ['daily', 'todo'].includes(this.task.type)) {
|
||||||
|
this.sync();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleBrokenTask (task) {
|
handleBrokenTask (task) {
|
||||||
|
|||||||
Reference in New Issue
Block a user