Moved the tree fab to the toolbar with smart parenting

This commit is contained in:
Stefan Zermatten
2021-04-11 12:36:14 +02:00
parent 81460f8835
commit 885607f685
4 changed files with 108 additions and 134 deletions

View File

@@ -27,13 +27,17 @@ const insertPropertyFromLibraryNode = new ValidatedMethod({
parentRef: { parentRef: {
type: RefSchema, type: RefSchema,
}, },
order: {
type: Number,
optional: true,
},
}).validator(), }).validator(),
mixins: [RateLimiterMixin], mixins: [RateLimiterMixin],
rateLimit: { rateLimit: {
numRequests: 5, numRequests: 5,
timeInterval: 5000, timeInterval: 5000,
}, },
run({nodeId, parentRef}) { run({nodeId, parentRef, order}) {
// get the new ancestry for the properties // get the new ancestry for the properties
let {parentDoc, ancestors} = getAncestry({parentRef}); let {parentDoc, ancestors} = getAncestry({parentRef});
@@ -79,10 +83,14 @@ const insertPropertyFromLibraryNode = new ValidatedMethod({
}); });
// Order the root node // Order the root node
setDocToLastOrder({ if (order === undefined){
collection: CreatureProperties, setDocToLastOrder({
doc: node, collection: CreatureProperties,
}); doc: node,
});
} else {
node.order = order;
}
// Insert the creature properties // Insert the creature properties
CreatureProperties.batchInsert(nodes); CreatureProperties.batchInsert(nodes);

View File

@@ -36,16 +36,26 @@
:disabled="!editPermission" :disabled="!editPermission"
@click="insertPropertyOfType(type)" @click="insertPropertyOfType(type)"
/> />
<labeled-fab <template v-if="tabNumber === 5">
v-if="tabNumber === 5" <labeled-fab
key="property" key="property"
color="primary" color="primary"
data-id="insert-creature-property-btn" data-id="insert-creature-property-btn"
label="New Property" label="New Property"
icon="add" icon="create"
:disabled="!editPermission" :disabled="!editPermission"
@click="insertTreeProperty" @click="insertTreeProperty"
/> />
<labeled-fab
key="property"
color="primary"
data-id="insert-creature-property-from-library-btn"
label="Property From Library"
icon="book"
:disabled="!editPermission"
@click="propertyFromLibrary"
/>
</template>
</v-speed-dial> </v-speed-dial>
</template> </template>
@@ -55,6 +65,54 @@
import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js'; import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import PROPERTIES from '/imports/constants/PROPERTIES.js'; import PROPERTIES from '/imports/constants/PROPERTIES.js';
import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
function getParentAndOrderFromSelectedTreeNode(creatureId){
// find the parent based on the currently selected property
let el = document.querySelector('.tree-tab .tree-node-title.primary--text');
let selectedComponent = el && el.parentElement.__vue__.$parent;
let parentRef, order;
if (selectedComponent){
if (selectedComponent.showExpanded){
parentRef = {
id: selectedComponent.node._id,
collection: 'creatureProperties',
};
order = getHighestOrder({
collection: CreatureProperties,
ancestorId: parentRef.id,
}) + 0.5;
} else {
parentRef = selectedComponent.node.parent;
order = selectedComponent.node.order + 0.5;
}
} else {
parentRef = {collection: 'creatures', id: creatureId};
order = getHighestOrder({
collection: CreatureProperties,
ancestorId: parentRef.id,
}) + 0.5;
}
return {parentRef, order}
}
function hideFab(){
let fab = document.querySelector('.insert-creature-property-fab');
if (fab) fab.style.opacity = '0';
return fab;
}
function revealFab(fab){
if (!fab) return;
// Bring back the fab with scale up animation
fab.style.transition = 'none';
fab.style.opacity = '';
fab.style.transform = 'scale(0)';
setTimeout(()=> {
fab.style.transform = '';
fab.style.transition = '';
}, 400);
}
const tabs = [ const tabs = [
'stats', 'stats',
@@ -100,9 +158,7 @@
methods: { methods: {
insertPropertyOfType(type){ insertPropertyOfType(type){
let creatureId = this.creatureId; let creatureId = this.creatureId;
// hide the whole fab let fab = hideFab();
let fab = document.querySelector('.insert-creature-property-fab');
if (fab) fab.style.opacity = '0'
// Open the dialog to insert the property // Open the dialog to insert the property
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
@@ -113,17 +169,7 @@
}, },
callback(creatureProperty){ callback(creatureProperty){
if (!creatureProperty) return 'insert-creature-property-fab'; if (!creatureProperty) return 'insert-creature-property-fab';
revealFab(fab);
// Bring back the fab with scale up animation
if (fab){
fab.style.transition = 'none';
fab.style.opacity = '';
fab.style.transform = 'scale(0)';
setTimeout(()=> {
fab.style.transform = '';
fab.style.transition = '';
}, 400);
}
// Insert the property // Insert the property
creatureProperty.order = getHighestOrder({ creatureProperty.order = getHighestOrder({
@@ -140,53 +186,18 @@
}, },
insertTreeProperty(){ insertTreeProperty(){
let creatureId = this.creatureId; let creatureId = this.creatureId;
// hide the whole fab let fab = hideFab();
let fab = document.querySelector('.insert-creature-property-fab');
if (fab) fab.style.opacity = '0'
// Open the dialog to insert the property // Open the dialog to insert the property
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'creature-property-creation-dialog', component: 'creature-property-creation-dialog',
elementId: 'insert-creature-property-btn', elementId: 'insert-creature-property-btn',
callback(creatureProperty){ callback(creatureProperty){
if (!creatureProperty) return 'insert-creature-property-fab'; if (!creatureProperty) return 'insert-creature-property-fab';
revealFab(fab);
// Bring back the fab with scale up animation // Get order and parent
if (fab){ let {parentRef, order } = getParentAndOrderFromSelectedTreeNode(creatureId);
fab.style.transition = 'none'; creatureProperty.order = order;
fab.style.opacity = '';
fab.style.transform = 'scale(0)';
setTimeout(()=> {
fab.style.transform = '';
fab.style.transition = '';
}, 400);
}
// find the parent based on the currently selected property
let el = document.querySelector('.tree-node-title.primary--text');
let selectedComponent = el && el.parentElement.__vue__.$parent;
let parentRef;
if (selectedComponent){
if (selectedComponent.showExpanded){
parentRef = {
id: selectedComponent.node._id,
collection: 'creatureProperties',
};
creatureProperty.order = getHighestOrder({
collection: CreatureProperties,
ancestorId: parentRef.id,
}) + 0.5;
} else {
parentRef = selectedComponent.node.parent;
creatureProperty.order = selectedComponent.node.order + 0.5;
}
} else {
parentRef = {collection: 'creatures', id: creatureId};
creatureProperty.order = getHighestOrder({
collection: CreatureProperties,
ancestorId: parentRef.id,
}) + 0.5;
}
// Insert the property // Insert the property
let id = insertProperty.call({creatureProperty, parentRef}); let id = insertProperty.call({creatureProperty, parentRef});
@@ -194,6 +205,25 @@
} }
}); });
}, },
propertyFromLibrary(){
let creatureId = this.creatureId;
let fab = hideFab();
this.$store.commit('pushDialogStack', {
component: 'creature-property-from-library-dialog',
elementId: 'insert-creature-property-from-library-btn',
callback(libraryNode){
if (!libraryNode) return;
revealFab(fab);
let nodeId = libraryNode._id;
let {parentRef, order } = getParentAndOrderFromSelectedTreeNode(creatureId);
let id = insertPropertyFromLibraryNode.call({nodeId, parentRef, order});
return `tree-node-${id}`;
}
});
},
} }
} }
</script> </script>

