Added floating action button to add properties directly to the sheet

This commit is contained in:
Stefan Zermatten
2021-02-25 12:37:32 +02:00
parent df361236f5
commit a5460bba0b
6 changed files with 165 additions and 20 deletions

View File

@@ -3,6 +3,8 @@
fab
small
v-bind="$attrs"
:disabled="disabled"
:style="disabled ? 'background-color: #616161 !important;' : ''"
@click="$emit('click')"
>
<v-icon>{{ icon }}</v-icon>
@@ -18,7 +20,7 @@
* component creates a v-btn with a label.
*/
export default {
props: ['icon', 'label'],
props: ['icon', 'label', 'disabled'],
}
</script>

View File

@@ -0,0 +1,104 @@
<template lang="html">
<v-speed-dial
v-if="speedDials && speedDials.length"
v-model="fab"
direction="bottom"
>
<template #activator>
<v-btn
v-model="fab"
color="primary"
fab
data-id="insert-creature-property-fab"
small
>
<v-icon>add</v-icon>
<v-icon>close</v-icon>
</v-btn>
</template>
<labeled-fab
v-for="type in speedDials"
:key="type"
color="primary"
:data-id="`insert-creature-property-type-${type}`"
:label="'New ' + properties[type].name"
:icon="properties[type].icon"
:disabled="!editPermission"
@click="insertPropertyOfType(type)"
/>
</v-speed-dial>
</template>
<script>
import LabeledFab from '/imports/ui/components/LabeledFab.vue';
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import PROPERTIES from '/imports/constants/PROPERTIES.js';
const tabs = [
'stats',
'features',
'inventory',
'spells',
'character',
'tree',
];
export default {
components: {
LabeledFab,
},
props: {
editPermission: Boolean,
},
data(){return {
fab: false,
};},
computed: {
creatureId(){
return this.$route.params.id;
},
tabNumber(){
return this.$store.getters.tabById(this.creatureId);
},
speedDials(){
return this.speedDialsByTab[tabs[this.tabNumber]];
},
speedDialsByTab() { return {
'stats': ['attribute', 'skill'],
'features': ['feature'],
'inventory': ['item', 'container'],
'spells': ['spellList', 'spell'],
'character': ['note'],
};},
properties(){
return PROPERTIES;
},
},
methods: {
insertPropertyOfType(type){
let that = this;
this.$store.commit('pushDialogStack', {
component: 'creature-property-creation-dialog',
elementId: 'insert-creature-property-type-' + type,
data: {
forcedType: type,
},
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 id;
}
});
}
}
}
</script>
<style lang="css" scoped>
</style>

View File

@@ -5,6 +5,7 @@
:color="toolbarColor"
:dark="isDark"
:light="!isDark"
extended
tabs
dense
>
@@ -73,11 +74,12 @@
>
<div
:key="$route.meta.title"
style="width: 100%"
class="layout row"
>
<v-tabs
v-if="creature"
slot="extension"
class="flex"
style="min-width: 0"
centered
grow
max="100px"
@@ -106,6 +108,10 @@
Tree
</v-tab>
</v-tabs>
<character-sheet-fab
class="character-sheet-fab"
:edit-permission="editPermission"
/>
</div>
</v-fade-transition>
</v-toolbar>
@@ -119,8 +125,15 @@ import { theme } from '/imports/ui/theme.js';
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
import CharacterSheetFab from '/imports/ui/creature/character/CharacterSheetFab.vue';
export default {
inject: {
context: { default: {} }
},
components: {
CharacterSheetFab,
},
data(){return {
theme,
}},
@@ -231,4 +244,8 @@ export default {
.character-sheet-toolbar .v-tabs__bar {
background: none !important;
}
.character-sheet-fab {
bottom: -24px;
margin-right: -8px;
}
</style>

View File

@@ -1,11 +1,11 @@
<template lang="html">
<selectable-property-dialog v-model="type">
<creature-property-insert-form
:type="type"
:property-name="getPropertyName(type)"
@back="type = undefined"
/>
</selectable-property-dialog>
<selectable-property-dialog :value="forcedType || type">
<creature-property-insert-form
:type="forcedType || type"
:property-name="getPropertyName(forcedType || type)"
@back="back"
/>
</selectable-property-dialog>
</template>
<script>
@@ -14,15 +14,28 @@ import CreaturePropertyInsertForm from '/imports/ui/creature/creatureProperties/
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
export default {
data() { return {
type: undefined,
};},
components: {
SelectablePropertyDialog,
CreaturePropertyInsertForm,
},
props: {
forcedType: {
type: String,
default: undefined,
},
},
data() { return {
type: undefined,
};},
methods: {
getPropertyName,
back(){
if (this.forcedType){
this.$store.dispatch('popDialogStack');
} else {
this.type = undefined;
}
},
},
};
</script>

View File

@@ -70,14 +70,22 @@ export default {
};},
watch: {
type(newType){
if (!newType) return;
this.schema = propertySchemasIndex[newType];
this.validationContext = this.schema.newContext();
let model = this.schema.clean({});
model.type = newType;
this.model = model;
this.changeType(newType);
},
},
mounted(){
this.changeType(this.type);
},
methods:{
changeType(type){
if (!type) return;
this.schema = propertySchemasIndex[type];
this.validationContext = this.schema.newContext();
let model = this.schema.clean({});
model.type = type;
this.model = model;
}
},
}
</script>

View File

@@ -25,7 +25,8 @@ for (const name in SVG_ICONS) {
}
Vue.use(VueMeteorTracker);
Vue.config.meteor.freeze = true
Vue.config.meteor.freeze = true;
Vue.config.devtools = true;
Vue.use(Vuetify, {
theme,
iconfont: 'md',