Added floating action button to add properties directly to the sheet
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
104
app/imports/ui/creature/character/CharacterSheetFab.vue
Normal file
104
app/imports/ui/creature/character/CharacterSheetFab.vue
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user