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 librarySchemas from '/imports/api/library/librarySchemas.js';
|
||||||
import Libraries from '/imports/api/library/Libraries.js';
|
import Libraries from '/imports/api/library/Libraries.js';
|
||||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.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');
|
let LibraryNodes = new Mongo.Collection('libraryNodes');
|
||||||
|
|
||||||
@@ -16,9 +17,10 @@ let LibraryNodeSchema = new SimpleSchema({
|
|||||||
|
|
||||||
for (let key in librarySchemas){
|
for (let key in librarySchemas){
|
||||||
let schema = new SimpleSchema({});
|
let schema = new SimpleSchema({});
|
||||||
schema.extend(librarySchemas[key]);
|
|
||||||
schema.extend(LibraryNodeSchema);
|
schema.extend(LibraryNodeSchema);
|
||||||
|
schema.extend(librarySchemas[key]);
|
||||||
schema.extend(ChildSchema);
|
schema.extend(ChildSchema);
|
||||||
|
schema.extend(SoftRemovableSchema);
|
||||||
LibraryNodes.attachSchema(schema, {
|
LibraryNodes.attachSchema(schema, {
|
||||||
selector: {type: key}
|
selector: {type: key}
|
||||||
});
|
});
|
||||||
@@ -46,9 +48,10 @@ const insertNode = new ValidatedMethod({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const updateLibraryNode = new ValidatedMethod({
|
const updateLibraryNode = new ValidatedMethod({
|
||||||
name: 'LibraryNodes.methods.set',
|
name: 'LibraryNodes.methods.update',
|
||||||
validate({_id, path, value, ack}){
|
validate({_id, path, value, ack}){
|
||||||
if (!_id) return false;
|
if (!_id) return false;
|
||||||
|
// We cannot change these with a simple update
|
||||||
switch (path[0]){
|
switch (path[0]){
|
||||||
case 'type':
|
case 'type':
|
||||||
case 'order':
|
case 'order':
|
||||||
@@ -57,23 +60,65 @@ const updateLibraryNode = new ValidatedMethod({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
run({_id, path, value, ack}) {
|
run({_id, path, value}) {
|
||||||
let node = LibraryNodes.findOne(_id);
|
let node = LibraryNodes.findOne(_id);
|
||||||
assertNodeEditPermission(node, this.userId);
|
assertNodeEditPermission(node, this.userId);
|
||||||
return LibraryNodes.update(_id, {
|
return LibraryNodes.update(_id, {
|
||||||
$set: {[path.join('.')]: value},
|
$set: {[path.join('.')]: value},
|
||||||
}, {
|
}, {
|
||||||
selector: {type: node.type},
|
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){
|
function libraryNodesToTree(ancestorId){
|
||||||
// Store a dict of all the nodes
|
// Store a dict of all the nodes
|
||||||
let nodeIndex = {};
|
let nodeIndex = {};
|
||||||
let nodeList = [];
|
let nodeList = [];
|
||||||
LibraryNodes.find({
|
LibraryNodes.find({
|
||||||
'ancestors.id': ancestorId
|
'ancestors.id': ancestorId,
|
||||||
|
removed: {$ne: true},
|
||||||
}, {
|
}, {
|
||||||
sort: {order: 1}
|
sort: {order: 1}
|
||||||
}).forEach( node => {
|
}).forEach( node => {
|
||||||
@@ -98,4 +143,12 @@ function libraryNodesToTree(ancestorId){
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default LibraryNodes;
|
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={}}){
|
export function updateDescendants({collection, ancestorId, filter = {}, modifier, options={}}){
|
||||||
filter["ancestors.id"] = ancestorId;
|
filter["ancestors.id"] = ancestorId;
|
||||||
options.multi = true;
|
options.multi = true;
|
||||||
|
options.selector = {type: 'any'};
|
||||||
collection.update(filter, modifier, options);
|
collection.update(filter, modifier, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,29 @@
|
|||||||
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
|
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}){
|
export function softRemove({_id, collection}){
|
||||||
let removalDate = new Date();
|
let removalDate = new Date();
|
||||||
|
if (typeof collection === 'string') {
|
||||||
|
collection = getCollectionByName(collection);
|
||||||
|
}
|
||||||
// Remove this document
|
// Remove this document
|
||||||
collection = getCollectionByName(collection);
|
collection.update(
|
||||||
collection.update(_id, {$set: {
|
_id, {
|
||||||
removed: true,
|
$set: {
|
||||||
removedAt: removalDate,
|
removed: true,
|
||||||
}, $unset: {
|
removedAt: removalDate,
|
||||||
removedWith: 1,
|
},
|
||||||
}});
|
$unset: {
|
||||||
|
removedWith: 1,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
selector: {type: 'any'},
|
||||||
|
},
|
||||||
|
);
|
||||||
// Remove all the descendants that have not yet been removed, and set them to be
|
// Remove all the descendants that have not yet been removed, and set them to be
|
||||||
// removed with this document
|
// removed with this document
|
||||||
updateDescendants({
|
updateDescendants({
|
||||||
|
collection,
|
||||||
ancestorId: _id,
|
ancestorId: _id,
|
||||||
filter: {removed: {$ne: true}},
|
filter: {removed: {$ne: true}},
|
||||||
modifier: {$set: {
|
modifier: {$set: {
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ let BuffSchema = new SimpleSchema({
|
|||||||
_id: {
|
_id: {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
autoValue(){
|
|
||||||
if (!this.isSet) return Random.id();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@@ -12,8 +12,9 @@
|
|||||||
</template>
|
</template>
|
||||||
<component
|
<component
|
||||||
v-if="model"
|
v-if="model"
|
||||||
:is="model.type"
|
|
||||||
class="library-node-form"
|
class="library-node-form"
|
||||||
|
stored
|
||||||
|
:is="model.type"
|
||||||
:model="model"
|
:model="model"
|
||||||
@change="change"
|
@change="change"
|
||||||
@push="push"
|
@push="push"
|
||||||
@@ -32,18 +33,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<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 librarySchemas from '/imports/api/library/librarySchemas.js';
|
||||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||||
import PropertyIcon from '/imports/ui/components/properties/PropertyIcon.vue';
|
import PropertyIcon from '/imports/ui/components/properties/PropertyIcon.vue';
|
||||||
import propertyFormIndex from '/imports/ui/properties/forms/shared/propertyFormIndex.js';
|
import propertyFormIndex from '/imports/ui/properties/forms/shared/propertyFormIndex.js';
|
||||||
|
import { get } from 'lodash';
|
||||||
let todo = ({ack}) => {
|
|
||||||
console.warn('not implemented');
|
|
||||||
ack && ack();
|
|
||||||
};
|
|
||||||
let libraryNodePull = libraryNodePush = libraryNodeRemove = todo;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -62,16 +63,28 @@
|
|||||||
methods: {
|
methods: {
|
||||||
getPropertyName,
|
getPropertyName,
|
||||||
change({path, value, ack}){
|
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}){
|
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}){
|
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(){
|
remove(){
|
||||||
libraryNodeRemove({_id: this._id});
|
softRemoveLibraryNode.call({_id: this._id});
|
||||||
|
this.$store.dispatch('popDialogStack');
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,16 +55,7 @@ export default {
|
|||||||
model.type = newType;
|
model.type = newType;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
},
|
},
|
||||||
model(newModel){
|
|
||||||
console.log('model changed');
|
|
||||||
console.log(newModel);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
insert(){
|
|
||||||
console.log(this.model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,10 @@
|
|||||||
return Libraries.findOne(this.$route.params.id);
|
return Libraries.findOne(this.$route.params.id);
|
||||||
},
|
},
|
||||||
selectedNode(){
|
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
|
* inputs, and sends update events when valid data model changes must occur
|
||||||
*/
|
*/
|
||||||
import { get, toPath } from 'lodash';
|
import { get, toPath } from 'lodash';
|
||||||
|
|
||||||
function resolvePath(model, path){
|
function resolvePath(model, path){
|
||||||
let arrayPath = toPath(path);
|
let arrayPath = toPath(path);
|
||||||
if (arrayPath.length === 1){
|
if (arrayPath.length === 1){
|
||||||
|
|||||||
Reference in New Issue
Block a user