feat: allowing modification of challenge tasks after challenge creation. fixes #7320

closes #7877
This commit is contained in:
Husman
2016-08-06 15:32:03 -07:00
committed by Blade Barringer
parent 89822222fe
commit 725c3b36f3
10 changed files with 104 additions and 17 deletions

View File

@@ -158,4 +158,57 @@ describe('Challenge Model', () => {
});
});
});
context('type specific updates', () => {
it('updates habit specific field to challenge and challenge members', async () => {
task = new Tasks.habit(Tasks.Task.sanitize(tasksToTest.habit)); // eslint-disable-line babel/new-cap
task.challenge.id = challenge._id;
await task.save();
await challenge.addTasks([task]);
task.up = true;
task.down = false;
await challenge.updateTask(task);
let updatedLeader = await User.findOne({_id: leader._id});
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.habits[0]);
expect(updatedUserTask.up).to.equal(true);
expect(updatedUserTask.down).to.equal(false);
});
it('updates todo specific field to challenge and challenge members', async () => {
task = new Tasks.todo(Tasks.Task.sanitize(tasksToTest.todo)); // eslint-disable-line babel/new-cap
task.challenge.id = challenge._id;
await task.save();
await challenge.addTasks([task]);
task.date = new Date();
await challenge.updateTask(task);
let updatedLeader = await User.findOne({_id: leader._id});
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.todos[0]);
expect(updatedUserTask.date).to.exist;
});
it('updates daily specific field to challenge and challenge members', async () => {
task = new Tasks.daily(Tasks.Task.sanitize(tasksToTest.daily)); // eslint-disable-line babel/new-cap
task.challenge.id = challenge._id;
await task.save();
await challenge.addTasks([task]);
task.everyX = 2;
await challenge.updateTask(task);
let updatedLeader = await User.findOne({_id: leader._id});
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.dailys[0]);
expect(updatedUserTask.everyX).to.eql(2);
});
});
});

View File

