[WIP] Group tasks claim (#8099)

* Added initial group tasks ui

* Changed group compnent directory

* Added group task checklist support

* Added checklist support to ui

* Fixed delete tags route

* Added checklist routes to support new group tasks

* Added assign user tag input

* Added new group members autocomplete directive

* Linked assign ui to api

* Added styles

* Limited tag use

* Fixed line endings

* Updated to new file structure

* Fixed failing task tests

* Updatd with new checklist logic and fixed columns

* Updated add task function

* Added userid check back to tag routes

* Added back routes accidently deleted

* Added locale strings

* Moved common task function to task service

* Removed files from manifest

* Added initial group tasks ui

* Changed group compnent directory

* Added checklist support to ui

* Added assign user tag input

* Added assign user tag input

* Added new group members autocomplete directive

* Added new group members autocomplete directive

* Removed group get tasks until live

* Linked assign ui to api

* Added styles

* Added server code for claiming a task

* ADded group task meta and claim button

* Adjusted styles, added local, and added confirm

* Updated claim with new file structures

* Fixed merge issue

* Removed extra file

* Removed duplicate functions

* Removed extra directive

* Removed dev items
This commit is contained in:
Keith Holliday
2016-10-09 12:23:34 -05:00
committed by Matteo Pagliazzi
parent 826d7b85d7
commit ff08e8b586
11 changed files with 65 additions and 5 deletions

View File

@@ -74,7 +74,7 @@ describe('POST /tasks/:taskId', () => {
}); });
it('returns error when non leader tries to create a task', async () => { it('returns error when non leader tries to create a task', async () => {
await expect(member.post(`/tasks/${task._id}/assign/${member._id}`)) await expect(member2.post(`/tasks/${task._id}/assign/${member._id}`))
.to.eventually.be.rejected.and.eql({ .to.eventually.be.rejected.and.eql({
code: 401, code: 401,
error: 'NotAuthorized', error: 'NotAuthorized',
@@ -82,6 +82,17 @@ describe('POST /tasks/:taskId', () => {
}); });
}); });
it('allows user to assign themselves', async () => {
await member.post(`/tasks/${task._id}/assign/${member._id}`);
let groupTask = await user.get(`/tasks/group/${guild._id}`);
let memberTasks = await member.get('/tasks/user');
let syncedTask = find(memberTasks, findAssignedTask);
expect(groupTask[0].group.assignedUsers).to.contain(member._id);
expect(syncedTask).to.exist;
});
it('assigns a task to a user', async () => { it('assigns a task to a user', async () => {
await user.post(`/tasks/${task._id}/assign/${member._id}`); await user.post(`/tasks/${task._id}/assign/${member._id}`);

View File

@@ -0,0 +1,15 @@
habitrpg.controller('GroupTaskMetaActionsCtrl', ['$scope', 'Shared', 'Tasks', 'User',
function ($scope, Shared, Tasks, User) {
$scope.assignedMembers = [];
$scope.user = User.user;
$scope.claim = function () {
if (!confirm("Are you sure you want to claim this task?")) return;
Tasks.assignTask($scope.task.id, $scope.user._id);
$scope.task.group.assignedUsers.push($scope.user._id);
};
$scope.userIsAssigned = function () {
return $scope.task.group.assignedUsers.indexOf($scope.user._id) !== -1;
};
}]);

View File

@@ -0,0 +1,22 @@
'use strict';
(function(){
angular
.module('habitrpg')
.directive('groupTaskMetaActions', hrpgSortTags);
hrpgSortTags.$inject = [
];
function hrpgSortTags() {
return {
scope: {
task: '=',
group: '=',
},
templateUrl: 'partials/groups.tasks.meta.actions.html',
controller: 'GroupTaskMetaActionsCtrl',
};
}
}());

View File

@@ -30,9 +30,12 @@
"bower_components/jquery-ui/ui/minified/jquery.ui.core.min.js", "bower_components/jquery-ui/ui/minified/jquery.ui.core.min.js",
"bower_components/jquery-ui/ui/minified/jquery.ui.widget.min.js", "bower_components/jquery-ui/ui/minified/jquery.ui.widget.min.js",
"bower_components/jquery-ui/ui/minified/jquery.ui.menu.min.js",
"bower_components/jquery-ui/ui/minified/jquery.ui.mouse.min.js", "bower_components/jquery-ui/ui/minified/jquery.ui.mouse.min.js",
"bower_components/jquery-ui/ui/minified/jquery.ui.sortable.min.js", "bower_components/jquery-ui/ui/minified/jquery.ui.sortable.min.js",
"bower_components/jquery-ui/ui/minified/jquery.ui.autocomplete.min.js",
"bower_components/smart-app-banner/smart-app-banner.js", "bower_components/smart-app-banner/smart-app-banner.js",
"bower_components/taggle/src/taggle.js",
"js/habitrpg-shared.js", "js/habitrpg-shared.js",

View File

@@ -213,5 +213,7 @@
"desktopNotificationsText": "We need your permission to enable desktop notifications for new messages in party chat! Follow your browser's instructions to turn them on.<br><br>You'll receive these notifications only while you have Habitica open. If you decide you don't like them, they can be disabled in your browser's settings.<br><br>This box will close automatically when a decision is made.", "desktopNotificationsText": "We need your permission to enable desktop notifications for new messages in party chat! Follow your browser's instructions to turn them on.<br><br>You'll receive these notifications only while you have Habitica open. If you decide you don't like them, they can be disabled in your browser's settings.<br><br>This box will close automatically when a decision is made.",
"confirmAddTag": "Do you really want to add \"<%= tag %>\"?", "confirmAddTag": "Do you really want to add \"<%= tag %>\"?",
"confirmRemoveTag": "Do you really want to remove \"<%= tag %>\"?", "confirmRemoveTag": "Do you really want to remove \"<%= tag %>\"?",
"assignTask": "Assign Task" "assignTask": "Assign Task",
"desktopNotificationsText": "We need your permission to enable desktop notifications for new messages in party chat! Follow your browser's instructions to turn them on.<br><br>You'll receive these notifications only while you have Habitica open. If you decide you don't like them, they can be disabled in your browser's settings.<br><br>This box will close automatically when a decision is made.",
"claim": "Claim"
} }

View File

@@ -122,7 +122,7 @@ api.assignTask = {
let group = await Group.getGroup({user, groupId: task.group.id, fields: requiredGroupFields}); let group = await Group.getGroup({user, groupId: task.group.id, fields: requiredGroupFields});
if (!group) throw new NotFound(res.t('groupNotFound')); if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.leader !== user._id) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); if (group.leader !== user._id && user._id !== assignedUserId) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
await group.syncTask(task, assignedUser); await group.syncTask(task, assignedUser);

View File

@@ -147,7 +147,7 @@ a.pull-right.gem-wallet(ng-if='group.type!="party"', popover-trigger='mouseenter
h3.popover-title {{group.leader.profile.name}} h3.popover-title {{group.leader.profile.name}}
.popover-content .popover-content
markdown(text='group._editing ? groupCopy.leaderMessage : group.leaderMessage') markdown(text='group._editing ? groupCopy.leaderMessage : group.leaderMessage')
ul.options-menu(ng-init="groupPane = 'chat'", ng-show="group.purchased.active") ul.options-menu(ng-init="groupPane = 'chat'", ng-show="group.purchased.active")
li li
a(ng-click="groupPane = 'chat'") a(ng-click="groupPane = 'chat'")

View File

@@ -0,0 +1,4 @@
script(type='text/ng-template', id='partials/groups.tasks.meta.actions.html')
a.badge(ng-click="claim()", ng-if="!userIsAssigned()")=env.t('claim')

View File

@@ -1,4 +1,5 @@
include ./group-tasks-actions include ./group-tasks-actions
include ./group-tasks-meta-actions
include ./group-members-autocomplete include ./group-members-autocomplete
script(type='text/ng-template', id='partials/groups.tasks.html') script(type='text/ng-template', id='partials/groups.tasks.html')

View File

@@ -11,7 +11,7 @@ div(ng-if='::task.type!="reward"')
fieldset.option-group.advanced-option(ng-show="task._edit._advanced") fieldset.option-group.advanced-option(ng-show="task._edit._advanced")
group-tasks-actions(ng-if="obj.type == 'guild'", task='task', group='obj') group-tasks-actions(ng-if="obj.type == 'guild'", task='task', group='obj')
div(ng-show='task._edit._advanced') div(ng-show='task._edit._advanced')
div(ng-if='::task.type == "daily"') div(ng-if='::task.type == "daily"')
.form-group .form-group

View File

@@ -13,6 +13,8 @@
// Icons only available if you own the tasks (aka, hidden from challenge stats) // Icons only available if you own the tasks (aka, hidden from challenge stats)
span(ng-if='!obj._locked') span(ng-if='!obj._locked')
group-task-meta-actions(ng-if="obj.type == 'guild'", task='task', group='obj')
a(ng-click='pushTask(task,$index,"top")', tooltip=env.t('pushTaskToTop'), ng-class="{'push-down': ctrlPressed}") a(ng-click='pushTask(task,$index,"top")', tooltip=env.t('pushTaskToTop'), ng-class="{'push-down': ctrlPressed}")
span(ng-hide="ctrlPressed").glyphicon.glyphicon-open span(ng-hide="ctrlPressed").glyphicon.glyphicon-open
span(ng-show="ctrlPressed").glyphicon.glyphicon-save span(ng-show="ctrlPressed").glyphicon.glyphicon-save