Improved slot fill UI

Added custom button
Prop insert form disabled +child
No backdrop close creation forms
This commit is contained in:
Stefan Zermatten
2023-06-06 12:35:22 +02:00
parent a25ab2040c
commit 56ca4b1680
10 changed files with 129 additions and 13 deletions

View File

@@ -153,12 +153,13 @@
} }
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'add-creature-property-dialog', component: 'insert-property-dialog',
elementId: 'insert-creature-property-type-' + forcedType, elementId: 'insert-creature-property-type-' + forcedType,
data: { data: {
parentDoc: forcedType ? undefined : parent, parentDoc: forcedType ? undefined : parent,
forcedType, forcedType,
creatureId: this.creatureId, creatureId: this.creatureId,
noBackdropClose: true,
}, },
callback(result){ callback(result){
if (!result){ if (!result){

View File

@@ -150,11 +150,12 @@ export default {
addProperty(){ addProperty(){
let parentPropertyId = this._id; let parentPropertyId = this._id;
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'add-creature-property-dialog', component: 'insert-property-dialog',
elementId: 'insert-creature-property-btn', elementId: 'insert-creature-property-btn',
data: { data: {
parentDoc: this.creature, parentDoc: this.creature,
creatureId: this._id, creatureId: this._id,
noBackdropClose: true,
}, },
callback(result){ callback(result){
if (!result) return; if (!result) return;

View File

@@ -261,12 +261,13 @@ export default {
addProperty({elementId, suggestedType}){ addProperty({elementId, suggestedType}){
let parentPropertyId = this.model._id; let parentPropertyId = this.model._id;
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'add-creature-property-dialog', component: 'insert-property-dialog',
elementId, elementId,
data: { data: {
parentDoc: this.model, parentDoc: this.model,
creatureId: this.creatureId, creatureId: this.creatureId,
suggestedType, suggestedType,
noBackdropClose: true,
}, },
callback(result){ callback(result){
if (!result) return; if (!result) return;

View File

@@ -146,6 +146,22 @@
Load More Load More
</v-btn> </v-btn>
</v-layout> </v-layout>
<v-layout
column
align-center
justify-center
class="ma-4"
>
<v-btn
text
color="accent"
:disabled="!model"
data-id="custom-button"
@click="insertCustomFiller"
>
Create custom
</v-btn>
</v-layout>
<template v-if="!showDisabled && disabledNodeCount"> <template v-if="!showDisabled && disabledNodeCount">
<v-layout <v-layout
column column
@@ -208,6 +224,9 @@ import LibraryNodeExpansionContent from '/imports/client/ui/library/LibraryNodeE
import PropertyTags from '/imports/client/ui/properties/viewers/shared/PropertyTags.vue'; import PropertyTags from '/imports/client/ui/properties/viewers/shared/PropertyTags.vue';
import { getPropertyName } from '/imports/constants/PROPERTIES.js'; import { getPropertyName } from '/imports/constants/PROPERTIES.js';
import { clone } from 'lodash'; import { clone } from 'lodash';
import getDefaultSlotFiller from '/imports/api/library/methods/getDefaultSlotFiller.js';
import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js';
export default { export default {
components: { components: {
@@ -292,6 +311,49 @@ export default {
!this.selectedNodeIds.includes(node._id) !this.selectedNodeIds.includes(node._id)
) )
}, },
insertCustomFiller() {
if (!this.model) return;
const prop = getDefaultSlotFiller(this.model);
const parentRef = { id: this.slotId, collection: 'creatureProperties' };
const order = this.model.order + 0.5;
const $store = this.$store;
$store.commit('pushDialogStack', {
component: 'insert-property-dialog',
elementId: 'custom-button',
data: {
parentDoc: this.model,
creatureId: this.creatureId,
prop,
noBackdropClose: true,
},
callback(result) {
if (!result) return;
if (Array.isArray(result)){
let nodeIds = result;
insertPropertyFromLibraryNode.call({ nodeIds, parentRef, order });
setTimeout(() => $store.dispatch('popDialogStack'), 200);
} else if (typeof result === 'object') {
let creatureProperty = result;
creatureProperty.order = order;
insertProperty.call({ creatureProperty, parentRef });
setTimeout(() => $store.dispatch('popDialogStack'), 200);
/* Maybe replace the dialog with the edit version?
* It's a bit jank, but a common use case
$store.commit('replaceDialog', {
component: 'creature-property-dialog',
//elementId: `?`,
data: {
_id,
startInEditTab: true,
},
});
*/
}
}
});
},
}, },
meteor: { meteor: {
$subscribe: { $subscribe: {

View File

@@ -1,5 +1,5 @@
// Load commonly used dialogs immediately // Load commonly used dialogs immediately
import AddCreaturePropertyDialog from '/imports/client/ui/creature/creatureProperties/AddCreaturePropertyDialog.vue'; import InsertPropertyDialog from '/imports/client/ui/properties/InsertPropertyDialog.vue';
import CharacterCreationDialog from '/imports/client/ui/creature/character/CharacterCreationDialog.vue'; import CharacterCreationDialog from '/imports/client/ui/creature/character/CharacterCreationDialog.vue';
import CastSpellWithSlotDialog from '/imports/client/ui/properties/components/spells/CastSpellWithSlotDialog.vue'; import CastSpellWithSlotDialog from '/imports/client/ui/properties/components/spells/CastSpellWithSlotDialog.vue';
import CreatureFormDialog from '/imports/client/ui/creature/CreatureFormDialog.vue'; import CreatureFormDialog from '/imports/client/ui/creature/CreatureFormDialog.vue';
@@ -34,7 +34,7 @@ const ShareDialog = () => import('/imports/client/ui/sharing/ShareDialog.vue');
const UsernameDialog = () => import('/imports/client/ui/user/UsernameDialog.vue'); const UsernameDialog = () => import('/imports/client/ui/user/UsernameDialog.vue');
export default { export default {
AddCreaturePropertyDialog, InsertPropertyDialog,
ArchiveDialog, ArchiveDialog,
CastSpellWithSlotDialog, CastSpellWithSlotDialog,
CharacterCreationDialog, CharacterCreationDialog,

View File

@@ -299,7 +299,7 @@ export default {
} }
let parentPropertyId = this.model._id; let parentPropertyId = this.model._id;
this.$store.commit('pushDialogStack', { this.$store.commit('pushDialogStack', {
component: 'add-creature-property-dialog', component: 'insert-property-dialog',
elementId, elementId,
data: { data: {
parentDoc: this.model, parentDoc: this.model,

View File

@@ -16,7 +16,7 @@
flat flat
@change="propertyHelpChanged" @change="propertyHelpChanged"
/> />
<v-btn <v-btn
v-if="tab === 1" v-if="tab === 1"
icon icon
data-id="help-button" data-id="help-button"
@@ -61,16 +61,23 @@
<property-selector <property-selector
:no-library-only-props="!showLibraryOnlyProps" :no-library-only-props="!showLibraryOnlyProps"
:parent-type="parentDoc && parentDoc.type" :parent-type="parentDoc && parentDoc.type"
:current-type="type"
@select="e => type = e" @select="e => type = e"
/> />
</v-tab-item> </v-tab-item>
<v-tab-item :disabled="!type"> <v-tab-item
:disabled="!type"
class="dialog-background"
style="min-height: 100%;"
>
<v-card-text <v-card-text
v-if="!$slots['unwrapped-content']" v-if="!$slots['unwrapped-content']"
class="dialog-background"
> >
<property-form <property-form
v-if="type" v-if="type"
class="creature-property-form" class="creature-property-form"
no-child-insert
:model="model" :model="model"
:errors="errors" :errors="errors"
@change="change" @change="change"
@@ -84,8 +91,10 @@
:disabled="!type" :disabled="!type"
> >
<v-expansion-panels <v-expansion-panels
accordion
tile
multiple multiple
inset hover
> >
<v-expansion-panel <v-expansion-panel
v-for="libraryNode in libraryNodes" v-for="libraryNode in libraryNodes"
@@ -196,6 +205,7 @@ import getThemeColor from '/imports/client/ui/utility/getThemeColor.js';
import PropertySelector from '/imports/client/ui/properties/shared/PropertySelector.vue'; import PropertySelector from '/imports/client/ui/properties/shared/PropertySelector.vue';
import {snackbar} from '/imports/client/ui/components/snackbars/SnackbarQueue.js'; import {snackbar} from '/imports/client/ui/components/snackbars/SnackbarQueue.js';
import PropertyForm from '/imports/client/ui/properties/PropertyForm.vue'; import PropertyForm from '/imports/client/ui/properties/PropertyForm.vue';
import SimpleSchema from 'simpl-schema';
export default { export default {
components: { components: {
@@ -227,6 +237,14 @@ export default {
type: Object, type: Object,
default: undefined, default: undefined,
}, },
prop: {
type: Object,
default: undefined,
},
children: {
type: Array,
default: () => [],
},
hideLibraryTab: Boolean, hideLibraryTab: Boolean,
showLibraryOnlyProps: Boolean, showLibraryOnlyProps: Boolean,
}, },
@@ -236,9 +254,10 @@ export default {
}, },
data(){return { data(){return {
selectedNodeIds: [], selectedNodeIds: [],
type: this.forcedType || this.suggestedType, type: this.forcedType || this.suggestedType || this.prop?.type || undefined,
model: { model: this.prop || {
type: this.type, type: this.type,
children: [],
}, },
searchValue: undefined, searchValue: undefined,
debounceTime: 0, debounceTime: 0,
@@ -260,6 +279,9 @@ export default {
type(newType){ type(newType){
this.changeType(newType); this.changeType(newType);
}, },
prop(newProp) {
this.model = newProp
},
}, },
mounted(){ mounted(){
this.changeType(this.type); this.changeType(this.type);
@@ -298,12 +320,16 @@ export default {
this._subs.searchLibraryNodes.setData('limit', this.currentLimit + 32); this._subs.searchLibraryNodes.setData('limit', this.currentLimit + 32);
}, },
changeType(type){ changeType(type){
if (type == 'slotFiller') {
type = 'folder';
this.type = 'folder';
}
this._subs.searchLibraryNodes.setData('type', type); this._subs.searchLibraryNodes.setData('type', type);
if (!type) return; if (!type) return;
this.tab = 1; this.tab = 1;
this.schema = propertySchemasIndex[type]; this.schema = propertySchemasIndex[type];
this.validationContext = this.schema.newContext(); this.validationContext = this.schema.newContext();
let model = this.schema.clean({}); let model = this.schema.clean(this.model || {});
model.type = type; model.type = type;
this.model = model; this.model = model;
}, },
@@ -357,4 +383,11 @@ export default {
</script> </script>
<style lang="css" scoped> <style lang="css" scoped>
.dialog-background {
background-color: #fafafa;
}
.theme--dark .dialog-background {
background-color: #303030;
}
</style> </style>

View File

@@ -147,6 +147,7 @@
<v-btn <v-btn
v-for="suggestion in suggestedChildren" v-for="suggestion in suggestedChildren"
:key="suggestion.type" :key="suggestion.type"
:disabled="noChildInsert"
tile tile
plain plain
:data-id="`insert-${suggestion.type}-property-btn`" :data-id="`insert-${suggestion.type}-property-btn`"
@@ -158,6 +159,7 @@
{{ suggestion.details.name }} {{ suggestion.details.name }}
</v-btn> </v-btn>
<v-btn <v-btn
:disabled="noChildInsert"
tile tile
plain plain
data-id="insert-any-property-btn" data-id="insert-any-property-btn"
@@ -171,6 +173,12 @@
</v-icon> </v-icon>
{{ suggestedChildren.length ? '...Other' : 'Child' }} {{ suggestedChildren.length ? '...Other' : 'Child' }}
</v-btn> </v-btn>
<div
v-if="noChildInsert"
class="ma-2 text--disabled"
>
Children can be added after this property is created
</div>
</outlined-input> </outlined-input>
</v-col> </v-col>
</v-row> </v-row>
@@ -222,6 +230,7 @@ export default {
default: 'creatureProperties' default: 'creatureProperties'
}, },
embedded: Boolean, // This dialog is embedded in a page embedded: Boolean, // This dialog is embedded in a page
noChildInsert: Boolean, // Don't allow inserting of children in this form
}, },
data() { data() {
return { return {

View File

@@ -2,6 +2,8 @@
<v-card <v-card
hover hover
style="height: 100%; overflow: hidden;" style="height: 100%; overflow: hidden;"
:class="{'accent--text': disabled}"
:disabled="disabled"
@click="e => $emit('click', e)" @click="e => $emit('click', e)"
> >
<v-card-title <v-card-title
@@ -42,7 +44,8 @@ export default {
property: { property: {
type: Object, type: Object,
required: true, required: true,
} },
disabled: Boolean,
}, },
meteor: { meteor: {
showPropertyHelp(){ showPropertyHelp(){

View File

@@ -23,6 +23,7 @@
> >
<property-select-card <property-select-card
:property="property" :property="property"
:disabled="type === currentType"
@click="$emit('select', type)" @click="$emit('select', type)"
/> />
</v-col> </v-col>
@@ -46,6 +47,7 @@
> >
<property-select-card <property-select-card
:property="property" :property="property"
:disabled="type === currentType"
@click="$emit('select', type)" @click="$emit('select', type)"
/> />
</v-col> </v-col>
@@ -72,6 +74,10 @@ export default {
type: Array, type: Array,
default: undefined, default: undefined,
}, },
currentType: {
type: String,
default: undefined,
}
}, },
data() { data() {
return { return {