@@ -1,5 +1,5 @@
habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', 'Challenges', 'Notification', '$compile', 'Groups', '$state', '$stateParams', 'Members', 'Tasks', 'TAVERN_ID',
function($rootScope, $scope, Shared, User, Challenges, Notification, $compile, Groups, $state, $stateParams, Members, Tasks, TAVERN_ID) {
habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', 'Tasks', 'Challenges', 'Notification', '$compile', 'Groups', '$state', '$stateParams', 'Members', 'Tasks', 'TAVERN_ID',
function($rootScope, $scope, Shared, User, Tasks, Challenges, Notification, $compile, Groups, $state, $stateParams, Members, Tasks, TAVERN_ID) {
// Use presence of cid to determine whether to show a list or a single
// challenge
@@ -36,6 +36,22 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
$scope.editTask = Tasks.editTask;
$scope.canEdit = function(task) {
return true;
}
$scope.doubleClickTask = function (obj, task) {
if (obj._locked) {
return false;
}
if (task._editing) {
$scope.saveTask(task);
} else {
$scope.editTask(task);
}
}
/**
* Create
*/
@@ -274,8 +290,8 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
};
$scope.saveTask = function(task){
Tasks.updateTask(task._id, task);
task._editing = false;
// TODO persist
}
$scope.toggleBulk = function(list) {

View File

@@ -70,6 +70,23 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
$scope.editTask = Tasks.editTask;
$scope.canEdit = function(task) {
// can't edit challenge tasks
return !task.challenge.id;
}
$scope.doubleClickTask = function (obj, task) {
if (obj._locked) {
return false;
}
if (task._editing) {
$scope.saveTask(task);
} else {
$scope.editTask(task);
}
}
/**
* Add the new task to the actions log
*/

View File

@@ -209,8 +209,9 @@ schema.methods.updateTask = async function challengeUpdateTask (task) {
updateCmd.$set[key] = syncableAttrs[key];
}
let taskSchema = Tasks[task.type];
// Updating instead of loading and saving for performances, risks becoming a problem if we introduce more complexity in tasks
await Tasks.Task.update({
await taskSchema.update({
userId: {$exists: true},
'challenge.id': challenge.id,
'challenge.taskId': task._id,

View File

@@ -18,13 +18,13 @@ div(ng-if='::task.type!="reward"')
input.form-control(type='text', ng-model='task.startDate',
datepicker-popup='{{::user.preferences.dateFormat}}', is-open='datepickerOpened',
ng-click='datepickerOpened = true', ng-disabled='task.challenge.id')
ng-click='datepickerOpened = true', ng-disabled='!canEdit(task)')
hr
.form-group
legend.option-title=env.t('repeat')
select.form-control(ng-model='task.frequency', ng-disabled='task.challenge.id')
select.form-control(ng-model='task.frequency', ng-disabled='!canEdit(task)')
option(value='weekly')=env.t('repeatWeek')
option(value='daily')=env.t('repeatDays')
@@ -39,19 +39,19 @@ div(ng-if='::task.type!="reward"')
ul.priority-multiplier
li
button(type='button', ng-class='{active: task.priority==0.1}',
ng-click='task.challenge.id || (task.priority=0.1)')
ng-click='!canEdit(task) || (task.priority=0.1)')
=env.t('trivial')
li
button(type='button', ng-class='{active: task.priority==1 || !task.priority}',
ng-click='task.challenge.id || (task.priority=1)')
ng-click='!canEdit(task) || (task.priority=1)')
=env.t('easy')
li
button(type='button', ng-class='{active: task.priority==1.5}',
ng-click='task.challenge.id || (task.priority=1.5)')
ng-click='!canEdit(task) || (task.priority=1.5)')
=env.t('medium')
li
button(type='button', ng-class='{active: task.priority==2}',
ng-click='task.challenge.id || (task.priority=2)')
ng-click='!canEdit(task) || (task.priority=2)')
=env.t('hard')
span(ng-if='task.type=="daily"')

View File

@@ -3,9 +3,9 @@ legend.option-title
popover='{{env.t(task.frequency + "RepeatHelpContent")}}')=env.t('repeatEvery')
// If frequency is daily
ng-form.form-group(name='everyX' ng-if='task.frequency=="daily"')
ng-form.form-group(name='everyX', ng-if='task.frequency=="daily"')
.input-group
input.form-control(type='number', ng-model='task.everyX', ng-disabled='task.challenge.id', min='0', required)
input.form-control(type='number', ng-model='task.everyX', min='0', ng-disabled='!canEdit(task)', required)
span.input-group-addon {{task.everyX == 1 ? env.t('day') : env.t('days')}}
// If frequency is weekly
@@ -15,7 +15,7 @@ ng-form.form-group(name='everyX' ng-if='task.frequency=="daily"')
mixin dayOfWeek(day, num)
li
button(type='button', ng-class='{active: task.repeat.#{day}}',
ng-disabled='task.challenge.id', ng-click='task.repeat.#{day} = !task.repeat.#{day}',
ng-disabled='!canEdit(task)', ng-click='task.repeat.#{day} = !task.repeat.#{day}',
tooltip='{{env.t((task.repeat.#{day}) ? "due" : "notDue")}}')
| {{::moment.weekdaysMin(#{num})}}

View File

@@ -1,4 +1,4 @@
fieldset.option-group.plusminus(ng-if='task.type=="habit" && !task.challenge.id')
fieldset.option-group.plusminus(ng-if='task.type=="habit" && canEdit(task)')
legend.option-title=env.t('direction/Actions')
span.task-checker
input.visuallyhidden.focusable(id='{{obj._id}}_{{task._id}}-option-plus', type='checkbox', ng-model='task.up')

View File

@@ -1,6 +1,6 @@
fieldset.option-group
label.option-title=env.t('text')
input.form-control(type='text', ng-model='task.text', required, ng-disabled='task.challenge.id')
input.form-control(type='text', ng-model='task.text', ng-disabled='!canEdit(task)', required)
fieldset.option-group
label.option-title=env.t('extraNotes')

View File

@@ -1,4 +1,4 @@
fieldset.option-group(ng-if='task.type=="todo" && !task.challenge.id')
fieldset.option-group(ng-if='task.type=="todo" && canEdit(task)')
legend.option-title=env.t('dueDate')
input.option-content.datepicker(type='text', ng-model='task.date',
datepicker-popup='{{::user.preferences.dateFormat}}', is-open='datepickerOpened',

View File

@@ -37,7 +37,7 @@
label(for='box-{{::obj._id}}_{{::task._id}}')
// main content
.task-text(ng-dblclick='task._editing ? saveTask(task) : editTask(task, user)')
.task-text(ng-dblclick='doubleClickTask(obj, task)')
markdown(text='task.text',target='_blank')
div(ng-if='task.checklist && !$state.includes("options.social.challenges") && !task.collapseChecklist && !task._editing')