WIP(teams): show open tasks on user view

This commit is contained in:
SabreCat 2022-06-16 13:25:09 -05:00
parent 4ac1a3e717
commit 8b084e627e
5 changed files with 66 additions and 24 deletions

View file

@ -1078,7 +1078,9 @@ export default {
}
if (this.task.group.completedBy.userId === this.user._id) return false;
if (this.teamManagerAccess) {
if (!this.task.group.assignedUsers) return false;
if (!this.task.group.assignedUsers || this.task.group.assignedUsers.length === 0) {
return false;
}
if (this.task.group.assignedUsers.length === 1) return false;
}
return true;
@ -1162,11 +1164,12 @@ export default {
if (
this.isGroupTask && direction === 'down'
&& ['todo', 'daily'].indexOf(this.task.type) !== -1
&& !this.task.group.assignedUsersDetail[this.user._id]
&& (!this.task.group.assignedUsersDetail
|| !this.task.group.assignedUsersDetail[this.user._id])
) {
this.$store.dispatch('tasks:needsWork', {
taskId: this.task._id,
userId: this.task.group.assignedUsers[0],
userId: this.task.group.assignedUsers[0] || this.task.group.completedBy.userId,
});
this.task.completed = false;
return;

View file

@ -294,7 +294,7 @@ export default function scoreTask (options = {}, req = {}, analytics) {
if (direction === 'up') {
if (task.group.id) {
if (!task.group.assignedUsers) {
if (!task.group.assignedUsers || task.group.assignedUsers.length === 0) {
task.group.completedBy = {
userId: user._id,
date: new Date(),
@ -365,7 +365,7 @@ export default function scoreTask (options = {}, req = {}, analytics) {
} else {
if (direction === 'up') {
if (task.group.id) {
if (!task.group.assignedUsers) {
if (!task.group.assignedUsers || task.group.assignedUsers.length === 0) {
task.group.completedBy = {
userId: user._id,
date: new Date(),

View file

@ -385,7 +385,7 @@ api.getUserTasks = {
url: '/tasks/user',
middlewares: [authWithHeaders({
// Some fields (including _id, preferences) are always loaded (see middlewares/auth)
userFieldsToInclude: ['tasksOrder'],
userFieldsToInclude: ['guilds', 'party', 'tasksOrder'],
})],
async handler (req, res) {
const types = Tasks.tasksTypes.map(type => `${type}s`);

View file

@ -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.assignedUsersDetail || !task.group.assignedUsersDetail[assignedUserId]) {
throw new BadRequest('User not assigned to this task.');
}
if (!task.group.assignedUsersDetail[assignedUserId].completed) {
if (
(task.group.completedBy.userId && task.group.completedBy.userId !== assignedUserId)
|| (task.group.assignedUsersDetail && !(task.group.assignedUsersDetail[assignedUserId]
&& task.group.assignedUsersDetail[assignedUserId].completed))) {
throw new BadRequest('Task not completed by this user.');
}

View file

@ -1,5 +1,7 @@
import moment from 'moment';
import _ from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import compact from 'lodash/compact';
import keys from 'lodash/keys';
import validator from 'validator';
import {
setNextDue,
@ -150,23 +152,52 @@ async function getTasks (req, res, options = {}) {
dueDate,
} = options;
let query = { $or: [{ userId: user._id }, { 'group.assignedUsers': user._id }] };
let query;
let limit;
let sort;
let upgradedGroups;
const owner = group || challenge || user;
if (challenge) {
query = { 'challenge.id': challenge.id, userId: { $exists: false } };
} else if (group) {
query = { 'group.id': group._id, userId: { $exists: false } };
query = { 'group.id': group._id };
} else {
upgradedGroups = await Group.find(
{
_id: { $in: user.guilds.concat(user.party._id) },
'purchased.plan.customerId': { $exists: true },
$or: [
{ 'purchased.plan.dateTerminated': { $exists: false } },
{ 'purchased.plan.dateTerminated': null },
{ 'purchased.plan.dateTerminated': { $gt: new Date() } },
],
},
{ _id: 1 },
).exec();
if (upgradedGroups.length > 0) {
const upgradedGroupIds = [];
for (const upgradedGroup of upgradedGroups) {
upgradedGroupIds.push(upgradedGroup._id);
}
query = {
$or: [
{ userId: user._id },
{ 'group.assignedUsers': user._id },
{ 'group.id': { $in: upgradedGroupIds }, 'group.assignedUsers.0': { $exists: false } },
],
};
} else {
query = { userId: user._id };
}
}
const { type } = req.query;
if (type) {
if (type === 'todos') {
query.completed = false; // Exclude completed todos
query.type = 'todo';
query.completed = false; // Exclude completed todos
} else if (type === 'completedTodos' || type === '_allCompletedTodos') { // _allCompletedTodos is currently in BETA and is likely to be removed in future
limit = 30;
@ -177,7 +208,13 @@ async function getTasks (req, res, options = {}) {
query.type = 'todo';
query.completed = true;
if (owner._id === user._id) {
if (upgradedGroups && upgradedGroups.length > 0) {
query.$or = [
{ userId: user._id },
{ 'group.assignedUsers': user._id },
{ 'group.completedBy.userId': user._id },
];
} else if (owner._id === user._id) {
query.userId = user._id;
}
@ -234,7 +271,7 @@ async function getTasks (req, res, options = {}) {
});
// Remove empty values from the array and add any unordered task
orderedTasks = _.compact(orderedTasks).concat(unorderedTasks);
orderedTasks = compact(orderedTasks).concat(unorderedTasks);
return orderedTasks;
}
@ -307,7 +344,7 @@ async function handleTeamTask (task, delta, direction) {
if (teamTask) {
const groupDelta = teamTask.group.assignedUsers
? delta / _.keys(teamTask.group.assignedUsers).length
? delta / keys(teamTask.group.assignedUsers).length
: delta;
await teamTask.scoreChallengeTask(groupDelta, direction);
if (task.type === 'daily' || task.type === 'todo') {
@ -330,10 +367,12 @@ async function handleTeamTask (task, delta, direction) {
*/
async function scoreTask (user, task, direction, req, res) {
if (task.type === 'daily' || task.type === 'todo') {
if (task.group.id && task.group.assignedUsers && task.group.assignedUsers[user._id]) {
if (task.group.assignedUsers[user._id].completed && direction === 'up') {
if (task.group.id && task.group.assignedUsersDetail
&& task.group.assignedUsersDetail[user._id]
) {
if (task.group.assignedUsersDetail[user._id].completed && direction === 'up') {
throw new NotAuthorized(res.t('sessionOutdated'));
} else if (!task.group.assignedUsers[user._id].completed && direction === 'down') {
} else if (!task.group.assignedUsersDetail[user._id].completed && direction === 'down') {
throw new NotAuthorized(res.t('sessionOutdated'));
}
} else if (task.completed && direction === 'up') {
@ -361,12 +400,12 @@ async function scoreTask (user, task, direction, req, res) {
const userIsManagement = group.leader === user._id || Boolean(group.managers[user._id]);
if (!userIsManagement
&& !(task.group.completedBy && task.group.completedBy.userId === user._id)
&& !(task.group.assignedUsers && task.group.assignedUsers[user._id])
&& !(task.group.assignedUsersDetail && task.group.assignedUsersDetail[user._id])
) {
throw new BadRequest('Cannot uncheck task you did not complete if not a manager.');
}
if (task.group.assignedUsers && _.keys(task.group.assignedUsers).length === 1) {
const rollbackUserId = _.keys(task.group.assignedUsers)[0];
if (task.group.assignedUsers && keys(task.group.assignedUsers).length === 1) {
const rollbackUserId = keys(task.group.assignedUsers)[0];
rollbackUser = await User.findOne({ _id: rollbackUserId });
} else {
rollbackUser = await User.findOne({ _id: task.group.completedBy.userId });
@ -471,7 +510,7 @@ async function scoreTask (user, task, direction, req, res) {
pushTask,
// clone user._tmp so that it's not overwritten by other score operations
// when using the bulk scoring API
_tmp: _.cloneDeep(user._tmp),
_tmp: cloneDeep(user._tmp),
};
}