Files
mixtape/zero.Web.UI/App/editor/editor-component.vue
T

223 lines
5.1 KiB
Vue
Raw Normal View History

2020-04-30 14:21:43 +02:00
<template>
2020-08-17 16:10:02 +02:00
<ui-property v-if="fulfillsCondition" :field="config.field" :label="label" :hide-label="config.hideLabel" :description="description" :required="config.required" :class="classList" :is-text="view === 'output'">
2020-07-03 15:32:32 +02:00
<component v-if="fieldComponent" :is="fieldComponent" :config="config" :value="model" :entity="value" @input="onChange" :meta="meta" :disabled="config.disabled" :depth="depth" />
2020-06-23 15:44:14 +02:00
<p v-if="config.helpText" class="ui-property-help" v-localize="config.helpText"></p>
2020-04-30 14:21:43 +02:00
</ui-property>
</template>
<script>
import Strings from 'zero/services/strings';
import Objects from 'zero/services/objects';
2020-06-23 12:23:23 +02:00
import Localization from 'zero/services/localization';
2020-04-30 14:21:43 +02:00
export default {
2020-04-30 15:35:09 +02:00
name: 'uiEditorComponent',
2020-04-30 14:21:43 +02:00
props: {
2020-04-30 15:35:09 +02:00
value: {
type: [ Object, Array ]
},
2020-06-23 12:23:23 +02:00
config: {
2020-04-30 14:21:43 +02:00
type: Object,
required: true
2020-05-01 12:40:08 +02:00
},
2020-06-23 12:23:23 +02:00
renderer: {
type: Object,
required: true
2020-06-29 18:20:43 +02:00
},
meta: {
type: Object,
default: () => { }
},
2020-06-30 12:12:31 +02:00
depth: {
type: Number,
default: 0
}
2020-04-30 14:21:43 +02:00
},
watch: {
value: {
deep: true,
handler: function ()
{
this.rebuildModel();
}
},
2020-06-23 12:23:23 +02:00
config: {
deep: true,
handler: function ()
{
this.rebuildConfig();
}
},
renderer: {
deep: true,
handler: function ()
{
this.rebuildConfig();
}
}
},
2020-04-30 14:21:43 +02:00
data: () => ({
fieldComponent: null,
model: null,
2020-06-23 12:23:23 +02:00
selector: [],
classList: [],
label: null,
description: null
2020-04-30 14:21:43 +02:00
}),
2020-05-19 13:13:40 +02:00
mounted()
{
this.rebuildModel();
},
2020-04-30 14:21:43 +02:00
computed: {
2020-05-01 12:40:08 +02:00
view()
2020-04-30 15:35:09 +02:00
{
2020-06-23 12:23:23 +02:00
return this.config.display;
2020-05-01 12:40:08 +02:00
},
classes()
{
2020-06-23 12:23:23 +02:00
2020-06-24 11:53:20 +02:00
},
fulfillsCondition()
{
return typeof this.config.condition !== 'function' || this.config.condition(this.value);
2020-04-30 14:21:43 +02:00
}
},
created()
{
2020-05-01 11:36:26 +02:00
this.fieldComponent = () =>
{
2020-05-01 12:40:08 +02:00
if (this.view === 'custom')
2020-05-01 11:36:26 +02:00
{
2020-06-23 12:23:23 +02:00
if (this.config.path.indexOf('@zero') === 0)
{
return import(`zero/` + this.config.path.substring(6));
}
2020-07-03 15:32:32 +02:00
else if (this.config.path.indexOf('@shop') === 0) // TODO common system for plugins
{
return import(`shop/` + this.config.path.substring(6));
}
2020-06-23 12:23:23 +02:00
else
{
// TODO external imports
}
2020-05-01 11:36:26 +02:00
}
2020-05-20 15:16:02 +02:00
else if (this.view === 'renderer')
{
2020-05-25 11:27:23 +02:00
return import(`zero/editor/editor`);
2020-05-20 15:16:02 +02:00
}
2020-05-01 11:36:26 +02:00
else
{
2020-06-23 12:23:23 +02:00
return import(`zero/editor/fields/${this.view.toLowerCase()}`);
2020-05-01 11:36:26 +02:00
}
}
2020-06-23 12:23:23 +02:00
this.rebuildModel();
this.rebuildConfig();
2020-04-30 15:35:09 +02:00
},
methods: {
rebuildModel()
{
2020-06-23 12:23:23 +02:00
this.selector = Strings.selectorToArray(this.config.field);
var currentValue = this.value;
if (!this.selector || !this.selector.length || !currentValue)
{
this.model = null;
}
else
{
for (var key of this.selector)
{
if (key in currentValue)
{
currentValue = currentValue[key];
}
else
{
break;
}
}
this.model = currentValue;
}
},
2020-06-23 12:23:23 +02:00
rebuildConfig()
{
// build class list
2020-06-24 14:03:54 +02:00
let classes = typeof this.config.class === 'string' ? this.config.class.split(' ') : (this.config.class || []);
2020-06-29 18:20:43 +02:00
if (this.view === 'renderer' || this.view === 'nested')
2020-06-23 12:23:23 +02:00
{
classes.push('full-width');
}
2020-06-30 12:12:31 +02:00
if (this.depth > 0)
{
classes.push('is-nested');
}
2020-06-23 12:23:23 +02:00
this.classList = classes;
// build label
let label = null;
if (this.config.label && this.config.label.indexOf('@') === 0)
{
label = this.config.label;
}
else if (this.renderer.labelTemplate)
{
label = this.renderer.labelTemplate(this.config.label || this.config.field);
}
else
{
label = this.config.label || this.config.field;
}
2020-06-25 16:15:23 +02:00
this.label = Localization.localize(label);
2020-06-23 12:23:23 +02:00
// build description
let description = null;
if (this.config.description && this.config.description.indexOf('@') === 0)
{
description = this.config.description;
}
else if (this.config.description === null)
{
description = null;
}
else if (this.renderer.descriptionTemplate)
{
description = this.renderer.descriptionTemplate(this.config.description || this.config.field);
}
else
{
description = this.config.description;
}
this.description = Localization.localize(description, { hideEmpty: true });
},
2020-04-30 15:35:09 +02:00
onChange(value)
{
2020-08-24 15:17:43 +02:00
if (typeof value === 'function')
{
value(this.value);
}
else
{
Objects.setValue(this.value, this.selector, value);
}
this.$emit('input', this.value);
2020-04-30 15:35:09 +02:00
}
2020-04-30 14:21:43 +02:00
}
}
</script>