View File

@@ -248,5 +248,6 @@ export default {
.character-sheet-fab { .character-sheet-fab {
bottom: -24px; bottom: -24px;
right: 8px; right: 8px;
margin-left: 16px;
} }
</style> </style>

View File

@@ -57,36 +57,6 @@
</template> </template>
</tree-detail-layout> </tree-detail-layout>
</v-card> </v-card>
<v-speed-dial
v-model="fab"
fixed
bottom="bottom"
right="right"
>
<template #activator>
<v-btn
v-model="fab"
color="primary"
fab
data-id="insert-creature-property-fab"
>
<v-icon>add</v-icon>
<v-icon>close</v-icon>
</v-btn>
</template>
<labeled-fab
color="primary"
label="Property from library"
icon="book"
@click="propertyFromLibrary"
/>
<labeled-fab
color="primary"
label="New property"
icon="edit"
@click="insertCreatureProperty"
/>
</v-speed-dial>
</div> </div>
</template> </template>
@@ -94,12 +64,8 @@
import TreeDetailLayout from '/imports/ui/components/TreeDetailLayout.vue'; import TreeDetailLayout from '/imports/ui/components/TreeDetailLayout.vue';
import CreaturePropertiesTree from '/imports/ui/creature/creatureProperties/CreaturePropertiesTree.vue'; import CreaturePropertiesTree from '/imports/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
import CreaturePropertyDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue'; import CreaturePropertyDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue';
import LabeledFab from '/imports/ui/components/LabeledFab.vue';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js';
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
import { getPropertyName } from '/imports/constants/PROPERTIES.js'; import { getPropertyName } from '/imports/constants/PROPERTIES.js';
export default { export default {
@@ -107,7 +73,6 @@
TreeDetailLayout, TreeDetailLayout,
CreaturePropertiesTree, CreaturePropertiesTree,
CreaturePropertyDialog, CreaturePropertyDialog,
LabeledFab,
}, },
inject: { inject: {
context: { default: {} } context: { default: {} }
@@ -196,36 +161,6 @@
}); });
} }
}, },
insertCreatureProperty(){
let that = this;
this.$store.commit('pushDialogStack', {
component: 'creature-property-creation-dialog',
elementId: 'insert-creature-property-fab',
callback(creatureProperty){
if (!creatureProperty) return;
creatureProperty.parent = {collection: 'creatures', id: that.creatureId};
creatureProperty.ancestors = [ {collection: 'creatures', id: that.creatureId}];
setDocToLastOrder({collection: CreatureProperties, doc: creatureProperty});
let id = insertProperty.call({creatureProperty});
return `tree-node-${id}`;
}
});
},
propertyFromLibrary(){
let that = this;
this.$store.commit('pushDialogStack', {
component: 'creature-property-from-library-dialog',
elementId: 'insert-creature-property-fab',
callback(libraryNode){
if (!libraryNode) return;
let id = insertPropertyFromLibraryNode.call({
nodeId: libraryNode._id,
parentRef: {collection: 'creatures', id: that.creatureId},
});
return `tree-node-${id}`;
}
});
},
editCreatureProperty(){ editCreatureProperty(){
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'creature-property-dialog', component: 'creature-property-dialog',