mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-04-14 11:36:45 +00:00
WIP(teams): display assigned tasks on user's personal board
This commit is contained in:
parent
9fec111c4d
commit
a0177fa44d
12 changed files with 106 additions and 136 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import clone from 'lodash/clone';
|
||||
import filter from 'lodash/filter';
|
||||
import find from 'lodash/find';
|
||||
import isArray from 'lodash/isArray';
|
||||
|
|
@ -20,19 +19,26 @@ async function updateTeamTasks (team) {
|
|||
boardTask.group.assignedDate = undefined;
|
||||
boardTask.group.assigningUsername = undefined;
|
||||
boardTask.group.sharedCompletion = undefined;
|
||||
const assignedUsers = clone(boardTask.group.assignedUsers);
|
||||
boardTask.group.assignedUsers = null;
|
||||
for (const assignedUser of assignedUsers) {
|
||||
|
||||
for (const assignedUser of boardTask.group.assignedUsers) {
|
||||
const userTask = find(teamUserTasks, task => task.userId === assignedUser
|
||||
&& task.group.taskId === boardTask._id);
|
||||
if (!boardTask.group.assignedUsersDetail) boardTask.group.assignedUsersDetail = {};
|
||||
if (userTask) {
|
||||
if (!boardTask.group.assignedUsers) boardTask.group.assignedUsers = {};
|
||||
boardTask.group.assignedUsers[assignedUser] = {
|
||||
boardTask.group.assignedUsersDetail[assignedUser] = {
|
||||
assignedDate: userTask.group.assignedDate,
|
||||
assigningUsername: userTask.group.assigningUsername,
|
||||
completed: userTask.completed || false,
|
||||
completedDate: userTask.dateCompleted,
|
||||
};
|
||||
toSave.push(Tasks.Task.findByIdAndDelete(userTask._id));
|
||||
} else {
|
||||
boardTask.group.assignedUsersDetail[assignedUser] = {
|
||||
assignedDate: new Date(),
|
||||
assigningUsername: null,
|
||||
completed: false,
|
||||
completedDate: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
boardTask.markModified('group');
|
||||
|
|
|
|||
|
|
@ -54,16 +54,16 @@ async function updateTeamTasks (team) {
|
|||
let processChecklist = false;
|
||||
let assignments = 0;
|
||||
let completions = 0;
|
||||
for (const assignedUser in daily.group.assignedUsers) {
|
||||
if (Object.prototype.hasOwnProperty.call(daily.group.assignedUsers, assignedUser)) {
|
||||
for (const assignedUser in daily.group.assignedUsersDetail) {
|
||||
if (Object.prototype.hasOwnProperty.call(daily.group.assignedUsersDetail, assignedUser)) {
|
||||
assignments += 1;
|
||||
if (daily.group.assignedUsers[assignedUser].completed) {
|
||||
if (daily.group.assignedUsersDetail[assignedUser].completed) {
|
||||
completions += 1;
|
||||
daily.group.assignedUsers[assignedUser].completed = false;
|
||||
daily.group.assignedUsersDetail[assignedUser].completed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (completions > 0) daily.markModified('group.assignedUsers');
|
||||
if (completions > 0) daily.markModified('group.assignedUsersDetail');
|
||||
if (daily.completed) {
|
||||
processChecklist = true;
|
||||
daily.completed = false;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
</div>
|
||||
<div
|
||||
class="claim-bottom-message d-flex align-items-center"
|
||||
v-if="group"
|
||||
>
|
||||
<div
|
||||
class="mr-auto ml-2"
|
||||
|
|
@ -215,8 +214,6 @@
|
|||
</style>
|
||||
|
||||
<script>
|
||||
import findIndex from 'lodash/findIndex';
|
||||
import keys from 'lodash/keys';
|
||||
import moment from 'moment';
|
||||
import reduce from 'lodash/reduce';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
|
@ -239,21 +236,18 @@ export default {
|
|||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
userIsAssigned () {
|
||||
return this.task.group.assignedUsers
|
||||
&& Boolean(this.task.group.assignedUsers[this.user._id]);
|
||||
return this.task.group.assignedUsersDetail
|
||||
&& Boolean(this.task.group.assignedUsersDetail[this.user._id]);
|
||||
},
|
||||
userIsManager () {
|
||||
return this.group
|
||||
&& (this.group.leader.id === this.user._id || this.group.managers[this.user._id]);
|
||||
},
|
||||
assignedUsersKeys () {
|
||||
return keys(this.task.group.assignedUsers);
|
||||
},
|
||||
assignedUsersCount () {
|
||||
return this.assignedUsersKeys.length;
|
||||
return this.task.group.assignedUsers.length;
|
||||
},
|
||||
completionsCount () {
|
||||
return reduce(this.task.group.assignedUsers, (count, assignment) => {
|
||||
return reduce(this.task.group.assignedUsersDetail, (count, assignment) => {
|
||||
if (assignment.completed) return count + 1;
|
||||
return count;
|
||||
}, 0);
|
||||
|
|
@ -261,10 +255,9 @@ export default {
|
|||
completionsList () {
|
||||
if (this.assignedUsersCount === 1) return [];
|
||||
const completionsArray = [];
|
||||
for (const userId of this.assignedUsersKeys) {
|
||||
for (const userId of this.task.group.assignedUsers) {
|
||||
if (userId !== this.user._id) {
|
||||
const index = findIndex(this.group.members, member => member._id === userId);
|
||||
const { completedDate } = this.task.group.assignedUsers[userId];
|
||||
const { completedDate } = this.task.group.assignedUsersDetail[userId];
|
||||
let completedDateString;
|
||||
if (moment().diff(completedDate, 'days') > 0) {
|
||||
completedDateString = `Completed ${moment(completedDate).format('M/D/YY')}`;
|
||||
|
|
@ -273,8 +266,8 @@ export default {
|
|||
}
|
||||
completionsArray.push({
|
||||
userId,
|
||||
userName: this.group.members[index].auth.local.username,
|
||||
completed: this.task.group.assignedUsers[userId].completed,
|
||||
userName: this.task.group.assignedUsersDetail[userId].assignedUsername,
|
||||
completed: this.task.group.assignedUsersDetail[userId].completed,
|
||||
completedDate,
|
||||
completedDateString,
|
||||
});
|
||||
|
|
@ -290,14 +283,11 @@ export default {
|
|||
return this.$t('assignedToMembers', { userCount: this.assignedUsersCount });
|
||||
}
|
||||
if (this.assignedUsersCount === 1) { // Singly assigned
|
||||
const userId = this.assignedUsersKeys[0];
|
||||
const index = findIndex(
|
||||
this.group.members, member => member._id === userId,
|
||||
);
|
||||
const userName = this.group.members[index].auth.local.username;
|
||||
const userId = this.task.group.assignedUsers[0];
|
||||
const userName = this.task.group.assignedUsersDetail[userId].assignedUsername;
|
||||
|
||||
if (this.task.group.assignedUsers[userId].completed) { // completed
|
||||
const { completedDate } = this.task.group.assignedUsers[userId];
|
||||
if (this.task.group.assignedUsersDetail[userId].completed) { // completed
|
||||
const { completedDate } = this.task.group.assignedUsersDetail[userId];
|
||||
if (this.userIsAssigned) {
|
||||
if (moment().diff(completedDate, 'days') > 0) {
|
||||
return `<strong>You</strong> completed ${moment(completedDate).format('M/D/YY')}`;
|
||||
|
|
@ -317,8 +307,8 @@ export default {
|
|||
return this.$t('error'); // task is open, or the other conditions aren't hitting right
|
||||
},
|
||||
singleAssignLastDone () {
|
||||
const userId = this.assignedUsersKeys[0];
|
||||
const completion = this.task.group.assignedUsers[userId];
|
||||
const userId = this.task.group.assignedUsers[0];
|
||||
const completion = this.task.group.assignedUsersDetail[userId];
|
||||
return completion.completedDate;
|
||||
},
|
||||
showGreen () {
|
||||
|
|
@ -343,7 +333,7 @@ export default {
|
|||
taskId: this.task._id,
|
||||
userId: completion.userId,
|
||||
});
|
||||
this.task.group.assignedUsers[completion.userId].completed = false;
|
||||
this.task.group.assignedUsersDetail[completion.userId].completed = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@
|
|||
<h3
|
||||
v-markdown="task.text"
|
||||
class="task-title markdown"
|
||||
:class="{ 'has-notes': task.notes || (!isUser && task.group.managerNotes)}"
|
||||
:class="{ 'has-notes': task.notes }"
|
||||
></h3>
|
||||
<menu-dropdown
|
||||
v-if="!isRunningYesterdailies && showOptions"
|
||||
|
|
@ -177,7 +177,7 @@
|
|||
</menu-dropdown>
|
||||
</div>
|
||||
<div
|
||||
v-markdown="displayNotes"
|
||||
v-markdown="task.notes"
|
||||
class="task-notes small-text"
|
||||
:class="{'has-checklist': task.notes && hasChecklist}"
|
||||
></div>
|
||||
|
|
@ -889,7 +889,6 @@
|
|||
import moment from 'moment';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import keys from 'lodash/keys';
|
||||
import { mapState, mapGetters, mapActions } from '@/libs/store';
|
||||
|
||||
import positiveIcon from '@/assets/svg/positive.svg';
|
||||
|
|
@ -1056,19 +1055,15 @@ export default {
|
|||
if (!this.group.leader && !this.group.managers) return false;
|
||||
return (this.group.leader._id === this.user._id || this.group.managers[this.user._id]);
|
||||
},
|
||||
displayNotes () {
|
||||
if (this.isGroupTask && !this.isUser) return this.task.group.managerNotes;
|
||||
return this.task.notes;
|
||||
},
|
||||
isOpenTask () {
|
||||
if (!this.isGroupTask) return false;
|
||||
if (this.task.group.assignedUsers) return false;
|
||||
if (this.task.group.assignedUsers.length > 0) return false;
|
||||
return true;
|
||||
},
|
||||
showCheckIcon () {
|
||||
if (this.isGroupTask && this.task.group.assignedUsers
|
||||
&& this.task.group.assignedUsers[this.user._id]) {
|
||||
return this.task.group.assignedUsers[this.user._id].completed;
|
||||
if (this.isGroupTask && this.task.group.assignedUsersDetail
|
||||
&& this.task.group.assignedUsersDetail[this.user._id]) {
|
||||
return this.task.group.assignedUsersDetail[this.user._id].completed;
|
||||
}
|
||||
return this.task.completed;
|
||||
},
|
||||
|
|
@ -1076,18 +1071,20 @@ export default {
|
|||
if (this.isUser) return false;
|
||||
if (this.isGroupTask) {
|
||||
if (this.task.completed) {
|
||||
if (this.task.group.assignedUsers && this.task.group.assignedUsers[this.user._id]) {
|
||||
if (this.task.group.assignedUsersDetail
|
||||
&& this.task.group.assignedUsersDetail[this.user._id]
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.task.group.completedBy.userId === this.user._id) return false;
|
||||
if (this.teamManagerAccess) {
|
||||
if (!this.task.group.assignedUsers) return false;
|
||||
if (keys(this.task.group.assignedUsers).length === 1) return false;
|
||||
if (this.task.group.assignedUsers.length === 1) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (this.isOpenTask) return false;
|
||||
if (this.task.group.assignedUsers && this.task.group.assignedUsers[this.user._id]) {
|
||||
if (this.task.group.assignedUsersDetail[this.user._id]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1165,11 +1162,11 @@ export default {
|
|||
if (
|
||||
this.isGroupTask && direction === 'down'
|
||||
&& ['todo', 'daily'].indexOf(this.task.type) !== -1
|
||||
&& this.task.group.assignedUsers && !this.task.group.assignedUsers[this.user._id]
|
||||
&& !this.task.group.assignedUsersDetail[this.user._id]
|
||||
) {
|
||||
this.$store.dispatch('tasks:needsWork', {
|
||||
taskId: this.task._id,
|
||||
userId: keys(this.task.group.assignedUsers)[0],
|
||||
userId: this.task.group.assignedUsers[0],
|
||||
});
|
||||
this.task.completed = false;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -71,47 +71,33 @@
|
|||
>
|
||||
</div>
|
||||
<div
|
||||
v-if="isUserTask || isChallengeTask || isOriginalChallengeTask"
|
||||
class="form-group mb-0"
|
||||
>
|
||||
<label
|
||||
class="d-flex align-items-center justify-content-between mb-1"
|
||||
>
|
||||
<span
|
||||
:class="cssClass('headings')"
|
||||
>{{ $t('notes') }}</span>
|
||||
<small>
|
||||
<div class="d-flex">
|
||||
<lockable-label
|
||||
class="mr-auto"
|
||||
:class-override="cssClass('headings')"
|
||||
:locked="groupAccessRequiredAndOnPersonalPage || challengeAccessRequired"
|
||||
:text="`${$t('notes')}`"
|
||||
/>
|
||||
<small
|
||||
class="my-1"
|
||||
>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://habitica.fandom.com/wiki/Markdown_Cheat_Sheet"
|
||||
:class="cssClass('headings')"
|
||||
>{{ $t('markdownHelpLink') }}</a>
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
<textarea
|
||||
v-model="task.notes"
|
||||
class="form-control input-notes"
|
||||
:class="cssClass('input')"
|
||||
:disabled="groupAccessRequiredAndOnPersonalPage || challengeAccessRequired"
|
||||
:placeholder="$t('addNotes')"
|
||||
></textarea>
|
||||
</div>
|
||||
<div
|
||||
v-if="showManagerNotes"
|
||||
class="form-group mb-0 mt-3"
|
||||
>
|
||||
<lockable-label
|
||||
:class-override="cssClass('headings')"
|
||||
:locked="groupAccessRequiredAndOnPersonalPage"
|
||||
:text="$t('managerNotes')"
|
||||
/>
|
||||
<textarea
|
||||
v-model="managerNotes"
|
||||
class="form-control input-notes"
|
||||
:class="cssClass('input')"
|
||||
:placeholder="$t('addNotes')"
|
||||
:disabled="groupAccessRequiredAndOnPersonalPage"
|
||||
></textarea>
|
||||
</div>
|
||||
<div
|
||||
v-if="task.group && task.group.assignedDate && !task.group.assigningUsername"
|
||||
class="mt-3 mb-n2"
|
||||
|
|
@ -405,7 +391,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="isUserTask"
|
||||
v-if="!challengeAccessRequired && !groupAccessRequiredAndOnPersonalPage"
|
||||
class="tags-select option mt-3"
|
||||
>
|
||||
<div class="tags-inline form-group row">
|
||||
|
|
@ -1085,7 +1071,6 @@ export default {
|
|||
calendar: calendarIcon,
|
||||
grip: gripIcon,
|
||||
}),
|
||||
managerNotes: '',
|
||||
members: [],
|
||||
membersNameAndId: [],
|
||||
memberNamesById: {},
|
||||
|
|
@ -1149,12 +1134,6 @@ export default {
|
|||
&& !this.isOriginalChallengeTask
|
||||
&& (!this.groupAccessRequiredAndOnPersonalPage || this.checklist.length > 0);
|
||||
},
|
||||
showManagerNotes () {
|
||||
return Boolean(this.task.group && this.task.group.managerNotes)
|
||||
|| (
|
||||
!this.groupAccessRequiredAndOnPersonalPage && this.managers.indexOf(this.user._id) !== -1
|
||||
);
|
||||
},
|
||||
isChallengeTask () {
|
||||
return Boolean(this.task.challenge && this.task.challenge.id);
|
||||
},
|
||||
|
|
@ -1261,10 +1240,6 @@ export default {
|
|||
createTag: 'tags:createTag',
|
||||
}),
|
||||
async syncTask () {
|
||||
if (this.task && this.task.group && this.task.group.managerNotes) {
|
||||
this.managerNotes = this.task.group.managerNotes;
|
||||
}
|
||||
|
||||
if (this.groupId) {
|
||||
const members = await this.$store.dispatch('members:getGroupMembers', {
|
||||
groupId: this.groupId,
|
||||
|
|
@ -1282,7 +1257,7 @@ export default {
|
|||
});
|
||||
this.assignedMembers = [];
|
||||
if (this.task.group?.assignedUsers) {
|
||||
this.assignedMembers = keys(this.task.group.assignedUsers);
|
||||
this.assignedMembers = this.task.group.assignedUsers;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1443,12 +1418,6 @@ export default {
|
|||
if (!this.canSave) return;
|
||||
if (this.newChecklistItem) this.addChecklistItem();
|
||||
|
||||
// TODO Fix up permissions on task.group so we don't have to keep doing these hacks
|
||||
if (this.groupId) {
|
||||
this.task.managerNotes = this.managerNotes;
|
||||
this.task.group.managerNotes = this.managerNotes;
|
||||
}
|
||||
|
||||
if (this.task.type === 'reward' && this.task.value === '') {
|
||||
this.task.value = 0;
|
||||
}
|
||||
|
|
@ -1472,8 +1441,8 @@ export default {
|
|||
assignedUserIds: this.assignedMembers,
|
||||
});
|
||||
this.assignedMembers.forEach(memberId => {
|
||||
if (!this.task.assignedUsers) this.task.assignedUsers = {};
|
||||
this.task.assignedUsers[memberId] = {
|
||||
if (!this.task.assignedUsersDetail) this.task.assignedUsersDetail = {};
|
||||
this.task.assignedUsersDetail[memberId] = {
|
||||
assignedDate: new Date(),
|
||||
assigningUsername: this.user.auth.local.username,
|
||||
completed: false,
|
||||
|
|
@ -1500,7 +1469,6 @@ export default {
|
|||
this.$root.$emit('bv::hide::modal', 'task-modal');
|
||||
},
|
||||
onClose () {
|
||||
if (this.task.group && this.task.group.managerNotes) this.managerNotes = null;
|
||||
this.newChecklistItem = '';
|
||||
this.$emit('cancel');
|
||||
},
|
||||
|
|
|
|||
|
|
@ -105,11 +105,8 @@ export function getActiveFilter (type, filterType, isChallenge) {
|
|||
return activeFilter(taskFilters)(type, filterType);
|
||||
}
|
||||
|
||||
export function sortAndFilterTasks (tasks, selectedFilter, group = false) {
|
||||
export function sortAndFilterTasks (tasks, selectedFilter) {
|
||||
let sortedTasks = tasks.filter(selectedFilter.filterFn);
|
||||
if (!group) {
|
||||
sortedTasks = sortedTasks.filter(task => !task.group.id);
|
||||
}
|
||||
if (selectedFilter.sort) {
|
||||
sortedTasks = sortBy(sortedTasks, selectedFilter.sort);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ export function getTaskClasses (store) {
|
|||
if (type === 'todo' || type === 'daily') {
|
||||
if (task.completed
|
||||
|| (!shouldDo(dueDate, task, userPreferences) && type === 'daily')
|
||||
|| (task.group.assignedUsers && task.group.assignedUsers[userId]
|
||||
&& task.group.assignedUsers[userId].completed)
|
||||
|| (task.group.assignedUsersDetail && task.group.assignedUsersDetail[userId]
|
||||
&& task.group.assignedUsersDetail[userId].completed)
|
||||
) {
|
||||
return {
|
||||
bg: _nonInteractive(task, userId) ? 'task-disabled-daily-todo-control-bg-noninteractive' : 'task-disabled-daily-todo-control-bg',
|
||||
|
|
|
|||
|
|
@ -302,9 +302,9 @@ export default function scoreTask (options = {}, req = {}, analytics) {
|
|||
task.completed = true;
|
||||
task.streak += 1;
|
||||
} else {
|
||||
task.group.assignedUsers[user._id].completed = true;
|
||||
task.group.assignedUsers[user._id].completedDate = new Date();
|
||||
if (!find(task.group.assignedUsers, assignedUser => !assignedUser.completed)) {
|
||||
task.group.assignedUsersDetail[user._id].completed = true;
|
||||
task.group.assignedUsersDetail[user._id].completedDate = new Date();
|
||||
if (!find(task.group.assignedUsersDetail, assignedUser => !assignedUser.completed)) {
|
||||
task.dateCompleted = new Date();
|
||||
task.completed = true;
|
||||
task.streak += 1;
|
||||
|
|
@ -332,16 +332,16 @@ export default function scoreTask (options = {}, req = {}, analytics) {
|
|||
}
|
||||
} else if (direction === 'down') {
|
||||
if (task.group.id) {
|
||||
if (!task.group.assignedUsers
|
||||
|| !find(task.group.assignedUsers, assignedUser => !assignedUser.completed)
|
||||
if (!task.group.assignedUsersDetail
|
||||
|| !find(task.group.assignedUsersDetail, assignedUser => !assignedUser.completed)
|
||||
) {
|
||||
task.streak -= 1;
|
||||
task.completed = false;
|
||||
}
|
||||
if (task.group.completedBy) task.group.completedBy = {};
|
||||
if (task.group.assignedUsers && task.group.assignedUsers[user._id]) {
|
||||
task.group.assignedUsers[user._id].completed = false;
|
||||
task.group.assignedUsers[user._id].completedDate = undefined;
|
||||
if (task.group.assignedUsersDetail && task.group.assignedUsersDetail[user._id]) {
|
||||
task.group.assignedUsersDetail[user._id].completed = false;
|
||||
task.group.assignedUsersDetail[user._id].completedDate = undefined;
|
||||
}
|
||||
if (task.markModified) task.markModified('group');
|
||||
} else {
|
||||
|
|
@ -372,9 +372,9 @@ export default function scoreTask (options = {}, req = {}, analytics) {
|
|||
};
|
||||
task.completed = true;
|
||||
} else {
|
||||
task.group.assignedUsers[user._id].completed = true;
|
||||
task.group.assignedUsers[user._id].completedDate = new Date();
|
||||
if (!find(task.group.assignedUsers, assignedUser => !assignedUser.completed)) {
|
||||
task.group.assignedUsersDetail[user._id].completed = true;
|
||||
task.group.assignedUsersDetail[user._id].completedDate = new Date();
|
||||
if (!find(task.group.assignedUsersDetail, assignedUser => !assignedUser.completed)) {
|
||||
task.dateCompleted = new Date();
|
||||
task.completed = true;
|
||||
}
|
||||
|
|
@ -389,9 +389,9 @@ export default function scoreTask (options = {}, req = {}, analytics) {
|
|||
task.dateCompleted = undefined;
|
||||
if (task.group.id) {
|
||||
if (task.group.completedBy) task.group.completedBy = {};
|
||||
if (task.group.assignedUsers && task.group.assignedUsers[user._id]) {
|
||||
task.group.assignedUsers[user._id].completed = false;
|
||||
task.group.assignedUsers[user._id].completedDate = undefined;
|
||||
if (task.group.assignedUsersDetail && task.group.assignedUsersDetail[user._id]) {
|
||||
task.group.assignedUsersDetail[user._id].completed = false;
|
||||
task.group.assignedUsersDetail[user._id].completedDate = undefined;
|
||||
}
|
||||
if (task.markModified) task.markModified('group');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,10 +355,10 @@ api.taskNeedsWork = {
|
|||
if (['daily', 'todo'].indexOf(task.type) === -1) {
|
||||
throw new BadRequest('Cannot roll back use of Habits or Rewards.');
|
||||
}
|
||||
if (!task.group.assignedUsers || !task.group.assignedUsers[assignedUserId]) {
|
||||
if (!task.group.assignedUsersDetail || !task.group.assignedUsersDetail[assignedUserId]) {
|
||||
throw new BadRequest('User not assigned to this task.');
|
||||
}
|
||||
if (!task.group.assignedUsers[assignedUserId].completed) {
|
||||
if (!task.group.assignedUsersDetail[assignedUserId].completed) {
|
||||
throw new BadRequest('Task not completed by this user.');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ async function getTasks (req, res, options = {}) {
|
|||
dueDate,
|
||||
} = options;
|
||||
|
||||
let query = { userId: user._id };
|
||||
let query = { $or: [{ userId: user._id }, { 'group.assignedUsers': user._id }] };
|
||||
let limit;
|
||||
let sort;
|
||||
const owner = group || challenge || user;
|
||||
|
|
@ -188,10 +188,12 @@ async function getTasks (req, res, options = {}) {
|
|||
query.type = type.slice(0, -1); // removing the final "s"
|
||||
}
|
||||
} else {
|
||||
query.$or = [ // Exclude completed todos
|
||||
{ type: 'todo', completed: false },
|
||||
{ type: { $in: ['habit', 'daily', 'reward'] } },
|
||||
];
|
||||
query.$and = [{
|
||||
$or: [ // Exclude completed todos
|
||||
{ type: 'todo', completed: false },
|
||||
{ type: { $in: ['habit', 'daily', 'reward'] } },
|
||||
],
|
||||
}];
|
||||
}
|
||||
|
||||
const mQuery = Tasks.Task.find(query);
|
||||
|
|
|
|||
|
|
@ -1447,18 +1447,24 @@ schema.methods.syncTask = async function groupSyncTask (taskToSync, users, assig
|
|||
for (const user of users) {
|
||||
const assignmentData = {
|
||||
assignedDate: new Date(),
|
||||
assignedUsername: user.auth.local.username,
|
||||
assigningUsername: assigningUser && assigningUser._id !== user._id
|
||||
? assigningUser.auth.local.username : null,
|
||||
completed: false,
|
||||
};
|
||||
|
||||
if (!taskToSync.group.assignedUsers) {
|
||||
taskToSync.group.assignedUsers = {};
|
||||
taskToSync.group.assignedUsers = [];
|
||||
}
|
||||
if (!taskToSync.group.assignedUsers[user._id]) {
|
||||
taskToSync.group.assignedUsers[user._id] = assignmentData;
|
||||
taskToSync.group.assignedUsers.push(user._id);
|
||||
|
||||
if (!taskToSync.group.assignedUsersDetail) {
|
||||
taskToSync.group.assignedUsersDetail = {};
|
||||
}
|
||||
taskToSync.markModified('group.assignedUsers');
|
||||
if (!taskToSync.group.assignedUsersDetail[user._id]) {
|
||||
taskToSync.group.assignedUsersDetail[user._id] = assignmentData;
|
||||
}
|
||||
taskToSync.markModified('group.assignedUsersDetail');
|
||||
|
||||
// Sync tags
|
||||
const userTags = user.tags;
|
||||
|
|
@ -1488,14 +1494,16 @@ schema.methods.unlinkTask = async function groupUnlinkTask (
|
|||
) {
|
||||
const findQuery = {
|
||||
'group.taskId': unlinkingTask._id,
|
||||
userId: user._id,
|
||||
'group.assignedUsers': user._id,
|
||||
};
|
||||
|
||||
delete unlinkingTask.group.assignedUsers[user._id];
|
||||
if (Object.keys(unlinkingTask.group.assignedUsers).length === 0) {
|
||||
delete unlinkingTask.group.assignedUsersDetail[user._id];
|
||||
const assignedUserIndex = unlinkingTask.group.assignedUsers.indexOf(user._id);
|
||||
unlinkingTask.group.assignedUsers.splice(assignedUserIndex, 1);
|
||||
if (unlinkingTask.group.assignedUsers.length === 0) {
|
||||
unlinkingTask.group.assignedUsers = undefined;
|
||||
}
|
||||
unlinkingTask.markModified('group.assignedUsers');
|
||||
unlinkingTask.markModified('group');
|
||||
|
||||
const promises = [unlinkingTask.save()];
|
||||
|
||||
|
|
|
|||
|
|
@ -129,10 +129,12 @@ export const TaskSchema = new Schema({
|
|||
id: { $type: String, ref: 'Group', validate: [v => validator.isUUID(v), 'Invalid uuid for group task.'] },
|
||||
assignedDate: { $type: Date }, // To be removed
|
||||
assigningUsername: { $type: String }, // To be removed
|
||||
assignedUsers: {
|
||||
assignedUsers: [{ $type: String, ref: 'User', validate: [v => validator.isUUID(v), 'Invalid uuid for group assigned user.'] }],
|
||||
assignedUsersDetail: {
|
||||
$type: Schema.Types.Mixed,
|
||||
// key is assigned UUID, with
|
||||
// { assignedDate: Date,
|
||||
// assignedUsername: '@username',
|
||||
// assigningUsername: '@username',
|
||||
// completed: Boolean,
|
||||
// completedDate: Date }
|
||||
|
|
|
|||
Loading…
Reference in a new issue