WIP(multi-assign): functioning multi

This commit is contained in:
SabreCat
2022-01-21 16:26:30 -06:00
parent a495db8480
commit eaa5f821a4
5 changed files with 100 additions and 91 deletions

View File

@@ -1469,11 +1469,10 @@ export default {
tasks: [this.task], tasks: [this.task],
}); });
Object.assign(this.task, response); Object.assign(this.task, response);
const promises = this.assignedMembers.map(memberId => this.$store.dispatch('tasks:assignTask', { await this.$store.dispatch('tasks:assignTask', {
taskId: this.task._id, taskId: this.task._id,
userId: memberId, assignedUserIds: this.assignedMembers,
})); });
Promise.all(promises);
this.assignedMembers.forEach(memberId => { this.assignedMembers.forEach(memberId => {
if (!this.task.assignedUsers) this.task.assignedUsers = {}; if (!this.task.assignedUsers) this.task.assignedUsers = {};
this.task.assignedUsers[memberId] = { this.task.assignedUsers[memberId] = {
@@ -1520,7 +1519,7 @@ export default {
} else { } else {
await this.$store.dispatch('tasks:assignTask', { await this.$store.dispatch('tasks:assignTask', {
taskId: this.task._id, taskId: this.task._id,
userId: memberId, assignedUserIds: [memberId],
}); });
} }
}, },

View File

@@ -204,7 +204,7 @@ export async function createGroupTasks (store, payload) {
} }
export async function assignTask (store, payload) { export async function assignTask (store, payload) {
const response = await axios.post(`/api/v4/tasks/${payload.taskId}/assign/${payload.userId}`); const response = await axios.post(`/api/v4/tasks/${payload.taskId}/assign`, payload.assignedUserIds);
return response.data.data; return response.data.data;
} }

View File

@@ -1,3 +1,4 @@
import isUUID from 'validator/lib/isUUID';
import { authWithHeaders } from '../../../middlewares/auth'; import { authWithHeaders } from '../../../middlewares/auth';
import * as Tasks from '../../../models/task'; import * as Tasks from '../../../models/task';
import { model as Group } from '../../../models/group'; import { model as Group } from '../../../models/group';
@@ -169,30 +170,31 @@ api.groupMoveTask = {
}; };
/** /**
* @api {post} /api/v3/tasks/:taskId/assign/:assignedUserId Assign a group task to a user * @api {post} /api/v3/tasks/:taskId/assign Assign a group task to a user or users
* @apiDescription Assigns a user to a group task * @apiDescription Assign users to a group task
* @apiName AssignTask * @apiName AssignTask
* @apiGroup Task * @apiGroup Task
* *
* @apiParam (Path) {UUID} taskId The id of the task that will be assigned * @apiParam (Path) {UUID} taskId The id of the task that will be assigned
* @apiParam (Path) {UUID} assignedUserId The id of the user that will be assigned to the task * @apiParam (Body) {UUID[]} [assignedUserIds] Array of user IDs to be assigned to the task
* *
* @apiSuccess data The assigned task * @apiSuccess data The assigned task
*/ */
api.assignTask = { api.assignTask = {
method: 'POST', method: 'POST',
url: '/tasks/:taskId/assign/:assignedUserId', url: '/tasks/:taskId/assign',
middlewares: [authWithHeaders()], middlewares: [authWithHeaders()],
async handler (req, res) { async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
const reqValidationErrors = req.validationErrors(); const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors; if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals; const { user } = res.locals;
const { assignedUserId } = req.params; const assignedUserIds = req.body;
const assignedUser = await User.findById(assignedUserId).exec(); for (const userId of assignedUserIds) {
if (!isUUID(userId)) throw new BadRequest('Assigned users must be UUIDs');
}
const { taskId } = req.params; const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -211,18 +213,21 @@ api.assignTask = {
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
const assignedUsers = await User.find({ _id: { $in: assignedUserIds } }).exec();
const promises = []; const promises = [];
const taskText = task.text; const taskText = task.text;
const userName = `@${user.auth.local.username}`; const userName = `@${user.auth.local.username}`;
if (user._id !== assignedUserId) { for (const userToAssign of assignedUsers) {
assignedUser.addNotification('GROUP_TASK_ASSIGNED', { if (user._id !== userToAssign._id) {
userToAssign.addNotification('GROUP_TASK_ASSIGNED', {
message: res.t('youHaveBeenAssignedTask', { managerName: userName, taskText }), message: res.t('youHaveBeenAssignedTask', { managerName: userName, taskText }),
taskId: task._id, taskId: task._id,
}); });
} }
}
promises.push(group.syncTask(task, assignedUser, user)); promises.push(group.syncTask(task, assignedUsers, user));
promises.push(group.save()); promises.push(group.save());
await Promise.all(promises); await Promise.all(promises);

View File

@@ -1499,9 +1499,10 @@ schema.methods.updateTask = async function updateTask (taskToSync, options = {})
await taskSchema.update(updateQuery, updateCmd, { multi: true }).exec(); await taskSchema.update(updateQuery, updateCmd, { multi: true }).exec();
}; };
schema.methods.syncTask = async function groupSyncTask (taskToSync, user, assigningUser) { schema.methods.syncTask = async function groupSyncTask (taskToSync, users, assigningUser) {
const group = this; const group = this;
const toSave = []; const toSave = [];
for (const user of users) {
const assignmentData = { const assignmentData = {
assignedDate: new Date(), assignedDate: new Date(),
assigningUsername: assigningUser && assigningUser._id !== user._id assigningUsername: assigningUser && assigningUser._id !== user._id
@@ -1540,7 +1541,7 @@ schema.methods.syncTask = async function groupSyncTask (taskToSync, user, assign
'group.id': group._id, 'group.id': group._id,
}; };
let matchingTask = await Tasks.Task.findOne(findQuery).exec(); let matchingTask = await Tasks.Task.findOne(findQuery).exec(); // eslint-disable-line
if (!matchingTask) { // If the task is new, create it if (!matchingTask) { // If the task is new, create it
matchingTask = new Tasks[taskToSync.type](Tasks.Task.sanitize(syncableAttrs(taskToSync))); matchingTask = new Tasks[taskToSync.type](Tasks.Task.sanitize(syncableAttrs(taskToSync)));
@@ -1554,7 +1555,6 @@ schema.methods.syncTask = async function groupSyncTask (taskToSync, user, assign
const orderList = user.tasksOrder[`${taskToSync.type}s`]; const orderList = user.tasksOrder[`${taskToSync.type}s`];
if (orderList.indexOf(matchingTask._id) === -1 && (matchingTask.type !== 'todo' || !matchingTask.completed)) orderList.push(matchingTask._id); if (orderList.indexOf(matchingTask._id) === -1 && (matchingTask.type !== 'todo' || !matchingTask.completed)) orderList.push(matchingTask._id);
} }
matchingTask.group.assignedUsers = taskToSync.group.assignedUsers; matchingTask.group.assignedUsers = taskToSync.group.assignedUsers;
matchingTask.group.sharedCompletion = taskToSync.group.sharedCompletion; matchingTask.group.sharedCompletion = taskToSync.group.sharedCompletion;
matchingTask.group.managerNotes = taskToSync.group.managerNotes; matchingTask.group.managerNotes = taskToSync.group.managerNotes;
@@ -1574,7 +1574,9 @@ schema.methods.syncTask = async function groupSyncTask (taskToSync, user, assign
// add tag if missing // add tag if missing
if (matchingTask.tags.indexOf(group._id) === -1) matchingTask.tags.push(group._id); if (matchingTask.tags.indexOf(group._id) === -1) matchingTask.tags.push(group._id);
toSave.push(matchingTask.save(), taskToSync.save(), user.save()); toSave.push(matchingTask.save(), user.save());
}
toSave.push(taskToSync.save());
return Promise.all(toSave); return Promise.all(toSave);
}; };

View File

@@ -140,7 +140,10 @@ export const TaskSchema = new Schema({
$type: String, default: 'singleCompletion', // legacy data $type: String, default: 'singleCompletion', // legacy data
}, },
managerNotes: { $type: String }, managerNotes: { $type: String },
completedBy: { $type: String, ref: 'User', validate: [v => validator.isUUID(v), 'Invalid uuid for group completing user.'] }, completedBy: {
$type: Schema.Types.Mixed,
default: () => ({}), // { 'UUID': Date }
},
}, },
reminders: [reminderSchema], reminders: [reminderSchema],