mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-13 00:09:20 +08:00
feat(editor): 支持禁用数据源与代码块
This commit is contained in:
parent
b1f020d532
commit
6152a78467
@ -415,6 +415,26 @@ const renderFunction = async (stage) => {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## renderType
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
是用iframe渲染还是直接渲染
|
||||||
|
|
||||||
|
- **默认值:** `iframe`
|
||||||
|
|
||||||
|
- **类型:** `string`
|
||||||
|
|
||||||
|
'iframe' | 'native'
|
||||||
|
|
||||||
|
- **示例:**
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<m-editor render-type="native"></m-editor>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
## autoScrollIntoView
|
## autoScrollIntoView
|
||||||
|
|
||||||
- **详情:**
|
- **详情:**
|
||||||
@ -942,4 +962,88 @@ const updateDragEl = (el, target) => {
|
|||||||
<m-editor :disabled-multi-select="true"></m-editor>
|
<m-editor :disabled-multi-select="true"></m-editor>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## guidesOptions
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
标尺配置
|
||||||
|
|
||||||
|
- **类型:** `Partial<GuidesOptions>`
|
||||||
|
|
||||||
|
|
||||||
|
## disabledPageFragment
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
禁用页面片
|
||||||
|
|
||||||
|
- **类型:** `boolean`
|
||||||
|
|
||||||
|
## disabledStageOverlay
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
禁用双击在浮层中单独编辑选中组件
|
||||||
|
|
||||||
|
- **类型:** `boolean`
|
||||||
|
|
||||||
|
## disabledShowSrc
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
禁用属性配置面板右下角显示源码的按钮
|
||||||
|
|
||||||
|
- **类型:** `boolean`
|
||||||
|
|
||||||
|
## disabledDataSource
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
禁用数据源
|
||||||
|
|
||||||
|
- **类型:** `boolean`
|
||||||
|
|
||||||
|
## disabledCodeBlock
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
禁用代码块
|
||||||
|
|
||||||
|
- **类型:** `boolean`
|
||||||
|
|
||||||
|
## treeIndent
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
已选组件、代码编辑、数据源缩进配置
|
||||||
|
|
||||||
|
- **类型:** `number`
|
||||||
|
|
||||||
|
## treeNextLevelIndentIncrement
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
已选组件、代码编辑、数据源子节点缩进增量配置
|
||||||
|
|
||||||
|
- **类型:** `number`
|
||||||
|
|
||||||
|
## customContentMenu
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
用于自定义组件树与画布的右键菜单
|
||||||
|
|
||||||
|
- **类型:** `function`
|
||||||
|
|
||||||
|
## pageBarSortOptions
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
页面顺序拖拽配置参数
|
||||||
|
|
||||||
|
## pageFilterFunction
|
||||||
|
|
||||||
|
- **详情:**
|
||||||
|
|
||||||
|
页面搜索函数
|
||||||
|
@ -81,6 +81,10 @@ export interface EditorProps {
|
|||||||
disabledStageOverlay?: boolean;
|
disabledStageOverlay?: boolean;
|
||||||
/** 禁用属性配置面板右下角显示源码的按钮 */
|
/** 禁用属性配置面板右下角显示源码的按钮 */
|
||||||
disabledShowSrc?: boolean;
|
disabledShowSrc?: boolean;
|
||||||
|
/** 禁用数据源 */
|
||||||
|
disabledDataSource?: boolean;
|
||||||
|
/** 禁用代码块 */
|
||||||
|
disabledCodeBlock?: boolean;
|
||||||
/** 已选组件、代码编辑、数据源缩进配置 */
|
/** 已选组件、代码编辑、数据源缩进配置 */
|
||||||
treeIndent?: number;
|
treeIndent?: number;
|
||||||
/** 已选组件、代码编辑、数据源子节点缩进增量配置 */
|
/** 已选组件、代码编辑、数据源子节点缩进增量配置 */
|
||||||
@ -111,6 +115,8 @@ export const defaultEditorProps = {
|
|||||||
containerHighlightDuration: 800,
|
containerHighlightDuration: 800,
|
||||||
containerHighlightType: ContainerHighlightType.DEFAULT,
|
containerHighlightType: ContainerHighlightType.DEFAULT,
|
||||||
disabledShowSrc: false,
|
disabledShowSrc: false,
|
||||||
|
disabledDataSource: false,
|
||||||
|
disabledCodeBlock: false,
|
||||||
componentGroupList: () => [],
|
componentGroupList: () => [],
|
||||||
datasourceList: () => [],
|
datasourceList: () => [],
|
||||||
menu: () => ({ left: [], right: [] }),
|
menu: () => ({ left: [], right: [] }),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-fields-data-source-field-select">
|
<div class="m-fields-data-source-field-select">
|
||||||
<FieldSelect
|
<FieldSelect
|
||||||
v-if="showDataSourceFieldSelect || !config.fieldConfig"
|
v-if="!disabledDataSource && (showDataSourceFieldSelect || !config.fieldConfig)"
|
||||||
:model-value="model[name]"
|
:model-value="model[name]"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:size="size"
|
:size="size"
|
||||||
@ -26,7 +26,11 @@
|
|||||||
@change="onChangeHandler"
|
@change="onChangeHandler"
|
||||||
></component>
|
></component>
|
||||||
|
|
||||||
<TMagicTooltip v-if="config.fieldConfig" :disabled="showDataSourceFieldSelect" content="选择数据源">
|
<TMagicTooltip
|
||||||
|
v-if="config.fieldConfig && !disabledDataSource"
|
||||||
|
:disabled="showDataSourceFieldSelect"
|
||||||
|
content="选择数据源"
|
||||||
|
>
|
||||||
<TMagicButton
|
<TMagicButton
|
||||||
style="margin-left: 5px"
|
style="margin-left: 5px"
|
||||||
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
||||||
@ -83,10 +87,11 @@ watch(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { dataSourceService } = useServices();
|
const { dataSourceService, propsService } = useServices();
|
||||||
const mForm = inject<FormState | undefined>('mForm');
|
const mForm = inject<FormState | undefined>('mForm');
|
||||||
|
|
||||||
const dataSources = computed(() => dataSourceService.get('dataSources') || []);
|
const dataSources = computed(() => dataSourceService.get('dataSources') || []);
|
||||||
|
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
||||||
|
|
||||||
const type = computed((): string => {
|
const type = computed((): string => {
|
||||||
let type = props.config.fieldConfig?.type;
|
let type = props.config.fieldConfig?.type;
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<TMagicInput
|
||||||
|
v-if="disabledDataSource"
|
||||||
|
v-model="state"
|
||||||
|
:disabled="disabled"
|
||||||
|
:size="size"
|
||||||
|
:clearable="true"
|
||||||
|
@change="changeHandler"
|
||||||
|
></TMagicInput>
|
||||||
<component
|
<component
|
||||||
v-if="disabled || isFocused"
|
v-else-if="disabled || isFocused"
|
||||||
:is="getDesignConfig('components')?.autocomplete.component || 'el-autocomplete'"
|
:is="getDesignConfig('components')?.autocomplete.component || 'el-autocomplete'"
|
||||||
class="tmagic-design-auto-complete"
|
class="tmagic-design-auto-complete"
|
||||||
ref="autocomplete"
|
ref="autocomplete"
|
||||||
@ -52,7 +60,7 @@ import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
|
|||||||
import { Coin } from '@element-plus/icons-vue';
|
import { Coin } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
import type { DataSchema, DataSourceSchema } from '@tmagic/core';
|
import type { DataSchema, DataSourceSchema } from '@tmagic/core';
|
||||||
import { getDesignConfig, TMagicAutocomplete, TMagicTag } from '@tmagic/design';
|
import { getDesignConfig, TMagicAutocomplete, TMagicInput, TMagicTag } from '@tmagic/design';
|
||||||
import type { DataSourceInputConfig, FieldProps } from '@tmagic/form';
|
import type { DataSourceInputConfig, FieldProps } from '@tmagic/form';
|
||||||
import { getKeysArray, isNumber } from '@tmagic/utils';
|
import { getKeysArray, isNumber } from '@tmagic/utils';
|
||||||
|
|
||||||
@ -72,7 +80,7 @@ const emit = defineEmits<{
|
|||||||
change: [value: string];
|
change: [value: string];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { dataSourceService } = useServices();
|
const { dataSourceService, propsService } = useServices();
|
||||||
|
|
||||||
const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
|
const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
|
||||||
const isFocused = ref(false);
|
const isFocused = ref(false);
|
||||||
@ -81,6 +89,7 @@ const displayState = ref<{ value: string; type: 'var' | 'text' }[]>([]);
|
|||||||
|
|
||||||
const input = computed<HTMLInputElement>(() => autocompleteRef.value?.inputRef?.input);
|
const input = computed<HTMLInputElement>(() => autocompleteRef.value?.inputRef?.input);
|
||||||
const dataSources = computed(() => dataSourceService.get('dataSources'));
|
const dataSources = computed(() => dataSourceService.get('dataSources'));
|
||||||
|
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
||||||
|
|
||||||
const setDisplayState = () => {
|
const setDisplayState = () => {
|
||||||
displayState.value = getDisplayField(dataSources.value, state.value);
|
displayState.value = getDisplayField(dataSources.value, state.value);
|
||||||
|
@ -85,7 +85,7 @@ const emit = defineEmits<{
|
|||||||
change: [v: any, eventData?: ContainerChangeEventData];
|
change: [v: any, eventData?: ContainerChangeEventData];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { editorService, dataSourceService, eventsService, codeBlockService } = useServices();
|
const { editorService, dataSourceService, eventsService, codeBlockService, propsService } = useServices();
|
||||||
|
|
||||||
// 事件名称下拉框表单配置
|
// 事件名称下拉框表单配置
|
||||||
const eventNameConfig = computed(() => {
|
const eventNameConfig = computed(() => {
|
||||||
@ -173,24 +173,39 @@ const actionTypeConfig = computed(() => {
|
|||||||
text: '联动类型',
|
text: '联动类型',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
defaultValue: ActionType.COMP,
|
defaultValue: ActionType.COMP,
|
||||||
options: () => [
|
options: () => {
|
||||||
{
|
const o: {
|
||||||
text: '组件',
|
text: string;
|
||||||
label: '组件',
|
label: string;
|
||||||
value: ActionType.COMP,
|
value: string;
|
||||||
},
|
disabled?: boolean;
|
||||||
{
|
}[] = [
|
||||||
text: '代码',
|
{
|
||||||
label: '代码',
|
text: '组件',
|
||||||
disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
|
label: '组件',
|
||||||
value: ActionType.CODE,
|
value: ActionType.COMP,
|
||||||
},
|
},
|
||||||
{
|
];
|
||||||
text: '数据源',
|
|
||||||
label: '数据源',
|
if (!propsService.getDisabledCodeBlock()) {
|
||||||
value: ActionType.DATA_SOURCE,
|
o.push({
|
||||||
},
|
text: '代码',
|
||||||
],
|
label: '代码',
|
||||||
|
disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
|
||||||
|
value: ActionType.CODE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!propsService.getDisabledDataSource()) {
|
||||||
|
o.push({
|
||||||
|
text: '数据源',
|
||||||
|
label: '数据源',
|
||||||
|
value: ActionType.DATA_SOURCE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return { ...defaultActionTypeConfig, ...props.config.actionTypeConfig };
|
return { ...defaultActionTypeConfig, ...props.config.actionTypeConfig };
|
||||||
});
|
});
|
||||||
|
@ -197,6 +197,22 @@ export const initServiceState = (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.disabledCodeBlock,
|
||||||
|
(disabledCodeBlock) => propsService.setDisabledCodeBlock(disabledCodeBlock ?? false),
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.disabledDataSource,
|
||||||
|
(disabledDataSource) => propsService.setDisabledDataSource(disabledDataSource ?? false),
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
editorService.resetState();
|
editorService.resetState();
|
||||||
historyService.resetState();
|
historyService.resetState();
|
||||||
|
@ -201,7 +201,7 @@ const props = withDefaults(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { depService, uiService } = useServices();
|
const { depService, uiService, propsService } = useServices();
|
||||||
|
|
||||||
const collecting = computed(() => depService.get('collecting'));
|
const collecting = computed(() => depService.get('collecting'));
|
||||||
const taskLength = computed(() => depService.get('taskLength'));
|
const taskLength = computed(() => depService.get('taskLength'));
|
||||||
@ -283,7 +283,19 @@ const getItemConfig = (data: SideItem): SideComponent => {
|
|||||||
return typeof data === 'string' ? map[data] : data;
|
return typeof data === 'string' ? map[data] : data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sideBarItems = computed(() => props.data.items.map((item) => getItemConfig(item)));
|
const sideBarItems = computed(() =>
|
||||||
|
props.data.items
|
||||||
|
.map((item) => getItemConfig(item))
|
||||||
|
.filter((item) => {
|
||||||
|
if (item.$key === SideItemKey.DATA_SOURCE) {
|
||||||
|
return !propsService.getDisabledDataSource();
|
||||||
|
}
|
||||||
|
if (item.$key === SideItemKey.CODE_BLOCK) {
|
||||||
|
return !propsService.getDisabledCodeBlock();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
sideBarItems,
|
sideBarItems,
|
||||||
|
@ -57,6 +57,10 @@ class Props extends BaseService {
|
|||||||
propsConfigMap: {},
|
propsConfigMap: {},
|
||||||
propsValueMap: {},
|
propsValueMap: {},
|
||||||
relateIdMap: {},
|
relateIdMap: {},
|
||||||
|
/** 禁用数据源 */
|
||||||
|
disabledDataSource: false,
|
||||||
|
/** 禁用代码块 */
|
||||||
|
disabledCodeBlock: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -66,6 +70,22 @@ class Props extends BaseService {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setDisabledDataSource(disabled: boolean) {
|
||||||
|
this.state.disabledDataSource = disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDisabledCodeBlock(disabled: boolean) {
|
||||||
|
this.state.disabledCodeBlock = disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDisabledDataSource(): boolean {
|
||||||
|
return this.state.disabledDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDisabledCodeBlock(): boolean {
|
||||||
|
return this.state.disabledCodeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
public setPropsConfigs(configs: Record<string, FormConfig | PropsFormConfigFunction>) {
|
public setPropsConfigs(configs: Record<string, FormConfig | PropsFormConfigFunction>) {
|
||||||
Object.keys(configs).forEach((type: string) => {
|
Object.keys(configs).forEach((type: string) => {
|
||||||
this.setPropsConfig(toLine(type), configs[type]);
|
this.setPropsConfig(toLine(type), configs[type]);
|
||||||
@ -74,7 +94,11 @@ class Props extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async fillConfig(config: FormConfig, labelWidth?: string) {
|
public async fillConfig(config: FormConfig, labelWidth?: string) {
|
||||||
return fillConfig(config, typeof labelWidth !== 'function' ? labelWidth : '80px');
|
return fillConfig(config, {
|
||||||
|
labelWidth: typeof labelWidth !== 'function' ? labelWidth : '80px',
|
||||||
|
disabledDataSource: this.getDisabledDataSource(),
|
||||||
|
disabledCodeBlock: this.getDisabledCodeBlock(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setPropsConfig(type: string, config: FormConfig | PropsFormConfigFunction) {
|
public async setPropsConfig(type: string, config: FormConfig | PropsFormConfigFunction) {
|
||||||
|
@ -188,6 +188,10 @@ export interface PropsState {
|
|||||||
propsConfigMap: Record<string, FormConfig>;
|
propsConfigMap: Record<string, FormConfig>;
|
||||||
propsValueMap: Record<string, Partial<MNode>>;
|
propsValueMap: Record<string, Partial<MNode>>;
|
||||||
relateIdMap: Record<Id, Id>;
|
relateIdMap: Record<Id, Id>;
|
||||||
|
/** 禁用数据源 */
|
||||||
|
disabledDataSource: boolean;
|
||||||
|
/** 禁用代码块 */
|
||||||
|
disabledCodeBlock: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StageOverlayState {
|
export interface StageOverlayState {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
import { NODE_CONDS_KEY } from '@tmagic/core';
|
import { NODE_CONDS_KEY } from '@tmagic/core';
|
||||||
import { tMagicMessage } from '@tmagic/design';
|
import { tMagicMessage } from '@tmagic/design';
|
||||||
import type { FormConfig, FormState, TabPaneConfig } from '@tmagic/form';
|
import type { FormConfig, FormState, TabConfig, TabPaneConfig } from '@tmagic/form';
|
||||||
|
|
||||||
export const arrayOptions = [
|
export const arrayOptions = [
|
||||||
{ text: '包含', value: 'include' },
|
{ text: '包含', value: 'include' },
|
||||||
@ -165,7 +165,14 @@ export const displayTabConfig: TabPaneConfig = {
|
|||||||
* @param config 组件属性配置
|
* @param config 组件属性配置
|
||||||
* @returns Object
|
* @returns Object
|
||||||
*/
|
*/
|
||||||
export const fillConfig = (config: FormConfig = [], labelWidth = '80px'): FormConfig => {
|
export const fillConfig = (
|
||||||
|
config: FormConfig = [],
|
||||||
|
{
|
||||||
|
labelWidth = '80px',
|
||||||
|
disabledDataSource = false,
|
||||||
|
disabledCodeBlock = false,
|
||||||
|
}: { labelWidth?: string; disabledDataSource?: boolean; disabledCodeBlock?: boolean } = {},
|
||||||
|
): FormConfig => {
|
||||||
const propsConfig: FormConfig = [];
|
const propsConfig: FormConfig = [];
|
||||||
|
|
||||||
// 组件类型,必须要有
|
// 组件类型,必须要有
|
||||||
@ -208,20 +215,34 @@ export const fillConfig = (config: FormConfig = [], labelWidth = '80px'): FormCo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
const noCodeAdvancedTabItems = advancedTabConfig.items.filter((item) => item.type !== 'code-select');
|
||||||
{
|
|
||||||
type: 'tab',
|
if (noCodeAdvancedTabItems.length > 0 && disabledCodeBlock) {
|
||||||
labelWidth,
|
advancedTabConfig.items = noCodeAdvancedTabItems;
|
||||||
items: [
|
}
|
||||||
{
|
|
||||||
title: '属性',
|
const tabConfig: TabConfig = {
|
||||||
items: [...propsConfig, ...config],
|
type: 'tab',
|
||||||
},
|
labelWidth,
|
||||||
{ ...styleTabConfig },
|
items: [
|
||||||
{ ...eventTabConfig },
|
{
|
||||||
{ ...advancedTabConfig },
|
title: '属性',
|
||||||
{ ...displayTabConfig },
|
items: [...propsConfig, ...config],
|
||||||
],
|
},
|
||||||
},
|
{ ...styleTabConfig },
|
||||||
];
|
{ ...eventTabConfig },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!disabledCodeBlock) {
|
||||||
|
tabConfig.items.push({ ...advancedTabConfig });
|
||||||
|
} else if (noCodeAdvancedTabItems.length > 0) {
|
||||||
|
tabConfig.items.push({ ...advancedTabConfig });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disabledDataSource) {
|
||||||
|
tabConfig.items.push({ ...displayTabConfig });
|
||||||
|
}
|
||||||
|
|
||||||
|
return [tabConfig];
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user