Worked on universal property form
This commit is contained in:
@@ -7,16 +7,18 @@
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
:outlined="!!label"
|
||||
:icon="!label"
|
||||
:tile="!label"
|
||||
:min-width="label && 108"
|
||||
:height="height"
|
||||
:width="width"
|
||||
:disabled="context.editPermission === false"
|
||||
v-on="on"
|
||||
>
|
||||
{{ label }}
|
||||
<v-icon
|
||||
:right="!!label"
|
||||
:color="label && value"
|
||||
:color="value"
|
||||
>
|
||||
mdi-format-paint
|
||||
</v-icon>
|
||||
@@ -137,7 +139,15 @@
|
||||
label: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
}
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
data(){ return {
|
||||
colors: [
|
||||
|
||||
@@ -5,26 +5,32 @@
|
||||
transition="slide-y-transition"
|
||||
min-width="290px"
|
||||
style="overflow-y: auto;"
|
||||
left
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
:loading="loading"
|
||||
outlined
|
||||
:min-width="108"
|
||||
v-bind="$attrs"
|
||||
:outlined="!!label"
|
||||
:icon="!label"
|
||||
:tile="!label"
|
||||
:min-width="label && 108"
|
||||
:height="height"
|
||||
:width="width"
|
||||
:style="buttonStyle"
|
||||
:disabled="context.editPermission === false"
|
||||
v-bind="$attrs"
|
||||
v-on="on"
|
||||
>
|
||||
{{ label }}
|
||||
<svg-icon
|
||||
v-if="safeValue && safeValue.shape"
|
||||
right
|
||||
class="ml-2"
|
||||
:class="{'ml-2': !!label}"
|
||||
:shape="safeValue.shape"
|
||||
/>
|
||||
<v-icon
|
||||
v-else
|
||||
right
|
||||
:right="!!label"
|
||||
>
|
||||
mdi-select-search
|
||||
</v-icon>
|
||||
@@ -87,15 +93,26 @@ export default {
|
||||
SvgIcon,
|
||||
},
|
||||
mixins: [SmartInput],
|
||||
inject: {
|
||||
context: { default: {} }
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: 'Icon',
|
||||
default: undefined,
|
||||
},
|
||||
buttonStyle: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -29,11 +29,6 @@
|
||||
style="flex-shrink: 0;"
|
||||
>
|
||||
<v-spacer />
|
||||
<color-picker
|
||||
v-if="$listeners && $listeners['color-changed']"
|
||||
:value="model.color"
|
||||
@input="colorChanged"
|
||||
/>
|
||||
<v-menu
|
||||
v-if="$listeners && (
|
||||
$listeners.move ||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
@duplicate="duplicate"
|
||||
@remove="remove"
|
||||
@toggle-editing="editing = !editing"
|
||||
@color-changed="value => change({path: ['color'], value})"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="model">
|
||||
@@ -32,37 +31,16 @@
|
||||
mode="out-in"
|
||||
>
|
||||
<div v-if="editing">
|
||||
<component
|
||||
:is="model.type + 'Form'"
|
||||
<property-form
|
||||
:key="_id"
|
||||
class="creature-property-form"
|
||||
:model="model"
|
||||
:embedded="embedded"
|
||||
@change="change"
|
||||
@push="push"
|
||||
@pull="pull"
|
||||
>
|
||||
<template #children>
|
||||
<creature-properties-tree
|
||||
style="width: 100%;"
|
||||
class="mb-2"
|
||||
organize
|
||||
:root="{collection: 'creatureProperties', id: model._id}"
|
||||
@length="childrenLength = $event"
|
||||
@selected="selectSubProperty"
|
||||
/>
|
||||
<v-btn
|
||||
icon
|
||||
outlined
|
||||
color="accent"
|
||||
data-id="insert-creature-property-btn"
|
||||
@click="addProperty"
|
||||
>
|
||||
<v-icon>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</component>
|
||||
@add-child="addProperty"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<component
|
||||
@@ -123,6 +101,7 @@ import DialogBase from '/imports/client/ui/dialogStack/DialogBase.vue';
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
import PropertyIcon from '/imports/client/ui/properties/shared/PropertyIcon.vue';
|
||||
import propertyFormIndex from '/imports/client/ui/properties/forms/shared/propertyFormIndex.js';
|
||||
import PropertyForm from '/imports/client/ui/properties/PropertyForm.vue';
|
||||
import propertyViewerIndex from '/imports/client/ui/properties/viewers/shared/propertyViewerIndex.js';
|
||||
import CreaturePropertiesTree from '/imports/client/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
|
||||
import getPropertyTitle from '/imports/client/ui/properties/shared/getPropertyTitle.js';
|
||||
@@ -150,6 +129,7 @@ export default {
|
||||
components: {
|
||||
...formIndex,
|
||||
...viewerIndex,
|
||||
PropertyForm,
|
||||
PropertyIcon,
|
||||
DialogBase,
|
||||
PropertyToolbar,
|
||||
|
||||
@@ -3,30 +3,24 @@
|
||||
<v-row>
|
||||
<v-col
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<icon-color-menu
|
||||
:model="model"
|
||||
:errors="errors"
|
||||
@change="$emit('change', ...arguments)"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="12"
|
||||
md="6"
|
||||
class="d-flex flex-wrap-reverse justify-end"
|
||||
style="gap: 8px"
|
||||
>
|
||||
<text-field
|
||||
ref="focusFirst"
|
||||
label="Name"
|
||||
style="flex-basis: 320px;"
|
||||
:value="model.name"
|
||||
:error-messages="errors.name"
|
||||
@change="change('name', ...arguments)"
|
||||
/>
|
||||
<icon-color-menu
|
||||
:model="model"
|
||||
@change="$emit('change', $event)"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<component
|
||||
:is="model.type + 'Form'"
|
||||
:key="_id"
|
||||
:is="model.type"
|
||||
class="creature-property-form"
|
||||
:model="model"
|
||||
@change="$emit('change', ...arguments)"
|
||||
@@ -34,24 +28,6 @@
|
||||
@pull="$emit('pull', ...arguments)"
|
||||
/>
|
||||
<v-divider inset />
|
||||
<v-row
|
||||
v-show="!embedded && childrenLength"
|
||||
class="mt-1"
|
||||
dense
|
||||
>
|
||||
<property-field
|
||||
name="Child properties"
|
||||
:cols="{cols: 12}"
|
||||
>
|
||||
<creature-properties-tree
|
||||
style="width: 100%;"
|
||||
organize
|
||||
:root="{collection: 'creatureProperties', id: model._id}"
|
||||
@length="childrenLength = $event"
|
||||
@selected="selectSubProperty"
|
||||
/>
|
||||
</property-field>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col
|
||||
cols="12"
|
||||
@@ -68,6 +44,52 @@
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row
|
||||
class="mt-1"
|
||||
dense
|
||||
>
|
||||
<v-col
|
||||
cols="12"
|
||||
class="d-flex flex-wrap-reverse justify-end"
|
||||
style="gap: 8px"
|
||||
>
|
||||
<outlined-input
|
||||
name="Child properties"
|
||||
style="width: 100%"
|
||||
class="pa-2"
|
||||
>
|
||||
<creature-properties-tree
|
||||
style="width: 100%;"
|
||||
organize
|
||||
:root="{collection: 'creatureProperties', id: model._id}"
|
||||
@selected="selectSubProperty"
|
||||
/>
|
||||
<v-btn
|
||||
v-for="suggestion in suggestedChildren"
|
||||
:key="suggestion.type"
|
||||
text
|
||||
tile
|
||||
color="accent"
|
||||
data-id="insert-creature-property-btn"
|
||||
@click="$emit('add-child')"
|
||||
>
|
||||
<v-icon left>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
{{ suggestion.details.name }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
text
|
||||
tile
|
||||
color="accent"
|
||||
data-id="insert-creature-property-btn"
|
||||
@click="$emit('add-child')"
|
||||
>
|
||||
...Other
|
||||
</v-btn>
|
||||
</outlined-input>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -79,6 +101,11 @@
|
||||
import ComputedField from '/imports/client/ui/properties/forms/shared/ComputedField.vue';
|
||||
import InlineComputationField from '/imports/client/ui/properties/forms/shared/InlineComputationField.vue';
|
||||
import FormSection, { FormSections } from '/imports/client/ui/properties/forms/shared/FormSection.vue';
|
||||
import propertyFormIndex from '/imports/client/ui/properties/forms/shared/propertyFormIndex.js';
|
||||
import IconColorMenu from '/imports/client/ui/properties/forms/shared/IconColorMenu.vue';
|
||||
import CreaturePropertiesTree from '/imports/client/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
|
||||
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
||||
import { getSuggestedChildren } from '/imports/constants/PROPERTIES.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -86,15 +113,22 @@ export default {
|
||||
InlineComputationField,
|
||||
FormSection,
|
||||
FormSections,
|
||||
IconColorMenu,
|
||||
CreaturePropertiesTree,
|
||||
OutlinedInput,
|
||||
...propertyFormIndex,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: [Object, Array],
|
||||
default: () => ({}),
|
||||
},
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
embedded: Boolean, // This dialog is embedded in a page
|
||||
},
|
||||
computed: {
|
||||
suggestedChildren() {
|
||||
if (!this.model?.type) return;
|
||||
return getSuggestedChildren(this.model.type);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template lang="html">
|
||||
<v-card
|
||||
:hover="hasClickListener"
|
||||
:color="model.color"
|
||||
:dark="model.color && isDark"
|
||||
:light="model.color && !isDark"
|
||||
@click="click"
|
||||
@mouseover="hasClickListener ? hovering = true : undefined"
|
||||
@mouseleave="hasClickListener ? hovering = false : undefined"
|
||||
@@ -13,6 +16,7 @@
|
||||
<script lang="js">
|
||||
import CardHighlight from '/imports/client/ui/components/CardHighlight.vue';
|
||||
import AttributeCardContent from '/imports/client/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||
import isDarkColor from '/imports/client/ui/utility/isDarkColor.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -33,6 +37,10 @@
|
||||
hasClickListener(){
|
||||
return this.$listeners && !!this.$listeners.click
|
||||
},
|
||||
isDark() {
|
||||
if (!this.model.color) return;
|
||||
return isDarkColor(this.model.color);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
click(e){
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
<v-card
|
||||
class="resource-card"
|
||||
:class="hover ? 'elevation-8': ''"
|
||||
:color="model.color"
|
||||
:dark="model.color && isDark"
|
||||
:light="model.color && !isDark"
|
||||
>
|
||||
<resource-card-content
|
||||
:model="model"
|
||||
@@ -18,6 +21,7 @@
|
||||
<script lang="js">
|
||||
import CardHighlight from '/imports/client/ui/components/CardHighlight.vue';
|
||||
import ResourceCardContent from '/imports/client/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||
import isDarkColor from '/imports/client/ui/utility/isDarkColor.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -38,6 +42,12 @@ export default {
|
||||
hover: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isDark() {
|
||||
if (!this.model.color) return;
|
||||
return isDarkColor(this.model.color);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,31 +1,40 @@
|
||||
<template lang="html">
|
||||
<div
|
||||
class="d-flex justify-center flex-wrap"
|
||||
class="d-flex flex-wrap align-start"
|
||||
>
|
||||
<div class="mx-1">
|
||||
<color-picker
|
||||
label="Color"
|
||||
:value="model.color"
|
||||
@input="value =>$emit('change', {path: ['color'], value})"
|
||||
/>
|
||||
</div>
|
||||
<div class="mx-1">
|
||||
<outlined-input
|
||||
name="Icon"
|
||||
class="mb-4"
|
||||
>
|
||||
<icon-picker
|
||||
label="Icon"
|
||||
:value="model.icon"
|
||||
:error-messages="errors.icon"
|
||||
:width="54"
|
||||
:height="54"
|
||||
@change="(value, ack) =>$emit('change', {path: ['icon'], value, ack})"
|
||||
/>
|
||||
</div>
|
||||
</outlined-input>
|
||||
<outlined-input
|
||||
name="Color"
|
||||
class="mb-4 ml-2"
|
||||
>
|
||||
<color-picker
|
||||
:value="model.color"
|
||||
:width="54"
|
||||
:height="54"
|
||||
@input="value =>$emit('change', {path: ['color'], value})"
|
||||
/>
|
||||
</outlined-input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import PropertyIcon from '/imports/client/ui/properties/shared/PropertyIcon.vue';
|
||||
import ColorPicker from '/imports/client/ui/components/ColorPicker.vue';
|
||||
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
OutlinedInput,
|
||||
PropertyIcon,
|
||||
ColorPicker,
|
||||
},
|
||||
@@ -34,10 +43,6 @@
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
errors: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<v-sheet
|
||||
outlined
|
||||
rounded
|
||||
style="position: relative;"
|
||||
@click="$emit('click', $event)"
|
||||
>
|
||||
<v-sheet
|
||||
v-if="name"
|
||||
class="text-caption px-1 ml-2 name"
|
||||
style="top: 0; left: 0; margin-top: -10px; position: absolute;"
|
||||
>
|
||||
{{ name }}
|
||||
</v-sheet>
|
||||
<slot />
|
||||
</v-sheet>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -209,14 +209,25 @@ const PROPERTIES = Object.freeze({
|
||||
|
||||
export default PROPERTIES;
|
||||
|
||||
export function getPropertyName(type){
|
||||
export function getPropertyName(type) {
|
||||
return type && PROPERTIES[type] && PROPERTIES[type].name;
|
||||
}
|
||||
|
||||
export function getPropertyIcon(type){
|
||||
export function getPropertyIcon(type) {
|
||||
return type && PROPERTIES[type] && PROPERTIES[type].icon;
|
||||
}
|
||||
|
||||
export function getSuggestedChildren(type) {
|
||||
const suggestions = [];
|
||||
for (const key in PROPERTIES) {
|
||||
const prop = PROPERTIES[key];
|
||||
if (prop.suggestedParents.includes(type)) {
|
||||
suggestions.push({ type: key, details: prop });
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
const propsByDocsPath = new Map();
|
||||
|
||||
for (const key in PROPERTIES) {
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
"allowJs": true
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
"target": 2.7,
|
||||
// "target": 2, // For Vue version <= 2.6.14
|
||||
"target": 2 // For Vue version <= 2.6.14
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
|
||||
Reference in New Issue
Block a user