Files
DiceCloud/app/imports/api/parenting/organizeMethods.js
2023-12-18 23:12:39 +02:00

119 lines
3.5 KiB
JavaScript

import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { RefSchema } from '/imports/api/parenting/ChildSchema';
import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import { changeParent, fetchDocByRefAsync, getCollectionByName, rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
const organizeDoc = new ValidatedMethod({
name: 'organize.organizeDoc',
validate: new SimpleSchema({
docRef: RefSchema,
parentRef: RefSchema,
order: {
type: Number,
// Should end in 0.5 to place it reliably between two existing documents
},
skipRecompute: {
type: Boolean,
optional: true,
},
skipClient: {
type: Boolean,
optional: true,
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
async run({ docRef, parentRef, order, skipRecompute, skipClient }) {
if (skipClient && this.isSimulation) {
return;
}
let doc = await fetchDocByRefAsync(docRef);
let collection = getCollectionByName(docRef.collection);
// The user must be able to edit both the doc and its parent to move it
// successfully
assertDocEditPermission(doc, this.userId);
let parent;
parent = await fetchDocByRefAsync(parentRef);
assertDocEditPermission(parent, this.userId);
// Moving the doc to the root level means changing its parent to undefined
if (doc.root.id === parent._id) {
parent = null;
}
// Change the doc's parent
await changeParent(doc, parent, collection, order);
// Figure out which creatures need to be recalculated after this move
const docCreature = getCreatureAncestorId(doc);
const parentCreature = getCreatureAncestorId(parent);
// Mark the creatures for recompute
if (!skipRecompute) {
if (docCreature) {
Creatures.updateAsync({
_id: docCreature,
}, {
$set: { dirty: true },
});
}
if (parentCreature && parentCreature !== docCreature) {
Creatures.updateAsync({
_id: parentCreature,
}, {
$set: { dirty: true },
});
}
}
},
});
const reorderDoc = new ValidatedMethod({
name: 'organize.reorderDoc',
validate: new SimpleSchema({
docRef: RefSchema,
order: {
type: Number,
// Should end in 0.5 to place it reliably between two existing documents
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
async run({ docRef, order }) {
const doc = await fetchDocByRefAsync(docRef);
assertDocEditPermission(doc, this.userId);
let collection = getCollectionByName(docRef.collection);
console.log('setting doc left to ', order);
await collection.updateAsync(doc._id, { $set: { left: order } });
// Recompute the affected creatures
const creatureId = getCreatureAncestorId(doc);
if (creatureId) {
return Creatures.updateAsync({
_id: creatureId
}, {
$set: { dirty: true },
});
}
},
});
function getCreatureAncestorId(doc) {
if (doc.type === 'pc' || doc.type === 'npc' || doc.type === 'monster') {
return doc._id;
}
if (doc?.root?.collection === 'creatures') {
return doc.root.id;
}
}
export { organizeDoc, reorderDoc };