From 0b184c4e858c67f5d6fb63b6b188bd504996a84d Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Fri, 2 Aug 2019 12:35:59 +0200 Subject: [PATCH] Library node editing now includes editing sub-documents and soft removal --- app/imports/api/library/LibraryNodes.js | 67 +++++++++++++++++-- app/imports/api/parenting/parenting.js | 1 + app/imports/api/parenting/softRemove.js | 27 +++++--- app/imports/api/properties/Buffs.js | 3 - .../ui/library/LibraryNodeEditDialog.vue | 37 ++++++---- .../ui/library/LibraryNodeInsertForm.vue | 9 --- app/imports/ui/pages/Library.vue | 5 +- .../forms/shared/schemaFormMixin.js | 1 + 8 files changed, 109 insertions(+), 41 deletions(-) diff --git a/app/imports/api/library/LibraryNodes.js b/app/imports/api/library/LibraryNodes.js index cde82a88..e9baef40 100644 --- a/app/imports/api/library/LibraryNodes.js +++ b/app/imports/api/library/LibraryNodes.js @@ -3,7 +3,8 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js'; import librarySchemas from '/imports/api/library/librarySchemas.js'; import Libraries from '/imports/api/library/Libraries.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; -import getModifierFields from '/imports/api/getModifierFields.js'; +import { softRemove } from '/imports/api/parenting/softRemove.js'; +import SoftRemovableSchema from '/imports/api/parenting/SoftRemovableSchema.js'; let LibraryNodes = new Mongo.Collection('libraryNodes'); @@ -16,9 +17,10 @@ let LibraryNodeSchema = new SimpleSchema({ for (let key in librarySchemas){ let schema = new SimpleSchema({}); - schema.extend(librarySchemas[key]); schema.extend(LibraryNodeSchema); + schema.extend(librarySchemas[key]); schema.extend(ChildSchema); + schema.extend(SoftRemovableSchema); LibraryNodes.attachSchema(schema, { selector: {type: key} }); @@ -46,9 +48,10 @@ const insertNode = new ValidatedMethod({ }); const updateLibraryNode = new ValidatedMethod({ - name: 'LibraryNodes.methods.set', + name: 'LibraryNodes.methods.update', validate({_id, path, value, ack}){ if (!_id) return false; + // We cannot change these with a simple update switch (path[0]){ case 'type': case 'order': @@ -57,23 +60,65 @@ const updateLibraryNode = new ValidatedMethod({ return false; } }, - run({_id, path, value, ack}) { + run({_id, path, value}) { let node = LibraryNodes.findOne(_id); assertNodeEditPermission(node, this.userId); return LibraryNodes.update(_id, { $set: {[path.join('.')]: value}, }, { selector: {type: node.type}, - }, error => ack && ack(error)); + }); }, }); +const pushToLibraryNode = new ValidatedMethod({ + name: 'LibraryNodes.methods.push', + validate: null, + run({_id, path, value}){ + let node = LibraryNodes.findOne(_id); + assertNodeEditPermission(node, this.userId); + return LibraryNodes.update(_id, { + $push: {[path.join('.')]: value}, + }, { + selector: {type: node.type}, + }); + } +}); + +const pullFromLibraryNode = new ValidatedMethod({ + name: 'LibraryNodes.methods.pull', + validate: null, + run({_id, path, itemId}){ + let node = LibraryNodes.findOne(_id); + assertNodeEditPermission(node, this.userId); + return LibraryNodes.update(_id, { + $pull: {[path.join('.')]: {_id: itemId}}, + }, { + selector: {type: node.type}, + getAutoValues: false, + }); + } +}); + +const softRemoveLibraryNode = new ValidatedMethod({ + name: 'LibraryNodes.methods.softRemove', + validate: new SimpleSchema({ + _id: SimpleSchema.RegEx.Id + }).validator(), + run({_id}){ + let node = LibraryNodes.findOne(_id); + assertNodeEditPermission(node, this.userId); + softRemove({_id, collection: LibraryNodes}); + } +}); + function libraryNodesToTree(ancestorId){ // Store a dict of all the nodes let nodeIndex = {}; let nodeList = []; LibraryNodes.find({ - 'ancestors.id': ancestorId + 'ancestors.id': ancestorId, + removed: {$ne: true}, }, { sort: {order: 1} }).forEach( node => { @@ -98,4 +143,12 @@ function libraryNodesToTree(ancestorId){ } export default LibraryNodes; -export { LibraryNodeSchema, insertNode, updateLibraryNode, libraryNodesToTree }; +export { + LibraryNodeSchema, + insertNode, + updateLibraryNode, + pullFromLibraryNode, + pushToLibraryNode, + softRemoveLibraryNode, + libraryNodesToTree, +}; diff --git a/app/imports/api/parenting/parenting.js b/app/imports/api/parenting/parenting.js index 58b9784e..8e977b73 100644 --- a/app/imports/api/parenting/parenting.js +++ b/app/imports/api/parenting/parenting.js @@ -32,6 +32,7 @@ export function fetchDescendants({ collection, ancestorId, filter = {}, options} export function updateDescendants({collection, ancestorId, filter = {}, modifier, options={}}){ filter["ancestors.id"] = ancestorId; options.multi = true; + options.selector = {type: 'any'}; collection.update(filter, modifier, options); } diff --git a/app/imports/api/parenting/softRemove.js b/app/imports/api/parenting/softRemove.js index e6642317..1b53d348 100644 --- a/app/imports/api/parenting/softRemove.js +++ b/app/imports/api/parenting/softRemove.js @@ -1,20 +1,29 @@ import getCollectionByName from '/imports/api/parenting/getCollectionByName.js'; -import updateDescendants from '/imports/api/parenting/parenting.js'; +import { updateDescendants } from '/imports/api/parenting/parenting.js'; -// 1 + n database hits export function softRemove({_id, collection}){ let removalDate = new Date(); + if (typeof collection === 'string') { + collection = getCollectionByName(collection); + } // Remove this document - collection = getCollectionByName(collection); - collection.update(_id, {$set: { - removed: true, - removedAt: removalDate, - }, $unset: { - removedWith: 1, - }}); + collection.update( + _id, { + $set: { + removed: true, + removedAt: removalDate, + }, + $unset: { + removedWith: 1, + } + }, { + selector: {type: 'any'}, + }, + ); // Remove all the descendants that have not yet been removed, and set them to be // removed with this document updateDescendants({ + collection, ancestorId: _id, filter: {removed: {$ne: true}}, modifier: {$set: { diff --git a/app/imports/api/properties/Buffs.js b/app/imports/api/properties/Buffs.js index acfdb48b..d0557e13 100644 --- a/app/imports/api/properties/Buffs.js +++ b/app/imports/api/properties/Buffs.js @@ -5,9 +5,6 @@ let BuffSchema = new SimpleSchema({ _id: { type: String, regEx: SimpleSchema.RegEx.Id, - autoValue(){ - if (!this.isSet) return Random.id(); - } }, name: { type: String, diff --git a/app/imports/ui/library/LibraryNodeEditDialog.vue b/app/imports/ui/library/LibraryNodeEditDialog.vue index 7fd7968e..6d09f124 100644 --- a/app/imports/ui/library/LibraryNodeEditDialog.vue +++ b/app/imports/ui/library/LibraryNodeEditDialog.vue @@ -12,8 +12,9 @@ diff --git a/app/imports/ui/pages/Library.vue b/app/imports/ui/pages/Library.vue index 576dbfd3..40c6ded9 100644 --- a/app/imports/ui/pages/Library.vue +++ b/app/imports/ui/pages/Library.vue @@ -109,7 +109,10 @@ return Libraries.findOne(this.$route.params.id); }, selectedNode(){ - return LibraryNodes.findOne(this.selected); + return LibraryNodes.findOne({ + _id: this.selected, + removed: {$ne: true} + }); } } }; diff --git a/app/imports/ui/properties/forms/shared/schemaFormMixin.js b/app/imports/ui/properties/forms/shared/schemaFormMixin.js index 25579a02..6af06fd6 100644 --- a/app/imports/ui/properties/forms/shared/schemaFormMixin.js +++ b/app/imports/ui/properties/forms/shared/schemaFormMixin.js @@ -3,6 +3,7 @@ * inputs, and sends update events when valid data model changes must occur */ import { get, toPath } from 'lodash'; + function resolvePath(model, path){ let arrayPath = toPath(path); if (arrayPath.length === 1){