diff --git a/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js index ea8bf122..c4119e2d 100644 --- a/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js @@ -1,6 +1,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { let computation = buildComputationFromProps(testProperties); @@ -53,30 +54,22 @@ var testProperties = [ _id: 'itemUnequippedId', type: 'item', parentId: 'charId', - left: 1, - right: 4, }), clean({ _id: 'itemUnequippedChildId', type: 'folder', parentId: 'itemUnequippedId', - left: 2, - right: 3, }), clean({ _id: 'itemEquippedId', type: 'item', equipped: true, parentId: 'charId', - left: 5, - right: 8, }), clean({ _id: 'itemEquippedChildId', type: 'folder', parentId: 'itemEquippedId', - left: 6, - right: 7, }), // Spells clean({ @@ -84,58 +77,44 @@ var testProperties = [ type: 'spell', parentId: 'charId', prepared: true, - left: 9, - right: 12, }), clean({ _id: 'spellPreparedChildId', type: 'folder', parentId: 'spellPreparedId', - left: 10, - right: 11, }), clean({ _id: 'spellAlwaysPreparedId', type: 'spell', parentId: 'charId', alwaysPrepared: true, - left: 13, - right: 16, }), clean({ _id: 'spellAlwaysPreparedChildId', type: 'folder', parentId: 'spellAlwaysPreparedId', - left: 14, - right: 15, }), clean({ _id: 'spellUnpreparedId', type: 'spell', parentId: 'charId', - left: 17, - right: 20, }), clean({ _id: 'spellUnpreparedChildId', type: 'folder', parentId: 'spellUnpreparedId', - left: 18, - right: 19, }), // Notes clean({ _id: 'NoteId', type: 'note', parentId: 'charId', - left: 21, - right: 24, }), clean({ _id: 'NoteChildId', type: 'folder', parentId: 'NoteId', - left: 22, - right: 23, }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js index 1de5205d..5ee0ee23 100644 --- a/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js @@ -1,6 +1,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { const computation = buildComputationFromProps(testProperties); @@ -13,8 +14,6 @@ var testProperties = [ clean({ _id: 'slotId', type: 'propertySlot', - left: 1, - right: 8, }), // Children clean({ @@ -23,21 +22,17 @@ var testProperties = [ slotQuantityFilled: 3, slotFillerType: 'item', parentId: 'slotId', - left: 2, - right: 3, }), clean({ _id: 'slotChildId', type: 'item', parentId: 'slotId', - left: 4, - right: 7, }), clean({ _id: 'slotGrandchildId', type: 'effect', parentId: 'slotChildId', - left: 5, - right: 6, }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js index 3ef3f8d3..5ffe3fb3 100644 --- a/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js @@ -1,6 +1,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { const computation = buildComputationFromProps(testProperties); @@ -37,38 +38,37 @@ var testProperties = [ _id: 'enabledToggleId', type: 'toggle', enabled: true, - ancestors: [{ id: 'charId' }], }), clean({ _id: 'disabledToggleId', type: 'toggle', disabled: true, - ancestors: [{ id: 'charId' }], }), clean({ _id: 'conditionToggleId', type: 'toggle', - ancestors: [{ id: 'charId' }], }), // Children clean({ _id: 'enabledToggleChildId', type: 'folder', - ancestors: [{ id: 'charId' }, { id: 'enabledToggleId' }], + parentId: 'enabledToggleId', }), clean({ _id: 'disabledToggleChildId', type: 'folder', - ancestors: [{ id: 'charId' }, { id: 'disabledToggleId' }], + parentId: 'disabledToggleId', }), clean({ _id: 'conditionToggleChildId', type: 'folder', - ancestors: [{ id: 'charId' }, { id: 'conditionToggleId' }], + parentId: 'conditionToggleId', }), clean({ _id: 'conditionToggleGrandChildId', type: 'folder', - ancestors: [{ id: 'charId' }, { id: 'conditionToggleId' }, { id: 'conditionToggleChildId' }], + parentId: 'conditionToggleChildId', }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js index 1145d74e..60c5eb22 100644 --- a/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js @@ -1,6 +1,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { const computation = buildComputationFromProps(testProperties); @@ -32,8 +33,6 @@ var testProperties = [ clean({ _id: 'spellListId', type: 'spellList', - left: 1, - right: 6, }), clean({ _id: 'childId', @@ -42,8 +41,6 @@ var testProperties = [ text: 'DC {#spellList.dc} save or suck' }, parentId: 'spellListId', - left: 2, - right: 5, }), clean({ _id: 'grandchildId', @@ -52,8 +49,6 @@ var testProperties = [ calculation: '#spellList.dc + strength + wisdom.modifier' }, parentId: 'childId', - left: 3, - right: 4, }), clean({ _id: 'strengthId', @@ -62,7 +57,7 @@ var testProperties = [ baseValue: { calculation: '15 + ', }, - left: 7, - right: 8, }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js b/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js index 201a1952..8b1d5f1d 100644 --- a/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js @@ -22,6 +22,5 @@ var testProperties = [ _id: 'strengthId', type: 'attribute', variableName: 'strength', - ancestors: [{ id: 'charId' }], }), ]; diff --git a/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js index 102b493c..e1151fa1 100644 --- a/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js @@ -2,6 +2,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/build import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { const computation = buildComputationFromProps(testProperties); @@ -20,41 +21,37 @@ var testProperties = [ type: 'class', variableName: 'wizard', classType: 'startingClass', - ancestors: [{ id: 'charId' }], }), clean({ _id: 'rangerId', type: 'class', variableName: 'ranger', classType: 'multiClass', - ancestors: [{ id: 'charId' }], }), clean({ _id: 'wiz1Id', type: 'classLevel', variableName: 'wizard', level: 1, - ancestors: [{ id: 'charId' }], }), clean({ _id: 'wiz2Id', type: 'classLevel', variableName: 'wizard', level: 2, - ancestors: [{ id: 'charId' }], }), clean({ _id: 'wiz4Id', type: 'classLevel', variableName: 'wizard', level: 4, - ancestors: [{ id: 'charId' }], }), clean({ _id: 'rang1Id', type: 'classLevel', variableName: 'ranger', level: 1, - ancestors: [{ id: 'charId' }], }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js index f4debd1a..13b8f77e 100644 --- a/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js @@ -2,6 +2,7 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/build import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation'; import clean from '../../utility/cleanProp.testFn'; +import { applyNestedSetProperties } from '/imports/api/parenting/parentingFunctions'; export default function () { const computation = buildComputationFromProps(testProperties); @@ -23,6 +24,7 @@ var testProperties = [ baseValue: { calculation: 'arrayConstant[3]', }, - ancestors: [{ id: 'charId' }], }), ]; + +applyNestedSetProperties(testProperties); diff --git a/app/imports/api/engine/computation/computeComputation/tests/computeProficiencies.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeProficiencies.testFn.js index c15831b1..da94c60e 100644 --- a/app/imports/api/engine/computation/computeComputation/tests/computeProficiencies.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeProficiencies.testFn.js @@ -44,7 +44,6 @@ var testProperties = [ clean({ _id: 'actionId', type: 'action', - ancestors: [{ id: 'charId' }], attackRoll: { calculation: 'strength.modifier', }, @@ -54,7 +53,6 @@ var testProperties = [ _id: 'profBonusId', type: 'attribute', variableName: 'proficiencyBonus', - ancestors: [{ id: 'charId' }], baseValue: { calculation: '13' }, diff --git a/app/imports/api/parenting/organizeMethods.ts b/app/imports/api/parenting/organizeMethods.ts deleted file mode 100644 index 48724985..00000000 --- a/app/imports/api/parenting/organizeMethods.ts +++ /dev/null @@ -1,102 +0,0 @@ -import SimpleSchema from 'simpl-schema'; -import { union } from 'lodash'; -import { ValidatedMethod } from 'meteor/mdg:validated-method'; -import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; -import { changeParent, fetchDocByRef, getCollectionByName } from '/imports/api/parenting/parentingFunctions'; -import { RefSchema } from '/imports/api/parenting/ChildSchema'; -import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions'; -import Creatures from '/imports/api/creature/creatures/Creatures'; - -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, parentId, order, skipRecompute, skipClient }) { - if (skipClient && this.isSimulation) { - return; - } - const collection = getCollectionByName(docRef.collection); - const [doc, parent] = await Promise.all([ - collection.findOneAsync(docRef.id), - collection.findOneAsync(parentId), - ]); - - if (!doc) throw new Meteor.Error('Document not found', 'The property to move could not be found'); - if (!parent) throw new Meteor.Error('Document not found', 'The new parent could not be found'); - // The user must be able to edit both the doc and its parent to move it - // successfully - await Promise.all([ - assertDocEditPermission(doc, this.userId), - // Only check parent if it has a different root - doc.root.id !== parent.root.id && assertDocEditPermission(parent, this.userId), - ]); - - // Change the doc's parent - await changeParent(doc, parent, collection, order); - - // Figure out which creatures need to be recalculated after this move - if (!skipRecompute && docRef.collection === 'creatures') { - const creaturesToRecompute = union[doc.root.id, parent.root.id]; - // Mark the creatures for recompute - await Creatures.updateAsync({ - _id: { $in: creaturesToRecompute } - }, { - $set: { dirty: true }, - }, { - multi: true - }); - } - }, -}); - -// TODO, rewrite -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, - }, - run({ docRef, order }) { - let doc = fetchDocByRef(docRef); - assertDocEditPermission(doc, this.userId); - safeUpdateDocOrder({ docRef, order }); - // Recompute the affected creatures - const ancestors = getCreatureAncestors(doc); - if (ancestors.length) { - Creatures.update({ - _id: { $in: ancestors } - }, { - $set: { dirty: true }, - }); - } - }, -}); - -export { organizeDoc, reorderDoc }; diff --git a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedSpells.vue b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedSpells.vue index 5f62359b..d02c246d 100644 --- a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedSpells.vue +++ b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedSpells.vue @@ -42,6 +42,7 @@ import ColumnLayout from '/imports/client/ui/components/ColumnLayout.vue'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties'; import PrintedSpell from '/imports/client/ui/creature/character/printedCharacterSheet/components/PrintedSpell.vue'; import PrintedSpellList from '/imports/client/ui/creature/character/printedCharacterSheet/components/PrintedSpellList.vue'; +import { getFilter } from '/imports/api/parenting/parentingFunctions'; export default { components: { @@ -60,23 +61,22 @@ export default { organize: false, } }, + // @ts-ignore-error Meteor not defined on vue meteor: { spellLists() { return CreatureProperties.find({ - 'ancestors.id': this.creatureId, + ...getFilter.descendantsOfRoot(this.creatureId), type: 'spellList', removed: { $ne: true }, inactive: { $ne: true }, }, { sort: { order: 1 } - }); + }).fetch(); }, spellsWithoutList() { return CreatureProperties.find({ - 'ancestors.id': { - $eq: this.creatureId, - $nin: this.spellListIds, - }, + ...getFilter.descendantsOfRoot(this.creatureId), + $not: getFilter.descendantsOfAll(this.spellLists), type: 'spell', removed: { $ne: true }, deactivatedByAncestor: { $ne: true }, @@ -90,10 +90,8 @@ export default { }, spellListsWithoutAncestorSpellLists() { return CreatureProperties.find({ - 'ancestors.id': { - $eq: this.creatureId, - $nin: this.spellListIds, - }, + ...getFilter.descendantsOfRoot(this.creatureId), + $not: getFilter.descendantsOfAll(this.spellLists), type: 'spellList', removed: { $ne: true }, inactive: { $ne: true }, @@ -101,7 +99,7 @@ export default { sort: { order: 1 } }).map(sl => { sl.spells = CreatureProperties.find({ - 'ancestors.id': sl._id, + ...getFilter.descendants(sl), type: 'spell', removed: { $ne: true }, inactive: { $ne: true }, diff --git a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedStats.vue b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedStats.vue index 4abd67ea..f83647f8 100644 --- a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedStats.vue +++ b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedStats.vue @@ -360,6 +360,7 @@ import PrintedSkill from '/imports/client/ui/creature/character/printedCharacter import PrintedDamageMultipliers from '/imports/client/ui/creature/character/printedCharacterSheet/components/PrintedDamageMultipliers.vue'; import PropertyDescription from '/imports/client/ui/properties/viewers/shared/PropertyDescription.vue'; import { uniqBy } from 'lodash'; +import { getFilter } from '/imports/api/parenting/parentingFunctions'; const getProperties = function (creature, filter, options = { sort: { order: 1 } @@ -368,7 +369,7 @@ const getProperties = function (creature, filter, options = { if (creature.settings.hideUnusedStats) { filter.hide = { $ne: true }; } - filter['ancestors.id'] = creature._id; + filter['root.id'] = creature._id; filter.removed = { $ne: true }; filter.inactive = { $ne: true }; filter.overridden = { $ne: true }; @@ -413,6 +414,7 @@ export default { doCheckLoading: false, } }, + //@ts-ignore-error Meteor not defined meteor: { creature() { return Creatures.findOne(this.creatureId, { fields: { settings: 1 } }); @@ -425,7 +427,7 @@ export default { }, toggles() { return CreatureProperties.find({ - 'ancestors.id': this.creatureId, + ...getFilter.descendantsOfRoot(this.creatureId), type: 'toggle', removed: { $ne: true }, deactivatedByAncestor: { $ne: true },