WIP(teams): more partial fixing

This commit is contained in:
Sabe Jones
2021-02-09 17:08:43 -06:00
committed by SabreCat
parent 248e1c6fe9
commit 6cddb3bf82
4 changed files with 26 additions and 127 deletions

View File

@@ -9,11 +9,6 @@
]" ]"
@click="castEnd($event, task)" @click="castEnd($event, task)"
> >
<approval-header
v-if="task.group.id"
:task="task"
:group="group"
/>
<div <div
class="d-flex" class="d-flex"
:class="{'task-not-scoreable': showTaskLockIcon }" :class="{'task-not-scoreable': showTaskLockIcon }"
@@ -894,14 +889,12 @@ 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 approvalHeader from './approvalHeader';
import approvalFooter from './approvalFooter'; import approvalFooter from './approvalFooter';
import MenuDropdown from '../ui/customMenuDropdown'; import MenuDropdown from '../ui/customMenuDropdown';
export default { export default {
components: { components: {
approvalFooter, approvalFooter,
approvalHeader,
MenuDropdown, MenuDropdown,
}, },
directives: { directives: {
@@ -1055,6 +1048,7 @@ export default {
if (this.isGroupTask) { if (this.isGroupTask) {
if (this.isOpenTask) return false; if (this.isOpenTask) return false;
if (this.task.group.assignedUsers.indexOf(this.user._id) !== -1) return false; if (this.task.group.assignedUsers.indexOf(this.user._id) !== -1) return false;
if (this.teamManagerAccess && this.task.completed) return false;
} }
return true; return true;
}, },

View File

@@ -447,13 +447,6 @@ export async function cron (options = {}) {
task.checklist.forEach(i => { i.completed = false; }); task.checklist.forEach(i => { i.completed = false; });
} }
} }
if (task.group && task.group.approval && task.group.approval.approved) {
task.group.approval.approved = false;
task.group.approval.dateApproved = null;
task.group.approval.requested = false;
task.group.approval.requestedDate = null;
}
}); });
resetHabitCounters(user, tasksByType, now, daysMissed); resetHabitCounters(user, tasksByType, now, daysMissed);
@@ -464,12 +457,6 @@ export async function cron (options = {}) {
if (task.up === false || task.down === false) { if (task.up === false || task.down === false) {
task.value = Math.abs(task.value) < 0.1 ? 0 : task.value /= 2; task.value = Math.abs(task.value) < 0.1 ? 0 : task.value /= 2;
} }
if (task.group && task.group.approval && task.group.approval.approved) {
task.group.approval.approved = false;
task.group.approval.dateApproved = null;
task.group.approval.requested = false;
task.group.approval.requestedDate = null;
}
}); });
// Finished tallying // Finished tallying

View File

