mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 21:57:22 +01:00
feat(tasks): make task copy/mirror pref per-group
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
id="taskMirrorToggle"
|
||||
class="mr-3 mb-1 ml-auto"
|
||||
:label="'Copy tasks'"
|
||||
:checked="user.preferences.tasks.mirrorGroupTasks"
|
||||
:checked="user.preferences.tasks.mirrorGroupTasks.indexOf(group._id) !== -1"
|
||||
:hover-text="'Add assigned and open tasks to your personal task board'"
|
||||
@change="changeMirrorPreference"
|
||||
/>
|
||||
@@ -431,12 +431,16 @@ export default {
|
||||
eventCategory: 'behavior',
|
||||
hitType: 'event',
|
||||
mirror: newVal,
|
||||
group: this.group._id,
|
||||
}, { trackOnClient: true });
|
||||
Analytics.updateUser({
|
||||
mirrorTasks: newVal,
|
||||
});
|
||||
const groupsToMirror = this.user.preferences.tasks.mirrorGroupTasks || [];
|
||||
if (newVal) { // we're turning copy ON for this group
|
||||
groupsToMirror.push(this.group._id);
|
||||
} else { // we're turning copy OFF for this group
|
||||
groupsToMirror.splice(groupsToMirror.indexOf(this.group._id), 1);
|
||||
}
|
||||
this.$store.dispatch('user:set', {
|
||||
'preferences.tasks.mirrorGroupTasks': newVal,
|
||||
'preferences.tasks.mirrorGroupTasks': groupsToMirror,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -385,7 +385,7 @@ api.getUserTasks = {
|
||||
url: '/tasks/user',
|
||||
middlewares: [authWithHeaders({
|
||||
// Some fields (including _id, preferences) are always loaded (see middlewares/auth)
|
||||
userFieldsToInclude: ['guilds', 'party', 'tasksOrder'],
|
||||
userFieldsToInclude: ['tasksOrder'],
|
||||
})],
|
||||
async handler (req, res) {
|
||||
const types = Tasks.tasksTypes.map(type => `${type}s`);
|
||||
|
||||
@@ -165,10 +165,11 @@ async function getTasks (req, res, options = {}) {
|
||||
} else if (group) {
|
||||
query = { 'group.id': group._id };
|
||||
} else {
|
||||
if (user.preferences.tasks.mirrorGroupTasks) {
|
||||
const groupsToMirror = user.preferences.tasks.mirrorGroupTasks;
|
||||
if (groupsToMirror && groupsToMirror.length > 0) {
|
||||
upgradedGroups = await Group.find(
|
||||
{
|
||||
_id: { $in: user.guilds.concat(user.party._id) },
|
||||
_id: { $in: groupsToMirror },
|
||||
'purchased.plan.customerId': { $exists: true },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import common from '../../../common';
|
||||
import * as Tasks from '../../models/task';
|
||||
import { model as Groups } from '../../models/group';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
@@ -132,6 +133,34 @@ export async function update (req, res, { isV3 = false }) {
|
||||
await checkNewInputForProfanity(user, res, newBlurb);
|
||||
}
|
||||
|
||||
if (req.body['preferences.tasks.mirrorGroupTasks'] !== undefined) {
|
||||
const groupsToMirror = req.body['preferences.tasks.mirrorGroupTasks'];
|
||||
if (!Array.isArray(groupsToMirror)) {
|
||||
throw new BadRequest('Groups to copy tasks from must be an array.');
|
||||
}
|
||||
const memberGroups = user.guilds;
|
||||
if (user.party._id) memberGroups.push(user.party._id);
|
||||
for (const targetGroup of groupsToMirror) {
|
||||
if (memberGroups.indexOf(targetGroup) === -1) {
|
||||
throw new BadRequest(`User not a member of group ${targetGroup}.`);
|
||||
}
|
||||
}
|
||||
|
||||
const matchingGroupsCount = await Groups.countDocuments({
|
||||
_id: { $in: groupsToMirror },
|
||||
'purchased.plan.customerId': { $exists: true },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
{ 'purchased.plan.dateTerminated': null },
|
||||
{ 'purchased.plan.dateTerminated': { $gt: new Date() } },
|
||||
],
|
||||
}).exec();
|
||||
|
||||
if (matchingGroupsCount !== groupsToMirror.length) {
|
||||
throw new BadRequest('Groups to copy tasks from must have subscriptions.');
|
||||
}
|
||||
}
|
||||
|
||||
_.each(req.body, (val, key) => {
|
||||
const purchasable = requiresPurchase[key];
|
||||
|
||||
@@ -140,7 +169,7 @@ export async function update (req, res, { isV3 = false }) {
|
||||
}
|
||||
|
||||
if (key === 'tags') {
|
||||
if (!Array.isArray(val)) throw new BadRequest('mustBeArray');
|
||||
if (!Array.isArray(val)) throw new BadRequest('Tag list must be an array.');
|
||||
|
||||
const removedTagsIds = [];
|
||||
|
||||
|
||||
@@ -1386,10 +1386,13 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all', keepC
|
||||
const promises = user.isModified() ? [user.save()] : [];
|
||||
|
||||
// remove the group from the user's groups
|
||||
const userUpdate = { $pull: { 'preferences.tasks.mirrorGroupTasks': group._id } };
|
||||
if (group.type === 'guild') {
|
||||
promises.push(User.update({ _id: user._id }, { $pull: { guilds: group._id } }).exec());
|
||||
userUpdate.$pull.guilds = group._id;
|
||||
promises.push(User.update({ _id: user._id }, userUpdate).exec());
|
||||
} else {
|
||||
promises.push(User.update({ _id: user._id }, { $set: { party: {} } }).exec());
|
||||
userUpdate.$set = { party: {} };
|
||||
promises.push(User.update({ _id: user._id }, userUpdate).exec());
|
||||
|
||||
update.$unset = { [`quest.members.${user._id}`]: 1 };
|
||||
}
|
||||
|
||||
@@ -582,7 +582,9 @@ export default new Schema({
|
||||
tasks: {
|
||||
groupByChallenge: { $type: Boolean, default: false }, // @TODO remove? not used
|
||||
confirmScoreNotes: { $type: Boolean, default: false }, // @TODO remove? not used
|
||||
mirrorGroupTasks: { $type: Boolean, default: false },
|
||||
mirrorGroupTasks: [
|
||||
{ $type: String, validate: [v => validator.isUUID(v), 'Invalid group UUID.'], ref: 'Group' },
|
||||
],
|
||||
},
|
||||
improvementCategories: {
|
||||
$type: Array,
|
||||
|
||||
Reference in New Issue
Block a user