Library node editing now includes editing sub-documents and soft removal
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
</template>
|
||||
<component
|
||||
v-if="model"
|
||||
:is="model.type"
|
||||
class="library-node-form"
|
||||
stored
|
||||
:is="model.type"
|
||||
:model="model"
|
||||
@change="change"
|
||||
@push="push"
|
||||
@@ -32,18 +33,18 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LibraryNodes, { updateLibraryNode } from '/imports/api/library/LibraryNodes.js';
|
||||
import LibraryNodes, {
|
||||
updateLibraryNode,
|
||||
pushToLibraryNode,
|
||||
pullFromLibraryNode,
|
||||
softRemoveLibraryNode,
|
||||
} from '/imports/api/library/LibraryNodes.js';
|
||||
import librarySchemas from '/imports/api/library/librarySchemas.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
import PropertyIcon from '/imports/ui/components/properties/PropertyIcon.vue';
|
||||
import propertyFormIndex from '/imports/ui/properties/forms/shared/propertyFormIndex.js';
|
||||
|
||||
let todo = ({ack}) => {
|
||||
console.warn('not implemented');
|
||||
ack && ack();
|
||||
};
|
||||
let libraryNodePull = libraryNodePush = libraryNodeRemove = todo;
|
||||
import { get } from 'lodash';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -62,16 +63,28 @@
|
||||
methods: {
|
||||
getPropertyName,
|
||||
change({path, value, ack}){
|
||||
updateLibraryNode.call({_id: this._id, path, value, ack});
|
||||
updateLibraryNode.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
});
|
||||
},
|
||||
push({path, value, ack}){
|
||||
libraryNodePush({_id: this._id, path}, e => ack(e));
|
||||
pushToLibraryNode.call({_id: this._id, path, value}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
});
|
||||
},
|
||||
pull({path, ack}){
|
||||
libraryNodePull({_id: this._id, path}, e => ack(e));
|
||||
let itemId = get(this.model, path)._id;
|
||||
path.pop();
|
||||
pullFromLibraryNode.call({_id: this._id, path, itemId}, (error, result) =>{
|
||||
console.log({error, result});
|
||||
ack && ack(error);
|
||||
});
|
||||
},
|
||||
remove(){
|
||||
libraryNodeRemove({_id: this._id});
|
||||
softRemoveLibraryNode.call({_id: this._id});
|
||||
this.$store.dispatch('popDialogStack');
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,16 +55,7 @@ export default {
|
||||
model.type = newType;
|
||||
this.model = model;
|
||||
},
|
||||
model(newModel){
|
||||
console.log('model changed');
|
||||
console.log(newModel);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
insert(){
|
||||
console.log(this.model);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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){
|
||||
|
||||
Reference in New Issue
Block a user