Merge feature-nested-sets into develop
This commit is contained in:
@@ -1,15 +1,35 @@
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ColorSchema from '/imports/api/properties/subSchemas/ColorSchema.js';
|
||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||
import SoftRemovableSchema from '/imports/api/parenting/SoftRemovableSchema.js';
|
||||
import propertySchemasIndex from '/imports/api/properties/computedPropertySchemasIndex.js';
|
||||
import { storedIconsSchema } from '/imports/api/icons/Icons.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import ColorSchema from '/imports/api/properties/subSchemas/ColorSchema';
|
||||
import ChildSchema, { TreeDoc } from '/imports/api/parenting/ChildSchema';
|
||||
import SoftRemovableSchema from '/imports/api/parenting/SoftRemovableSchema';
|
||||
import propertySchemasIndex from '/imports/api/properties/computedPropertySchemasIndex';
|
||||
import { storedIconsSchema } from '/imports/api/icons/Icons';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
|
||||
let CreatureProperties = new Mongo.Collection('creatureProperties');
|
||||
const CreatureProperties: Mongo.Collection<CreatureProperty> = new Mongo.Collection('creatureProperties');
|
||||
|
||||
let CreaturePropertySchema = new SimpleSchema({
|
||||
export interface CreatureProperty extends TreeDoc {
|
||||
_id: string
|
||||
_migrationError?: string
|
||||
type: string
|
||||
tags: string[]
|
||||
disabled?: boolean
|
||||
icon?: {
|
||||
name: string
|
||||
shape: string
|
||||
},
|
||||
libraryNodeId?: string
|
||||
slotQuantityFilled?: number
|
||||
inactive?: boolean
|
||||
deactivatedByAncestor?: boolean
|
||||
deactivatedBySelf?: boolean
|
||||
deactivatedByToggle?: boolean
|
||||
deactivatingToggleId?: boolean
|
||||
dirty?: boolean
|
||||
}
|
||||
|
||||
const CreaturePropertySchema = new SimpleSchema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
@@ -56,7 +76,7 @@ let CreaturePropertySchema = new SimpleSchema({
|
||||
|
||||
const DenormalisedOnlyCreaturePropertySchema = new SimpleSchema({
|
||||
// Denormalised flag if this property is inactive on the sheet for any reason
|
||||
// Including being disabled, or a decendent of a disabled property
|
||||
// Including being disabled, or a descendant of a disabled property
|
||||
inactive: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
@@ -135,13 +155,14 @@ const DenormalisedOnlyCreaturePropertySchema = new SimpleSchema({
|
||||
|
||||
CreaturePropertySchema.extend(DenormalisedOnlyCreaturePropertySchema);
|
||||
|
||||
for (let key in propertySchemasIndex) {
|
||||
let schema = new SimpleSchema({});
|
||||
for (const key in propertySchemasIndex) {
|
||||
const schema = new SimpleSchema({});
|
||||
schema.extend(propertySchemasIndex[key]);
|
||||
schema.extend(CreaturePropertySchema);
|
||||
schema.extend(ColorSchema);
|
||||
schema.extend(ChildSchema);
|
||||
schema.extend(SoftRemovableSchema);
|
||||
// @ts-expect-error don't have types for .attachSchema
|
||||
CreatureProperties.attachSchema(schema, {
|
||||
selector: { type: key }
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getCreature } from '/imports/api/engine/loadCreatures';
|
||||
|
||||
export default function getRootCreatureAncestor(property) {
|
||||
return getCreature(property.ancestors[0].id);
|
||||
return getCreature(property.root.id);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
|
||||
const adjustQuantity = new ValidatedMethod({
|
||||
name: 'creatureProperties.adjustQuantity',
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema';
|
||||
import {
|
||||
assertEditPermission,
|
||||
assertDocEditPermission,
|
||||
assertCopyPermission
|
||||
} from '/imports/api/sharing/sharingPermissions.js';
|
||||
} from '/imports/api/sharing/sharingPermissions';
|
||||
import {
|
||||
setLineageOfDocs,
|
||||
getAncestry,
|
||||
fetchDocByRef,
|
||||
getFilter,
|
||||
renewDocIds
|
||||
} from '/imports/api/parenting/parenting.js';
|
||||
import { reorderDocs } from '/imports/api/parenting/order.js';
|
||||
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
} from '/imports/api/parenting/parentingFunctions';
|
||||
import { rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
|
||||
import Libraries from '/imports/api/library/Libraries';
|
||||
const DUPLICATE_CHILDREN_LIMIT = 500;
|
||||
|
||||
const copyPropertyToLibrary = new ValidatedMethod({
|
||||
@@ -41,33 +40,30 @@ const copyPropertyToLibrary = new ValidatedMethod({
|
||||
},
|
||||
run({ propId, parentRef, order }) {
|
||||
// get the new ancestry for the properties
|
||||
let { parentDoc, ancestors } = getAncestry({ parentRef });
|
||||
const parentDoc = fetchDocByRef(parentRef);
|
||||
|
||||
// Check permission to edit the destination
|
||||
let rootLibrary;
|
||||
if (parentRef.collection === 'libraries') {
|
||||
rootLibrary = parentDoc;
|
||||
} else if (parentRef.collection === 'libraryNodes') {
|
||||
rootLibrary = Libraries.findOne(parentDoc.ancestors[0].id)
|
||||
rootLibrary = Libraries.findOne(parentDoc.root.id)
|
||||
} else {
|
||||
throw `${parentRef.collection} is not a valid parent collection`
|
||||
}
|
||||
assertEditPermission(rootLibrary, this.userId);
|
||||
|
||||
const insertedRootNode = insertNodeFromProperty(propId, ancestors, order, this);
|
||||
const insertedRootNode = insertNodeFromProperty(propId, order, this);
|
||||
|
||||
// Tree structure changed by inserts, reorder the tree
|
||||
reorderDocs({
|
||||
collection: LibraryNodes,
|
||||
ancestorId: rootLibrary._id,
|
||||
});
|
||||
rebuildNestedSets(LibraryNodes, rootLibrary._id);
|
||||
|
||||
// Return the docId of the inserted root property
|
||||
return insertedRootNode?._id;
|
||||
},
|
||||
});
|
||||
|
||||
function insertNodeFromProperty(propId, ancestors, order, method) {
|
||||
function insertNodeFromProperty(propId, order, method) {
|
||||
// Fetch the property and its descendants, provided they have not been
|
||||
// removed
|
||||
let prop = CreatureProperties.findOne({
|
||||
@@ -87,9 +83,9 @@ function insertNodeFromProperty(propId, ancestors, order, method) {
|
||||
// Make sure we can edit this property
|
||||
assertDocEditPermission(prop, method.userId);
|
||||
|
||||
let oldParent = prop.parent;
|
||||
let oldParentId = prop.parentId;
|
||||
const propCursor = CreatureProperties.find({
|
||||
'ancestors.id': propId,
|
||||
...getFilter.descendants(prop),
|
||||
removed: { $ne: true },
|
||||
});
|
||||
|
||||
@@ -109,13 +105,6 @@ function insertNodeFromProperty(propId, ancestors, order, method) {
|
||||
// properties
|
||||
assertSourceLibraryCopyPermission(props, method);
|
||||
|
||||
// re-map all the ancestors
|
||||
setLineageOfDocs({
|
||||
docArray: props,
|
||||
newAncestry: ancestors,
|
||||
oldParent,
|
||||
});
|
||||
|
||||
// Give the docs new IDs without breaking internal references
|
||||
renewDocIds({
|
||||
docArray: props,
|
||||
@@ -123,14 +112,8 @@ function insertNodeFromProperty(propId, ancestors, order, method) {
|
||||
});
|
||||
|
||||
// Order the root node
|
||||
if (order === undefined) {
|
||||
setDocToLastOrder({
|
||||
collection: LibraryNodes,
|
||||
doc: prop,
|
||||
});
|
||||
} else {
|
||||
prop.order = order;
|
||||
}
|
||||
prop.left = Number.MAX_SAFE_INTEGER - 1;
|
||||
prop.right = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
// Clean the props
|
||||
props = cleanProps(props);
|
||||
@@ -142,8 +125,8 @@ function insertNodeFromProperty(propId, ancestors, order, method) {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {[Property]} props The properties to check
|
||||
* @param {String} userId The userId trying to copy these properties to a library
|
||||
* @param props The properties to check
|
||||
* @param userId The userId trying to copy these properties to a library
|
||||
* Checks that every property can be copied out of the library that originated it by this user
|
||||
*/
|
||||
function assertSourceLibraryCopyPermission(props, method) {
|
||||
@@ -162,9 +145,9 @@ function assertSourceLibraryCopyPermission(props, method) {
|
||||
LibraryNodes.find({
|
||||
_id: { $in: libraryNodeIds }
|
||||
}, {
|
||||
fields: { ancestors: 1 }
|
||||
fields: { root: 1 }
|
||||
}).forEach(node => {
|
||||
sourceLibIds.add(node.ancestors?.[0]?.id);
|
||||
sourceLibIds.add(node.root.id);
|
||||
});
|
||||
|
||||
// Assert copy permission on each of those libraries
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers.js';
|
||||
import ActionContext from '/imports/api/engine/actions/ActionContext.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers';
|
||||
import ActionContext from '/imports/api/engine/actions/ActionContext';
|
||||
|
||||
const damageProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.damage',
|
||||
@@ -28,7 +28,7 @@ const damageProperty = new ValidatedMethod({
|
||||
if (!prop) throw new Meteor.Error(
|
||||
'Damage property failed', 'Property doesn\'t exist'
|
||||
);
|
||||
const creatureId = prop.ancestors[0].id;
|
||||
const creatureId = prop.root.id;
|
||||
const actionContext = new ActionContext(creatureId, [creatureId], this);
|
||||
|
||||
// Check permissions
|
||||
@@ -59,7 +59,7 @@ const damageProperty = new ValidatedMethod({
|
||||
},
|
||||
});
|
||||
|
||||
export function damagePropertyWork({ prop, operation, value, actionContext, logFunction }) {
|
||||
export function damagePropertyWork({ prop, operation, value, actionContext, logFunction = undefined }) {
|
||||
|
||||
// Save the value to the scope before applying the before triggers
|
||||
if (operation === 'increment') {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import {
|
||||
setLineageOfDocs,
|
||||
getFilter,
|
||||
renewDocIds
|
||||
} from '/imports/api/parenting/parenting.js';
|
||||
import { reorderDocs } from '/imports/api/parenting/order.js';
|
||||
} from '/imports/api/parenting/parentingFunctions';
|
||||
import { rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
|
||||
var snackbar;
|
||||
if (Meteor.isClient) {
|
||||
snackbar = require(
|
||||
'/imports/client/ui/components/snackbars/SnackbarQueue.js'
|
||||
'/imports/client/ui/components/snackbars/SnackbarQueue'
|
||||
).snackbar
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ const duplicateProperty = new ValidatedMethod({
|
||||
},
|
||||
run({ _id }) {
|
||||
let property = CreatureProperties.findOne(_id);
|
||||
if (!property) throw new Meteor.Error('not-found', 'The source property was not found');
|
||||
|
||||
let creature = getRootCreatureAncestor(property);
|
||||
|
||||
assertEditPermission(creature, this.userId);
|
||||
@@ -49,7 +51,7 @@ const duplicateProperty = new ValidatedMethod({
|
||||
|
||||
// Get all the descendants
|
||||
let nodes = CreatureProperties.find({
|
||||
'ancestors.id': _id,
|
||||
...getFilter.descendants(property),
|
||||
removed: { $ne: true },
|
||||
}, {
|
||||
limit: DUPLICATE_CHILDREN_LIMIT + 1,
|
||||
@@ -66,22 +68,13 @@ const duplicateProperty = new ValidatedMethod({
|
||||
}
|
||||
}
|
||||
|
||||
// re-map all the ancestors
|
||||
setLineageOfDocs({
|
||||
docArray: nodes,
|
||||
newAncestry: [
|
||||
...property.ancestors,
|
||||
{ id: propertyId, collection: 'creatureProperties' }
|
||||
],
|
||||
oldParent: { id: _id, collection: 'creatureProperties' },
|
||||
});
|
||||
|
||||
// Give the docs new IDs without breaking internal references
|
||||
const allNodes = [property, ...nodes];
|
||||
renewDocIds({ docArray: allNodes });
|
||||
|
||||
// Order the root node
|
||||
property.order += 0.5;
|
||||
property.left = Number.MAX_SAFE_INTEGER - 1;
|
||||
property.right = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
// Mark the sheet as needing recompute
|
||||
property.dirty = true;
|
||||
@@ -90,10 +83,7 @@ const duplicateProperty = new ValidatedMethod({
|
||||
CreatureProperties.batchInsert(allNodes);
|
||||
|
||||
// Tree structure changed by inserts, reorder the tree
|
||||
reorderDocs({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: property.ancestors[0].id,
|
||||
});
|
||||
rebuildNestedSets(CreatureProperties, property.root.id);
|
||||
|
||||
return propertyId;
|
||||
},
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { organizeDoc } from '/imports/api/parenting/organizeMethods.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS.js';
|
||||
import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import { organizeDoc } from '/imports/api/parenting/organizeMethods';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS';
|
||||
import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag';
|
||||
|
||||
// Equipping or unequipping an item will also change its parent
|
||||
const equipItem = new ValidatedMethod({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
|
||||
const flipToggle = new ValidatedMethod({
|
||||
name: 'creatureProperties.flipToggle',
|
||||
@@ -17,7 +17,7 @@ const flipToggle = new ValidatedMethod({
|
||||
run({ _id }) {
|
||||
// Permission
|
||||
let property = CreatureProperties.findOne(_id, {
|
||||
fields: { type: 1, ancestors: 1, enabled: 1, disabled: 1 }
|
||||
fields: { type: 1, root: 1, enabled: 1, disabled: 1 }
|
||||
});
|
||||
if (property.type !== 'toggle') {
|
||||
throw new Meteor.Error('wrong property',
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { getFilter } from '/imports/api/parenting/parentingFunctions';
|
||||
|
||||
export default function getParentRefByTag(creatureId, tag){
|
||||
export default function getParentRefByTag(creatureId, tag) {
|
||||
let prop = CreatureProperties.findOne({
|
||||
'ancestors.id': creatureId,
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
...getFilter.descendantsOfRoot(creatureId),
|
||||
removed: { $ne: true },
|
||||
inactive: { $ne: true },
|
||||
tags: tag,
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
sort: { order: 1 },
|
||||
});
|
||||
return prop && {id: prop._id, collection: 'creatureProperties'};
|
||||
return prop && { id: prop._id, collection: 'creatureProperties' };
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { getFilter } from "/imports/api/parenting/parentingFunctions";
|
||||
|
||||
export default function getSlotFillFilter({ slot, libraryIds }) {
|
||||
|
||||
if (!slot) throw 'Slot is required for getSlotFillFilter';
|
||||
@@ -6,9 +8,14 @@ export default function getSlotFillFilter({ slot, libraryIds }) {
|
||||
let filter = {
|
||||
fillSlots: true,
|
||||
removed: { $ne: true },
|
||||
$and: []
|
||||
$and: [],
|
||||
};
|
||||
filter['ancestors.id'] = { $in: libraryIds };
|
||||
if (libraryIds.length) {
|
||||
Object.assign(
|
||||
filter,
|
||||
getFilter.descendantsOfAllRoots(libraryIds)
|
||||
);
|
||||
}
|
||||
if (slot.slotType) {
|
||||
filter.$and.push({
|
||||
$or: [{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { assert } from 'chai';
|
||||
import getSlotFillFilter from '/imports/api/creature/creatureProperties/methods/getSlotFillFilter.js';
|
||||
import getSlotFillFilter from '/imports/api/creature/creatureProperties/methods/getSlotFillFilter';
|
||||
|
||||
describe('Slot fill filter', function () {
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('Slot fill filter', function () {
|
||||
$or: [{
|
||||
libraryTags: { $all: ['tag1', 'tag2'] }
|
||||
}],
|
||||
'ancestors.id': { $in: ['libraryId1', 'libraryId2'] },
|
||||
'root.id': { $in: ['libraryId1', 'libraryId2'] },
|
||||
removed: { $ne: true },
|
||||
fillSlots: true,
|
||||
});
|
||||
@@ -76,7 +76,7 @@ describe('Slot fill filter', function () {
|
||||
$and: [
|
||||
{ libraryTags: { $nin: ['tag5', 'tag6', 'tag7', 'tag8'] } },
|
||||
],
|
||||
'ancestors.id': { $in: ['libraryId1', 'libraryId2'] },
|
||||
'root.id': { $in: ['libraryId1', 'libraryId2'] },
|
||||
removed: { $ne: true },
|
||||
fillSlots: true,
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import '/imports/api/creature/creatureProperties/methods/adjustQuantity.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/copyPropertyToLibrary.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/duplicateProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/equipItem.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/insertProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/pullFromProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/pushToProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/restoreProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/selectAmmoItem.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/softRemoveProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/updateCreatureProperty.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/flipToggle.js';
|
||||
import '/imports/api/creature/creatureProperties/methods/adjustQuantity';
|
||||
import '/imports/api/creature/creatureProperties/methods/copyPropertyToLibrary';
|
||||
import '/imports/api/creature/creatureProperties/methods/damageProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/duplicateProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/equipItem';
|
||||
import '/imports/api/creature/creatureProperties/methods/insertProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode';
|
||||
import '/imports/api/creature/creatureProperties/methods/pullFromProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/pushToProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/restoreProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/selectAmmoItem';
|
||||
import '/imports/api/creature/creatureProperties/methods/softRemoveProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/updateCreatureProperty';
|
||||
import '/imports/api/creature/creatureProperties/methods/flipToggle';
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { reorderDocs } from '/imports/api/parenting/order.js';
|
||||
import { getAncestry } from '/imports/api/parenting/parenting.js';
|
||||
import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag.js';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||
import { getHighestOrder } from '/imports/api/parenting/order.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import { fetchDocByRef, rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
|
||||
import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema';
|
||||
|
||||
const insertProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.insert',
|
||||
@@ -25,27 +23,23 @@ const insertProperty = new ValidatedMethod({
|
||||
timeInterval: 5000,
|
||||
},
|
||||
run({ creatureProperty, parentRef }) {
|
||||
// get the new ancestry for the properties
|
||||
let { parentDoc, ancestors } = getAncestry({ parentRef });
|
||||
let rootCreature;
|
||||
const parentDoc = fetchDocByRef(parentRef);
|
||||
|
||||
// Check permission to edit
|
||||
let rootCreature;
|
||||
if (parentRef.collection === 'creatures') {
|
||||
rootCreature = parentDoc;
|
||||
} else if (parentRef.collection === 'creatureProperties') {
|
||||
rootCreature = getRootCreatureAncestor(parentDoc);
|
||||
creatureProperty.parentId = parentDoc._id;
|
||||
} else {
|
||||
throw `${parentRef.collection} is not a valid parent collection`
|
||||
}
|
||||
assertEditPermission(rootCreature, this.userId);
|
||||
|
||||
creatureProperty.parent = parentRef;
|
||||
creatureProperty.ancestors = ancestors;
|
||||
creatureProperty.root = { collection: 'creatures', id: rootCreature._id };
|
||||
|
||||
return insertPropertyWork({
|
||||
property: creatureProperty,
|
||||
creature: rootCreature,
|
||||
});
|
||||
return insertPropertyWork(creatureProperty);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -77,18 +71,17 @@ const insertPropertyAsChildOfTag = new ValidatedMethod({
|
||||
},
|
||||
run({ creatureProperty, creatureId, tag, tagDefaultName }) {
|
||||
let parentRef = getParentRefByTag(creatureId, tag);
|
||||
let insertFolderFirst = false;
|
||||
|
||||
if (!parentRef) {
|
||||
// Use the creature as the parent and mark that we need to insert the folder first later
|
||||
var insertFolderFirst = true;
|
||||
insertFolderFirst = true;
|
||||
parentRef = { id: creatureId, collection: 'creatures' };
|
||||
}
|
||||
|
||||
// get the new ancestry for the properties
|
||||
let { parentDoc, ancestors } = getAncestry({ parentRef });
|
||||
|
||||
// Check permission to edit
|
||||
let rootCreature;
|
||||
const parentDoc = fetchDocByRef(parentRef);
|
||||
if (parentRef.collection === 'creatures') {
|
||||
rootCreature = parentDoc;
|
||||
} else if (parentRef.collection === 'creatureProperties') {
|
||||
@@ -98,46 +91,34 @@ const insertPropertyAsChildOfTag = new ValidatedMethod({
|
||||
}
|
||||
assertEditPermission(rootCreature, this.userId);
|
||||
|
||||
const root = { collection: 'creatures', id: rootCreature._id };
|
||||
|
||||
// Add the folder first if we need to
|
||||
if (insertFolderFirst) {
|
||||
let order = getHighestOrder({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: parentRef.id,
|
||||
}) + 1;
|
||||
let id = CreatureProperties.insert({
|
||||
type: 'folder',
|
||||
name: tagDefaultName || (tag.charAt(0).toUpperCase() + tag.slice(1)),
|
||||
tags: [tag],
|
||||
parent: parentRef,
|
||||
ancestors: [parentRef],
|
||||
order,
|
||||
// parentId: undefined,
|
||||
root,
|
||||
});
|
||||
// Make the folder our new parent
|
||||
let newParentRef = { id, collection: 'creatureProperties' };
|
||||
ancestors = [parentRef, newParentRef];
|
||||
parentRef = newParentRef;
|
||||
creatureProperty.order = order + 1;
|
||||
parentRef = { id, collection: 'creatureProperties' };
|
||||
}
|
||||
|
||||
creatureProperty.parent = parentRef;
|
||||
creatureProperty.ancestors = ancestors;
|
||||
creatureProperty.root = root;
|
||||
creatureProperty.parentId = parentRef.id;
|
||||
|
||||
return insertPropertyWork({
|
||||
property: creatureProperty,
|
||||
creature: rootCreature,
|
||||
});
|
||||
return insertPropertyWork(creatureProperty);
|
||||
},
|
||||
});
|
||||
|
||||
export function insertPropertyWork({ property, creature }) {
|
||||
export function insertPropertyWork(property) {
|
||||
delete property._id;
|
||||
property.dirty = true;
|
||||
let _id = CreatureProperties.insert(property);
|
||||
// Tree structure changed by insert, reorder the tree
|
||||
reorderDocs({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: creature._id,
|
||||
});
|
||||
rebuildNestedSets(CreatureProperties, property.root.id);
|
||||
return _id;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import {
|
||||
setLineageOfDocs,
|
||||
getAncestry,
|
||||
renewDocIds
|
||||
} from '/imports/api/parenting/parenting.js';
|
||||
import { reorderDocs } from '/imports/api/parenting/order.js';
|
||||
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
|
||||
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
|
||||
renewDocIds,
|
||||
fetchDocByRef,
|
||||
rebuildNestedSets,
|
||||
getFilter
|
||||
} from '/imports/api/parenting/parentingFunctions';
|
||||
import { union } from 'lodash';
|
||||
|
||||
const insertPropertyFromLibraryNode = new ValidatedMethod({
|
||||
@@ -30,19 +28,15 @@ const insertPropertyFromLibraryNode = new ValidatedMethod({
|
||||
parentRef: {
|
||||
type: RefSchema,
|
||||
},
|
||||
order: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
}).validator(),
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 5,
|
||||
timeInterval: 5000,
|
||||
},
|
||||
run({ nodeIds, parentRef, order }) {
|
||||
run({ nodeIds, parentRef }) {
|
||||
// get the new ancestry for the properties
|
||||
let { parentDoc, ancestors } = getAncestry({ parentRef });
|
||||
const parentDoc = fetchDocByRef(parentRef);
|
||||
|
||||
// Check permission to edit
|
||||
let rootCreature;
|
||||
@@ -55,37 +49,32 @@ const insertPropertyFromLibraryNode = new ValidatedMethod({
|
||||
}
|
||||
assertEditPermission(rootCreature, this.userId);
|
||||
|
||||
// {libraryId: hasViewPermission}
|
||||
//let libraryPermissionMemoir = {};
|
||||
const root = { collection: 'creatures', id: rootCreature._id };
|
||||
const parentId = parentRef.id;
|
||||
|
||||
let node;
|
||||
nodeIds.forEach(nodeId => {
|
||||
// TODO: Check library view permission for each node before starting
|
||||
node = insertPropertyFromNode(nodeId, ancestors, order);
|
||||
node = insertPropertyFromNode(nodeId, root, parentId);
|
||||
});
|
||||
|
||||
// get one of the root inserted docs
|
||||
let rootId = node._id;
|
||||
|
||||
// Tree structure changed by inserts, reorder the tree
|
||||
reorderDocs({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: rootCreature._id,
|
||||
});
|
||||
// Return the docId of the last property, the inserted root property
|
||||
return rootId;
|
||||
rebuildNestedSets(CreatureProperties, rootCreature._id);
|
||||
|
||||
// get one of the root inserted docs
|
||||
const lastInsertedId = node?._id;
|
||||
return lastInsertedId;
|
||||
},
|
||||
});
|
||||
|
||||
function insertPropertyFromNode(nodeId, ancestors, order) {
|
||||
// Fetch the library node and its decendents, provided they have not been
|
||||
function insertPropertyFromNode(nodeId, root, parentId) {
|
||||
// Fetch the library node and its descendants, provided they have not been
|
||||
// removed
|
||||
// TODO: Check permission to read the library this node is in
|
||||
let node = LibraryNodes.findOne({
|
||||
_id: nodeId,
|
||||
removed: { $ne: true },
|
||||
});
|
||||
if (!node) {
|
||||
if (Meteor.isClient) return;
|
||||
if (Meteor.isClient) return {};
|
||||
else {
|
||||
throw new Meteor.Error(
|
||||
'Insert property from library failed',
|
||||
@@ -93,13 +82,12 @@ function insertPropertyFromNode(nodeId, ancestors, order) {
|
||||
);
|
||||
}
|
||||
}
|
||||
let oldParent = node.parent;
|
||||
|
||||
let nodes = LibraryNodes.find({
|
||||
'ancestors.id': nodeId,
|
||||
...getFilter.descendants(node),
|
||||
removed: { $ne: true },
|
||||
}).fetch();
|
||||
|
||||
|
||||
// The root node is first in the array of nodes
|
||||
// It must get the first generated ID to prevent flickering
|
||||
nodes = [node, ...nodes];
|
||||
@@ -112,31 +100,17 @@ function insertPropertyFromNode(nodeId, ancestors, order) {
|
||||
// set libraryNodeIds
|
||||
storeLibraryNodeReferences(nodes);
|
||||
|
||||
// re-map all the ancestors
|
||||
setLineageOfDocs({
|
||||
docArray: nodes,
|
||||
newAncestry: ancestors,
|
||||
oldParent,
|
||||
});
|
||||
|
||||
// Give the docs new IDs without breaking internal references
|
||||
renewDocIds({
|
||||
docArray: nodes,
|
||||
collectionMap: { 'libraryNodes': 'creatureProperties' }
|
||||
});
|
||||
|
||||
// Order the root node
|
||||
if (order === undefined) {
|
||||
setDocToLastOrder({
|
||||
collection: CreatureProperties,
|
||||
doc: node,
|
||||
});
|
||||
} else {
|
||||
node.order = order;
|
||||
}
|
||||
// Mark root node as dirty
|
||||
node.dirty = true;
|
||||
|
||||
// Mark all nodes as dirty
|
||||
dirtyNodes(nodes);
|
||||
// Move the root node to the end of the order
|
||||
node.left = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
// Insert the creature properties
|
||||
CreatureProperties.batchInsert(nodes);
|
||||
@@ -150,12 +124,6 @@ function storeLibraryNodeReferences(nodes) {
|
||||
});
|
||||
}
|
||||
|
||||
function dirtyNodes(nodes) {
|
||||
nodes.forEach(node => {
|
||||
node.dirty = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Covert node references into actual nodes
|
||||
// TODO: check permissions for each library a reference node references
|
||||
function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0) {
|
||||
@@ -178,7 +146,6 @@ function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0) {
|
||||
let referencedNode
|
||||
try {
|
||||
referencedNode = fetchDocByRef(node.ref);
|
||||
referencedNode.order = node.order;
|
||||
referencedNode.tags = union(node.tags, referencedNode.tags);
|
||||
// We are definitely replacing this node, so add it to the list
|
||||
visitedRefs.add(node._id);
|
||||
@@ -188,23 +155,15 @@ function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0) {
|
||||
}
|
||||
|
||||
// Get all the descendants of the referenced node
|
||||
let descendents = LibraryNodes.find({
|
||||
'ancestors.id': referencedNode._id,
|
||||
let descendants = LibraryNodes.find({
|
||||
...getFilter.descendants(referencedNode),
|
||||
removed: { $ne: true },
|
||||
}, {
|
||||
sort: { order: 1 },
|
||||
}).fetch();
|
||||
|
||||
// We are adding the referenced node and its descendants
|
||||
let addedNodes = [referencedNode, ...descendents];
|
||||
|
||||
// re-map all the ancestors to parent the new sub-tree into our existing
|
||||
// node tree
|
||||
setLineageOfDocs({
|
||||
docArray: addedNodes,
|
||||
newAncestry: node.ancestors,
|
||||
oldParent: referencedNode.parent,
|
||||
});
|
||||
let addedNodes = [referencedNode, ...descendants];
|
||||
|
||||
// Filter all the looped references
|
||||
addedNodes = addedNodes.filter(addedNode => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
|
||||
const pullFromProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.pull',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import { get } from 'lodash';
|
||||
|
||||
const pushToProperty = new ValidatedMethod({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { restore } from '/imports/api/parenting/softRemove.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import { restore } from '/imports/api/parenting/softRemove';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
|
||||
const restoreProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.restore',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
|
||||
const selectAmmoItem = new ValidatedMethod({
|
||||
name: 'creatureProperties.selectAmmoItem',
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { softRemove } from '/imports/api/parenting/softRemove.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import { softRemove } from '/imports/api/parenting/softRemove';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
|
||||
const softRemoveProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.softRemove',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor';
|
||||
|
||||
const updateCreatureProperty = new ValidatedMethod({
|
||||
name: 'creatureProperties.update',
|
||||
@@ -14,6 +14,8 @@ const updateCreatureProperty = new ValidatedMethod({
|
||||
case 'order':
|
||||
case 'parent':
|
||||
case 'ancestors':
|
||||
case 'root':
|
||||
case 'parentId':
|
||||
case 'damage':
|
||||
throw new Meteor.Error('Permission denied',
|
||||
'This property can\'t be updated directly');
|
||||
@@ -27,7 +29,7 @@ const updateCreatureProperty = new ValidatedMethod({
|
||||
run({ _id, path, value }) {
|
||||
// Permission
|
||||
let property = CreatureProperties.findOne(_id, {
|
||||
fields: { type: 1, ancestors: 1 }
|
||||
fields: { type: 1, root: 1 }
|
||||
});
|
||||
let rootCreature = getRootCreatureAncestor(property);
|
||||
assertEditPermission(rootCreature, this.userId);
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import computeCreature from '/imports/api/engine/computeCreature.js';
|
||||
import computeCreature from '/imports/api/engine/computeCreature';
|
||||
|
||||
/**
|
||||
* Recomputes all ancestor creatures of this property
|
||||
* @deprecated
|
||||
*/
|
||||
export default function recomputeCreaturesByProperty(property){
|
||||
for (let ref of property.ancestors){
|
||||
if (ref.collection === 'creatures') {
|
||||
computeCreature.call(ref.id);
|
||||
}
|
||||
}
|
||||
export default function recomputeCreaturesByProperty(property) {
|
||||
computeCreature.call(property.root.id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user