Teams Updates 201908 (#11347)

* fix(teams): no hover bg change for noninteractive checkboxes

* feat(teams): send notification to managers on task claim
Also fix client unit test broken by prev commit

* feat(groups): don't penalize for tasks assigned since last activity

* fix(tests): actually fix client unit

* fix(teams): improve task styles

* fix(teams): let people other than leader see relevant approvals
Also more style fixes

* fix(approvals): better filtering and task headings for approval data

* fix(test): correct test expectations for new GET /approvals behavior

* fix(groups): style tweaks

* different border for group and normal tasks

* fix(teams): remove extra click for claiming

* fix(teams): leaders & managers can check off approval-required tasks

* fix(teams): don't notify user of own claim

* fix group task margin and z-index on hover

* fix(menu): sporadic error in top bar

* fix(teams): more approval header and footer adjustments

* fix(tests): adjust expectations for self-approval

* fix(teams): address PR comments

* refactor(timestamps): date user activity on authenticated requests

* refactor(timestamps): update local user instead of direct db update
This commit is contained in:
Sabe Jones
2019-09-26 14:49:11 -04:00
committed by GitHub
parent 5f2032a9d5
commit 01d272d2c4
26 changed files with 314 additions and 145 deletions

View File

@@ -567,41 +567,48 @@ api.scoreTask = {
}
if (task.group.approval.required && !task.group.approval.approved) {
if (task.group.approval.requested) {
throw new NotAuthorized(res.t('taskRequiresApproval'));
}
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
let fields = requiredGroupFields.concat(' managers');
let group = await Group.getGroup({user, groupId: task.group.id, fields});
// @TODO: we can use the User.pushNotification function because we need to ensure notifications are translated
let managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
let managers = await User.find({_id: managerIds}, 'notifications preferences').exec(); // Use this method so we can get access to notifications
let 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,
taskId: task._id, // user task id, used to match the notification when the task is approved
userId: user._id,
groupTaskId: task.group.taskId, // the original task id
direction,
if (managerIds.indexOf(user._id) !== -1) {
task.group.approval.approved = true;
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
} else {
if (task.group.approval.requested) {
throw new NotAuthorized(res.t('taskRequiresApproval'));
}
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
let 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
let 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,
taskId: task._id, // user task id, used to match the notification when the task is approved
userId: user._id,
groupTaskId: task.group.taskId, // the original task id
direction,
});
managerPromises.push(manager.save());
});
managerPromises.push(manager.save());
});
managerPromises.push(task.save());
await Promise.all(managerPromises);
managerPromises.push(task.save());
await Promise.all(managerPromises);
throw new NotAuthorized(res.t('taskApprovalHasBeenRequested'));
throw new NotAuthorized(res.t('taskApprovalHasBeenRequested'));
}
}
let wasCompleted = task.completed;

View File

@@ -200,13 +200,25 @@ api.assignTask = {
if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
let promises = [];
const taskText = task.text;
const userName = user.profile.name;
if (user._id !== assignedUserId) {
const taskText = task.text;
const managerName = user.profile.name;
if (user._id === assignedUserId) {
const managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
const managers = await User.find({_id: managerIds}, 'notifications preferences').exec();
managers.forEach((manager) => {
if (manager._id === user._id) return;
manager.addNotification('GROUP_TASK_CLAIMED', {
message: res.t('taskClaimed', {userName, taskText}, manager.preferences.language),
groupId: group._id,
taskId: task._id,
});
promises.push(manager.save());
});
} else {
assignedUser.addNotification('GROUP_TASK_ASSIGNED', {
message: res.t('youHaveBeenAssignedTask', {managerName, taskText}),
message: res.t('youHaveBeenAssignedTask', {managerName: userName, taskText}),
taskId: task._id,
});
}
@@ -504,15 +516,26 @@ api.getGroupApprovals = {
let group = await Group.getGroup({user, groupId, fields});
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
let approvals = await Tasks.Task.find({
'group.id': groupId,
'group.approval.approved': false,
'group.approval.requested': true,
}, 'userId group text')
.populate('userId', 'profile')
.exec();
let approvals;
if (canNotEditTasks(group, user)) {
approvals = await Tasks.Task.find({
'group.id': groupId,
'group.approval.approved': false,
'group.approval.requested': true,
'group.assignedUsers': user._id,
userId: user._id,
}, 'userId group text')
.populate('userId', 'profile')
.exec();
} else {
approvals = await Tasks.Task.find({
'group.id': groupId,
'group.approval.approved': false,
'group.approval.requested': true,
}, 'userId group text')
.populate('userId', 'profile')
.exec();
}
res.respond(200, approvals);
},