Migrated insert prop methods to nested sets
This commit is contained in:
@@ -7,13 +7,11 @@ 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
|
||||
renewDocIds,
|
||||
fetchDocByRef,
|
||||
rebuildNestedSets,
|
||||
getFilter
|
||||
} from '/imports/api/parenting/parentingFunctions';
|
||||
import { rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
|
||||
import { setDocToLastOrder } from '/imports/api/parenting/order';
|
||||
import { fetchDocByRef } 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,34 +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
|
||||
rebuildNestedSets(CreatureProperties, rootCreature._id);
|
||||
// Return the docId of the last property, the inserted root property
|
||||
return rootId;
|
||||
|
||||
// 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',
|
||||
@@ -90,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];
|
||||
@@ -109,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);
|
||||
@@ -147,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) {
|
||||
@@ -175,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);
|
||||
@@ -185,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 => {
|
||||
|
||||
Reference in New Issue
Block a user