forked from opentiny/tiny-engine
318 lines
8.9 KiB
Vue
318 lines
8.9 KiB
Vue
<template>
|
||
<div class="property-setting-container">
|
||
<div class="property-title" @click="handleCancelEdit">
|
||
<icon-chevron-left></icon-chevron-left>
|
||
{{ propertyName }}
|
||
</div>
|
||
<tiny-form class="property-form" label-position="left" label-width="110px">
|
||
<tiny-form-item label="属性名(ID)">
|
||
<tiny-input v-model="propertyName"></tiny-input>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="属性值类型">
|
||
<tiny-select v-model="type" :options="typeList" @change="changeType"></tiny-select>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="属性面板组件">
|
||
<tiny-select
|
||
v-model="widgetComponent"
|
||
:options="widgetComponentList"
|
||
@change="handleChangeWidgetComponent"
|
||
></tiny-select>
|
||
<div class="global-desc-info">
|
||
区块发布后使用当前区块时,会在属性面板中使用当前选择的组件(例如SelectConfigurator),来配置该属性
|
||
</div>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="属性面板组件属性">
|
||
<meta-code-editor
|
||
:modelValue="widgetProps"
|
||
title="属性面板组件属性"
|
||
button-text="设置"
|
||
language="json"
|
||
:tips="componentPropsTips"
|
||
@save="handleSaveWidgetProps"
|
||
>
|
||
</meta-code-editor>
|
||
</tiny-form-item>
|
||
<tiny-form-item v-if="showArrayItemConfig" label="配置项">
|
||
<meta-list-items class="config-list" :optionsList="arrayConfig">
|
||
<template #content="{ data }">
|
||
<div :class="{ 'item-text': true }">
|
||
{{ data?.property }}
|
||
</div>
|
||
</template>
|
||
<template #operate="{ data }">
|
||
<div class="operate-right-container">
|
||
<tiny-tooltip class="item" effect="light" content="编辑" placement="top">
|
||
<span class="item-icon" @click.stop="handleEdit(data)">
|
||
<svg-icon name="to-edit"></svg-icon>
|
||
</span>
|
||
</tiny-tooltip>
|
||
<tiny-tooltip class="item" effect="light" content="删除" placement="top">
|
||
<span class="item-icon" @click="del(data)">
|
||
<svg-icon name="delete"></svg-icon>
|
||
</span>
|
||
</tiny-tooltip>
|
||
</div>
|
||
</template>
|
||
</meta-list-items>
|
||
<span class="add-item-btn" @click="handleAddItem">
|
||
<icon-plus-circle class="icon"></icon-plus-circle>
|
||
<span class="text">添加一项</span>
|
||
</span>
|
||
<teleport to=".block-manage">
|
||
<div v-if="showPropertyConfigItem" class="config-item-container" @click.stop>
|
||
<div v-for="(data, idx) in itemConfig" :key="idx" class="meta-config-item">
|
||
<config-item
|
||
:key="idx"
|
||
:property="data"
|
||
:data-prop-index="idx"
|
||
:data-group-index="index"
|
||
@update:modelValue="handleConfigItemChange(data.property, $event)"
|
||
>
|
||
<slot name="prefix" :data="data"></slot>
|
||
<slot name="suffix" :data="data"></slot>
|
||
</config-item>
|
||
</div>
|
||
</div>
|
||
</teleport>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="默认值">
|
||
<config-item
|
||
:property="defaultValueProperty"
|
||
:onlyEdit="true"
|
||
@update:modelValue="updateDefaultValue"
|
||
></config-item>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="属性显示名">
|
||
<tiny-input v-model="label"></tiny-input>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="获取属性值">
|
||
<meta-code-editor
|
||
:modelValue="getterValue"
|
||
title="获取属性值"
|
||
button-text="getter"
|
||
language="javascript"
|
||
single
|
||
@save="(...args) => saveAccessor('getter', ...args)"
|
||
></meta-code-editor>
|
||
</tiny-form-item>
|
||
<tiny-form-item label="设置属性值">
|
||
<meta-code-editor
|
||
:modelValue="setterValue"
|
||
title="设置属性值"
|
||
button-text="setter"
|
||
language="javascript"
|
||
single
|
||
@save="(...args) => saveAccessor('setter', ...args)"
|
||
></meta-code-editor>
|
||
</tiny-form-item>
|
||
<div v-if="property.linked" class="linked-info">
|
||
链接到组件: {{ property.linked.componentName }} 属性: {{ property.linked.property }}
|
||
</div>
|
||
</tiny-form>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
/* metaService: engine.plugins.blockmanage.BlockPropertyForm */
|
||
import { computed, ref, watch } from 'vue'
|
||
import {
|
||
Input as TinyInput,
|
||
Form as TinyForm,
|
||
FormItem as TinyFormItem,
|
||
Select as TinySelect,
|
||
Tooltip as TinyTooltip
|
||
} from '@opentiny/vue'
|
||
import { iconChevronLeft, iconPlusCircle } from '@opentiny/vue-icon'
|
||
import { ConfigItem, MetaListItems, MetaCodeEditor } from '@opentiny/tiny-engine-common'
|
||
import { getEditProperty, DEFAULT_ARRAY_CONFIG, META_COMPONENTS_ENUM } from './js/blockSetting'
|
||
import {
|
||
itemConfig,
|
||
arrayConfig,
|
||
showArrayItemConfig,
|
||
type,
|
||
label,
|
||
propertyName,
|
||
widgetComponent,
|
||
saveAccessor,
|
||
handleConfigItemChange,
|
||
handleAddItem,
|
||
del,
|
||
handleSaveWidgetProps,
|
||
updateDefaultValue,
|
||
handleChangeWidgetComponent,
|
||
handleEdit,
|
||
handleCancelEdit,
|
||
changeType,
|
||
widgetComponentList,
|
||
typeList,
|
||
showPropertyConfigItem
|
||
} from './js/blockPropertyForm'
|
||
|
||
export default {
|
||
components: {
|
||
TinyForm,
|
||
TinyInput,
|
||
TinySelect,
|
||
TinyFormItem,
|
||
ConfigItem,
|
||
MetaCodeEditor,
|
||
IconChevronLeft: iconChevronLeft(),
|
||
IconPlusCircle: iconPlusCircle(),
|
||
MetaListItems,
|
||
TinyTooltip
|
||
},
|
||
setup() {
|
||
const property = computed(() => getEditProperty() || {})
|
||
const getterValue = computed(() => property.value?.accessor?.getter?.value || 'function getter() {}')
|
||
const setterValue = computed(() => property.value?.accessor?.setter?.value || 'function setter() {}')
|
||
const defaultValueProperty = ref({
|
||
...property.value,
|
||
widget: {
|
||
props: {
|
||
...property.value.widget.props
|
||
},
|
||
component:
|
||
property.value.widget.component === META_COMPONENTS_ENUM.ArrayItemConfigurator
|
||
? META_COMPONENTS_ENUM.CodeConfigurator
|
||
: property.value.widget.component
|
||
}
|
||
})
|
||
|
||
const componentPropsTips = ref({
|
||
title: '该选项用于配置,当前选择的属性面板组件,其对应的props参数',
|
||
demo: '例如SelectConfigurator的props参数可以是 { options: [{ "label": "xx", "value": "xx"}, ...] }'
|
||
})
|
||
watch(
|
||
() => getEditProperty(),
|
||
(property) => {
|
||
if (!property) {
|
||
return
|
||
}
|
||
|
||
const {
|
||
defaultValue,
|
||
widget: { props, component },
|
||
...otherProperty
|
||
} = property
|
||
|
||
const newDefaultValueProperty = {
|
||
...otherProperty,
|
||
widget: {
|
||
props: {
|
||
...props,
|
||
modelValue: defaultValue
|
||
},
|
||
component:
|
||
component === META_COMPONENTS_ENUM.ArrayItemConfigurator
|
||
? META_COMPONENTS_ENUM.CodeConfigurator
|
||
: component
|
||
}
|
||
}
|
||
|
||
Object.assign(defaultValueProperty.value, newDefaultValueProperty)
|
||
},
|
||
{
|
||
deep: true
|
||
}
|
||
)
|
||
|
||
const widgetProps = computed(() => property.value?.widget?.props || {})
|
||
|
||
return {
|
||
type,
|
||
label,
|
||
property,
|
||
typeList,
|
||
getterValue,
|
||
setterValue,
|
||
propertyName,
|
||
changeType,
|
||
saveAccessor,
|
||
updateDefaultValue,
|
||
handleCancelEdit,
|
||
widgetProps,
|
||
handleSaveWidgetProps,
|
||
widgetComponent,
|
||
widgetComponentList,
|
||
handleChangeWidgetComponent,
|
||
arrayConfig,
|
||
DEFAULT_ARRAY_CONFIG,
|
||
handleEdit,
|
||
del,
|
||
handleAddItem,
|
||
showPropertyConfigItem,
|
||
handleConfigItemChange,
|
||
itemConfig,
|
||
defaultValueProperty,
|
||
showArrayItemConfig,
|
||
componentPropsTips
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.property-setting-container {
|
||
padding: 12px 15px;
|
||
}
|
||
|
||
.property-title {
|
||
margin-bottom: 12px;
|
||
cursor: pointer;
|
||
fill: currentcolor;
|
||
}
|
||
|
||
.property-form {
|
||
:deep(.tiny-form-item__label) {
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
.add-item-btn {
|
||
display: inline-block;
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: var(--te-block-property-add-item-text-color);
|
||
cursor: pointer;
|
||
|
||
.text {
|
||
margin-left: 4px;
|
||
}
|
||
}
|
||
|
||
.linked-info {
|
||
margin-top: 10px;
|
||
padding: 15px 0px;
|
||
}
|
||
|
||
.handle {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.config-item-container {
|
||
position: absolute;
|
||
right: calc(-280px - var(--base-collection-panel-width));
|
||
top: 0;
|
||
width: 280px;
|
||
height: 100%;
|
||
padding: 20px;
|
||
background-color: var(--te-block-property-config-item-bg-color);
|
||
border-right: 1px solid var(--te-block-property-config-item-border-color);
|
||
}
|
||
|
||
.config-list {
|
||
:deep(.operate-right-container) {
|
||
.item-icon {
|
||
cursor: pointer;
|
||
padding: 2px;
|
||
}
|
||
|
||
.item + .item {
|
||
margin-left: 8px;
|
||
}
|
||
}
|
||
}
|
||
</style>
|