@@ -6,11 +6,6 @@ const SHARED_COMPLETION = {
every: 'allAssignedCompletion', every: 'allAssignedCompletion',
}; };
async function _completeMasterTask (masterTask) {
masterTask.completed = true;
await masterTask.save();
}
async function _deleteUnfinishedTasks (groupMemberTask) { async function _deleteUnfinishedTasks (groupMemberTask) {
await Tasks.Task.deleteMany({ await Tasks.Task.deleteMany({
'group.taskId': groupMemberTask.group.taskId, 'group.taskId': groupMemberTask.group.taskId,
@@ -21,33 +16,11 @@ async function _deleteUnfinishedTasks (groupMemberTask) {
}).exec(); }).exec();
} }
async function _evaluateAllAssignedCompletion (masterTask) {
let completions;
if (masterTask.group.approval && masterTask.group.approval.required) {
completions = await Tasks.Task.countDocuments({
'group.taskId': masterTask._id,
'group.approval.approved': true,
}).exec();
} else {
completions = await Tasks.Task.countDocuments({
'group.taskId': masterTask._id,
completed: true,
}).exec();
}
if (completions >= masterTask.group.assignedUsers.length) {
await _completeMasterTask(masterTask);
}
}
async function handleSharedCompletion (masterTask, groupMemberTask) { async function handleSharedCompletion (masterTask, groupMemberTask) {
if (masterTask.type !== 'todo') return; if (masterTask.type === 'reward') return;
if (masterTask.type === 'todo') await _deleteUnfinishedTasks(groupMemberTask);
if (masterTask.group.sharedCompletion === SHARED_COMPLETION.single) { masterTask.completed = groupMemberTask.completed;
await _deleteUnfinishedTasks(groupMemberTask); await masterTask.save();
await _completeMasterTask(masterTask);
} else if (masterTask.group.sharedCompletion === SHARED_COMPLETION.every) {
await _evaluateAllAssignedCompletion(masterTask);
}
} }
export { export {

View File

@@ -8,7 +8,6 @@ import {
} from './utils'; } from './utils';
import { model as Challenge } from '../../models/challenge'; import { model as Challenge } from '../../models/challenge';
import { model as Group } from '../../models/group'; import { model as Group } from '../../models/group';
import { model as User } from '../../models/user';
import * as Tasks from '../../models/task'; import * as Tasks from '../../models/task';
import apiError from '../apiError'; import apiError from '../apiError';
import { import {
@@ -336,69 +335,18 @@ async function scoreTask (user, task, direction, req, res) {
} }
} }
if (task.group.approval.required && !task.group.approval.approved) { let localTask;
const fields = requiredGroupFields.concat(' managers');
const group = await Group.getGroup({ user, groupId: task.group.id, fields });
const managerIds = Object.keys(group.managers); if (task.group.id && !task.userId && task.group.assignedUsers.length > 0) {
managerIds.push(group.leader); // Task is being scored from team board, and a user copy should exist
if (!task.group.assignedUsers.includes(user._id)) {
if (managerIds.indexOf(user._id) !== -1) { throw new BadRequest('Task has not been assigned to this user.');
task.group.approval.approved = true;
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
} else {
if (task.group.approval.requested) {
return {
task,
requiresApproval: true,
message: res.t('taskRequiresApproval'),
};
}
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); // Use this method so we can get access to notifications
// @TODO: we can use the User.pushNotification function because
// we need to ensure notifications are translated
const managerPromises = [];
managers.forEach(manager => {
manager.addNotification('GROUP_TASK_APPROVAL', {
message: res.t('userHasRequestedTaskApproval', {
user: user.profile.name,
taskName: task.text,
}, manager.preferences.language),
groupId: group._id,
// user task id, used to match the notification when the task is approved
taskId: task._id,
userId: user._id,
groupTaskId: task.group.taskId, // the original task id
direction,
});
managerPromises.push(manager.save());
});
managerPromises.push(task.save());
await Promise.all(managerPromises);
return {
task,
requiresApproval: true,
message: res.t('taskApprovalHasBeenRequested'),
};
} }
}
if (task.group.approval.required && task.group.approval.approved) { localTask = await Tasks.Task.findOne(
const notificationIndex = user.notifications.findIndex(notification => notification { userId: user._id, 'group.taskId': task._id },
&& notification.data && notification.data.task ).exec();
&& notification.data.task._id === task._id && notification.type === 'GROUP_TASK_APPROVED'); if (!localTask) throw new NotFound('Task not found.');
if (notificationIndex !== -1) {
user.notifications.splice(notificationIndex, 1);
}
} }
const wasCompleted = task.completed; const wasCompleted = task.completed;
@@ -411,26 +359,30 @@ async function scoreTask (user, task, direction, req, res) {
// If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list // If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list
// TODO move to common code? // TODO move to common code?
let pullTask = false; let pullTask;
let pushTask = false; let pushTask;
if (task.type === 'todo') { if (task.type === 'todo') {
if (!wasCompleted && task.completed) { if (!wasCompleted && task.completed) {
// @TODO: mongoose's push and pull should be atomic and help with // @TODO: mongoose's push and pull should be atomic and help with
// our concurrency issues. If not, we need to use this update $pull and $push // our concurrency issues. If not, we need to use this update $pull and $push
pullTask = true; pullTask = localTask ? localTask._id : task._id;
// user.tasksOrder.todos.pull(task._id);
} else if ( } else if (
wasCompleted wasCompleted
&& !task.completed && !task.completed
&& user.tasksOrder.todos.indexOf(task._id) === -1 && user.tasksOrder.todos.indexOf(task._id) === -1
) { ) {
pushTask = true; pushTask = localTask ? localTask._id : task._id;
// user.tasksOrder.todos.push(task._id);
} }
} }
setNextDue(task, user); setNextDue(task, user);
if (localTask) {
localTask.completed = task.completed;
localTask.value = task.value + delta;
await localTask.save();
}
taskScoredWebhook.send(user, { taskScoredWebhook.send(user, {
task, task,
direction, direction,
@@ -514,8 +466,8 @@ export async function scoreTasks (user, taskScorings, req, res) {
const pushIDs = []; const pushIDs = [];
returnDatas.forEach(returnData => { returnDatas.forEach(returnData => {
if (returnData.pushTask === true) pushIDs.push(returnData.task._id); if (returnData.pushTask) pushIDs.push(returnData.pushTask);
if (returnData.pullTask === true) pullIDs.push(returnData.task._id); if (returnData.pullTask) pullIDs.push(returnData.pullTask);
}); });
const moveUpdateObject = {}; const moveUpdateObject = {};
@@ -532,13 +484,6 @@ export async function scoreTasks (user, taskScorings, req, res) {
handleChallengeTask(data.task, data.delta, data.direction); handleChallengeTask(data.task, data.delta, data.direction);
handleGroupTask(data.task, data.delta, data.direction); handleGroupTask(data.task, data.delta, data.direction);
// Handle group tasks that require approval
if (data.requiresApproval === true) {
return {
id: data.task._id, message: data.message, requiresApproval: true,
};
}
return { id: data.task._id, delta: data.delta, _tmp: data._tmp }; return { id: data.task._id, delta: data.delta, _tmp: data._tmp };
}); });
} }