Added inserting library subtrees as character property subtrees
This commit is contained in:
@@ -1,8 +1,15 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema, { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||||
import Creature from '/imports/api/creature/Creatures.js';
|
import Creature from '/imports/api/creature/Creatures.js';
|
||||||
|
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||||
import propertySchemasIndex from '/imports/api/properties/propertySchemasIndex.js';
|
import propertySchemasIndex from '/imports/api/properties/propertySchemasIndex.js';
|
||||||
|
import {
|
||||||
|
setLineageOfDocs,
|
||||||
|
getAncestry,
|
||||||
|
renewDocIds
|
||||||
|
} from '/imports/api/parenting/parenting.js';
|
||||||
|
import {setDocToLastOrder} from '/imports/api/parenting/order.js';
|
||||||
|
|
||||||
let CreatureProperties = new Mongo.Collection('creatureProperties');
|
let CreatureProperties = new Mongo.Collection('creatureProperties');
|
||||||
|
|
||||||
@@ -11,12 +18,6 @@ let CreaturePropertySchema = new SimpleSchema({
|
|||||||
type: String,
|
type: String,
|
||||||
allowedValues: Object.keys(propertySchemasIndex),
|
allowedValues: Object.keys(propertySchemasIndex),
|
||||||
},
|
},
|
||||||
charId: {
|
|
||||||
type: String,
|
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
|
||||||
index: 1,
|
|
||||||
optional: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let key in propertySchemasIndex){
|
for (let key in propertySchemasIndex){
|
||||||
@@ -44,12 +45,85 @@ function assertPropertyEditPermission(property, userId){
|
|||||||
const insertProperty = new ValidatedMethod({
|
const insertProperty = new ValidatedMethod({
|
||||||
name: 'CreatureProperties.methods.insert',
|
name: 'CreatureProperties.methods.insert',
|
||||||
validate: null,
|
validate: null,
|
||||||
run(creatureProperty) {
|
run({creatureProperty, parentRef}) {
|
||||||
assertPropertyEditPermission(creatureProperty, this.userId);
|
// TODO insert a property with the correct ancestry and order
|
||||||
return CreatureProperties.insert(creatureProperty);
|
//assertPropertyEditPermission(creatureProperty, this.userId);
|
||||||
|
//return CreatureProperties.insert(creatureProperty);
|
||||||
|
// TODO trigger a recalculation of the creature
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const insertPropertyFromLibraryNode = new ValidatedMethod({
|
||||||
|
name: 'CreatureProperties.methods.insertPropertyFromLibraryNode',
|
||||||
|
validate: new SimpleSchema({
|
||||||
|
nodeId: {
|
||||||
|
type: String,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
},
|
||||||
|
parentRef: {
|
||||||
|
type: RefSchema,
|
||||||
|
},
|
||||||
|
}).validator(),
|
||||||
|
run({nodeId, parentRef}) {
|
||||||
|
// get the new ancestry for the properties
|
||||||
|
let {parentDoc, ancestors} = getAncestry({parentRef});
|
||||||
|
|
||||||
|
// Check permission to edit
|
||||||
|
if (parentRef.collection === 'creatures'){
|
||||||
|
assertEditPermission(parentDoc, this.userId);
|
||||||
|
} else if (parentRef.collection === 'creatureProperties'){
|
||||||
|
assertPropertyEditPermission(parentDoc, this.userId);
|
||||||
|
} else {
|
||||||
|
throw `${parentRef.collection} is not a valid parent collection`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the library node and its decendents, provided they have not been
|
||||||
|
// removed
|
||||||
|
let node = LibraryNodes.findOne({
|
||||||
|
_id: nodeId,
|
||||||
|
removed: {$ne: true},
|
||||||
|
});
|
||||||
|
if (!node) throw `Node not found for nodeId: ${nodeId}`;
|
||||||
|
let oldParent = node.parent;
|
||||||
|
let nodes = LibraryNodes.find({
|
||||||
|
'ancestors.id': nodeId,
|
||||||
|
removed: {$ne: true},
|
||||||
|
}).fetch();
|
||||||
|
// The root node is last in the array of nodes
|
||||||
|
nodes.push(node);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
setDocToLastOrder({
|
||||||
|
collection: CreatureProperties,
|
||||||
|
doc: node,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert the creature properties
|
||||||
|
let docId;
|
||||||
|
nodes.forEach(doc => {
|
||||||
|
docId = CreatureProperties.insert(doc);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO trigger a recalculation of the creature
|
||||||
|
|
||||||
|
// Return the docId of the last property, the inserted root property
|
||||||
|
return docId;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const adjustAttribute = new ValidatedMethod({
|
const adjustAttribute = new ValidatedMethod({
|
||||||
name: 'Attributes.methods.adjust',
|
name: 'Attributes.methods.adjust',
|
||||||
@@ -97,4 +171,4 @@ const adjustAttribute = new ValidatedMethod({
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export default CreatureProperties;
|
export default CreatureProperties;
|
||||||
export { CreaturePropertySchema, insertProperty };
|
export { CreaturePropertySchema, insertProperty, insertPropertyFromLibraryNode };
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export function compareOrder(docA, docB){
|
|||||||
|
|
||||||
// Go through their ancestors after the root, and find the first order
|
// Go through their ancestors after the root, and find the first order
|
||||||
// difference
|
// difference
|
||||||
|
// TODO ancestors don't store order yet
|
||||||
let i, difference;
|
let i, difference;
|
||||||
const length = Math.min(docA.ancestors.length, docB.ancestors.length);
|
const length = Math.min(docA.ancestors.length, docB.ancestors.length);
|
||||||
for (i = 1; i < length; i++){
|
for (i = 1; i < length; i++){
|
||||||
|
|||||||
@@ -94,6 +94,46 @@ export function getAncestry({parentRef, inheritedFields = {}}){
|
|||||||
return {parentDoc, parent, ancestors};
|
return {parentDoc, parent, ancestors};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setLineageOfDocs({docArray, oldParent, newAncestry}){
|
||||||
|
//const oldParent = oldAncestry[oldAncestry.length - 1];
|
||||||
|
const newParent = newAncestry[newAncestry.length - 1];
|
||||||
|
docArray.forEach(doc => {
|
||||||
|
if(doc.parent.id === oldParent.id){
|
||||||
|
doc.parent = newParent;
|
||||||
|
}
|
||||||
|
let oldAncestors = doc.ancestors;
|
||||||
|
let oldParentIndex = oldAncestors.findIndex(a => a.id === oldParent.id);
|
||||||
|
doc.ancestors = [...newAncestry, ...oldAncestors.slice(oldParentIndex + 1)];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give documents new random ids and transform their references.
|
||||||
|
* Transform collections of re-IDed docs according to the collection map
|
||||||
|
*/
|
||||||
|
export function renewDocIds({docArray, collectionMap}){
|
||||||
|
// map of {oldId: newId}
|
||||||
|
let idMap = {};
|
||||||
|
// Give new ids and map the changes
|
||||||
|
docArray.forEach(doc => {
|
||||||
|
let oldId = doc._id;
|
||||||
|
let newId = Random.id();
|
||||||
|
doc._id = newId;
|
||||||
|
idMap[oldId] = newId;
|
||||||
|
});
|
||||||
|
const remapReference = ref => {
|
||||||
|
if (idMap[ref.id]){
|
||||||
|
ref.id = idMap[ref.id];
|
||||||
|
ref.collection = collectionMap[ref.collection] || ref.collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
docArray.forEach(doc => {
|
||||||
|
remapReference(doc.parent);
|
||||||
|
doc.ancestors.forEach(remapReference);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function updateParent({docRef, parentRef}){
|
export function updateParent({docRef, parentRef}){
|
||||||
let collection = getCollectionByName(docRef.collection);
|
let collection = getCollectionByName(docRef.collection);
|
||||||
let oldDoc = fetchDocByRef(docRef, {fields: {
|
let oldDoc = fetchDocByRef(docRef, {fields: {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
small icon
|
small icon
|
||||||
:class="showExpanded ? 'rotate-90' : null"
|
:class="showExpanded ? 'rotate-90' : null"
|
||||||
@click.stop="expanded = !expanded"
|
@click.stop="expanded = !expanded"
|
||||||
:disabled="!hasChildren && !organize"
|
:disabled="!hasChildren && !organize || !canExpand"
|
||||||
>
|
>
|
||||||
<v-icon v-if="canExpand && (hasChildren || organize)">chevron_right</v-icon>
|
<v-icon v-if="canExpand && (hasChildren || organize)">chevron_right</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|||||||
@@ -80,7 +80,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CreatureTreeContainer from '/imports/ui/creature/CreatureTreeContainer.vue';
|
import CreatureTreeContainer from '/imports/ui/creature/CreatureTreeContainer.vue';
|
||||||
import CreatureProperties, { insertProperty } from '/imports/api/creature/CreatureProperties.js';
|
import CreatureProperties, {
|
||||||
|
insertProperty,
|
||||||
|
insertPropertyFromLibraryNode
|
||||||
|
} from '/imports/api/creature/CreatureProperties.js';
|
||||||
import PropertyViewer from '/imports/ui/properties/PropertyViewer.vue';
|
import PropertyViewer from '/imports/ui/properties/PropertyViewer.vue';
|
||||||
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
|
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
|
||||||
import PropertyIcon from '/imports/ui/properties/PropertyIcon.vue';
|
import PropertyIcon from '/imports/ui/properties/PropertyIcon.vue';
|
||||||
@@ -123,8 +126,13 @@
|
|||||||
this.$store.commit('pushDialogStack', {
|
this.$store.commit('pushDialogStack', {
|
||||||
component: 'creature-property-from-library-dialog',
|
component: 'creature-property-from-library-dialog',
|
||||||
elementId: 'insert-creature-property-fab',
|
elementId: 'insert-creature-property-fab',
|
||||||
callback(creatureProperty){
|
callback(libraryNode){
|
||||||
console.log(creatureProperty);
|
console.log({libraryNode});
|
||||||
|
let propertyId = insertPropertyFromLibraryNode.call({
|
||||||
|
nodeId: libraryNode._id,
|
||||||
|
parentRef: {collection: 'creatures', id: that.creatureId},
|
||||||
|
});
|
||||||
|
console.log({propertyId});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,19 +29,19 @@ RouterFactory.configure(factory => {
|
|||||||
component: Home,
|
component: Home,
|
||||||
},{
|
},{
|
||||||
path: '/characterList',
|
path: '/characterList',
|
||||||
//component: CharacterList,
|
component: CharacterList,
|
||||||
component: NotImplemented,
|
//component: NotImplemented,
|
||||||
},{
|
},{
|
||||||
path: '/library',
|
path: '/library',
|
||||||
component: Library,
|
component: Library,
|
||||||
},{
|
},{
|
||||||
path: '/character/:id/:urlName',
|
path: '/character/:id/:urlName',
|
||||||
//component: CharacterSheetPage,
|
component: CharacterSheetPage,
|
||||||
component: NotImplemented,
|
//component: NotImplemented,
|
||||||
},{
|
},{
|
||||||
path: '/character/:id',
|
path: '/character/:id',
|
||||||
//component: CharacterSheetPage,
|
component: CharacterSheetPage,
|
||||||
component: NotImplemented,
|
//component: NotImplemented,
|
||||||
|
|
||||||
},{
|
},{
|
||||||
path: '/sign-in',
|
path: '/sign-in',
|
||||||
|
|||||||
Reference in New Issue
Block a user