mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-10 22:19:23 +08:00
feat(editor): 支持禁用数据源与代码块
This commit is contained in:
parent
b1f020d532
commit
6152a78467
@ -415,6 +415,26 @@ const renderFunction = async (stage) => {
|
||||
</script>
|
||||
```
|
||||
|
||||
## renderType
|
||||
|
||||
- **详情:**
|
||||
|
||||
是用iframe渲染还是直接渲染
|
||||
|
||||
- **默认值:** `iframe`
|
||||
|
||||
- **类型:** `string`
|
||||
|
||||
'iframe' | 'native'
|
||||
|
||||
- **示例:**
|
||||
|
||||
```html
|
||||
<template>
|
||||
<m-editor render-type="native"></m-editor>
|
||||
</template>
|
||||
```
|
||||
|
||||
## autoScrollIntoView
|
||||
|
||||
- **详情:**
|
||||
@ -942,4 +962,88 @@ const updateDragEl = (el, target) => {
|
||||
<m-editor :disabled-multi-select="true"></m-editor>
|
||||
</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;
|
||||
/** 禁用属性配置面板右下角显示源码的按钮 */
|
||||
disabledShowSrc?: boolean;
|
||||
/** 禁用数据源 */
|
||||
disabledDataSource?: boolean;
|
||||
/** 禁用代码块 */
|
||||
disabledCodeBlock?: boolean;
|
||||
/** 已选组件、代码编辑、数据源缩进配置 */
|
||||
treeIndent?: number;
|
||||
/** 已选组件、代码编辑、数据源子节点缩进增量配置 */
|
||||
@ -111,6 +115,8 @@ export const defaultEditorProps = {
|
||||
containerHighlightDuration: 800,
|
||||
containerHighlightType: ContainerHighlightType.DEFAULT,
|
||||
disabledShowSrc: false,
|
||||
disabledDataSource: false,
|
||||
disabledCodeBlock: false,
|
||||
componentGroupList: () => [],
|
||||
datasourceList: () => [],
|
||||
menu: () => ({ left: [], right: [] }),
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="m-fields-data-source-field-select">
|
||||
<FieldSelect
|
||||
v-if="showDataSourceFieldSelect || !config.fieldConfig"
|
||||
v-if="!disabledDataSource && (showDataSourceFieldSelect || !config.fieldConfig)"
|
||||
:model-value="model[name]"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
@ -26,7 +26,11 @@
|
||||
@change="onChangeHandler"
|
||||
></component>
|
||||
|
||||
<TMagicTooltip v-if="config.fieldConfig" :disabled="showDataSourceFieldSelect" content="选择数据源">
|
||||
<TMagicTooltip
|
||||
v-if="config.fieldConfig && !disabledDataSource"
|
||||
:disabled="showDataSourceFieldSelect"
|
||||
content="选择数据源"
|
||||
>
|
||||
<TMagicButton
|
||||
style="margin-left: 5px"
|
||||
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
||||
@ -83,10 +87,11 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
const { dataSourceService } = useServices();
|
||||
const { dataSourceService, propsService } = useServices();
|
||||
const mForm = inject<FormState | undefined>('mForm');
|
||||
|
||||
const dataSources = computed(() => dataSourceService.get('dataSources') || []);
|
||||
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
||||
|
||||
const type = computed((): string => {
|
||||
let type = props.config.fieldConfig?.type;
|
||||
|
@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<TMagicInput
|
||||
v-if="disabledDataSource"
|
||||
v-model="state"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:clearable="true"
|
||||
@change="changeHandler"
|
||||
></TMagicInput>
|
||||
<component
|
||||
v-if="disabled || isFocused"
|
||||
v-else-if="disabled || isFocused"
|
||||
:is="getDesignConfig('components')?.autocomplete.component || 'el-autocomplete'"
|
||||
class="tmagic-design-auto-complete"
|
||||
ref="autocomplete"
|
||||
@ -52,7 +60,7 @@ import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
|
||||
import { Coin } from '@element-plus/icons-vue';
|
||||
|
||||
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 { getKeysArray, isNumber } from '@tmagic/utils';
|
||||
|
||||
@ -72,7 +80,7 @@ const emit = defineEmits<{
|
||||
change: [value: string];
|
||||
}>();
|
||||
|
||||
const { dataSourceService } = useServices();
|
||||
const { dataSourceService, propsService } = useServices();
|
||||
|
||||
const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
|
||||
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 dataSources = computed(() => dataSourceService.get('dataSources'));
|
||||
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
||||
|
||||
const setDisplayState = () => {
|
||||
displayState.value = getDisplayField(dataSources.value, state.value);
|
||||
|
@ -85,7 +85,7 @@ const emit = defineEmits<{
|
||||
change: [v: any, eventData?: ContainerChangeEventData];
|
||||
}>();
|
||||
|
||||
const { editorService, dataSourceService, eventsService, codeBlockService } = useServices();
|
||||
const { editorService, dataSourceService, eventsService, codeBlockService, propsService } = useServices();
|
||||
|
||||
// 事件名称下拉框表单配置
|
||||
const eventNameConfig = computed(() => {
|
||||
@ -173,24 +173,39 @@ const actionTypeConfig = computed(() => {
|
||||
text: '联动类型',
|
||||
type: 'select',
|
||||
defaultValue: ActionType.COMP,
|
||||
options: () => [
|
||||
{
|
||||
text: '组件',
|
||||
label: '组件',
|
||||
value: ActionType.COMP,
|
||||
},
|
||||
{
|
||||
text: '代码',
|
||||
label: '代码',
|
||||
disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
|
||||
value: ActionType.CODE,
|
||||
},
|
||||
{
|
||||
text: '数据源',
|
||||
label: '数据源',
|
||||
value: ActionType.DATA_SOURCE,
|
||||
},
|
||||
],
|
||||
options: () => {
|
||||
const o: {
|
||||
text: string;
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}[] = [
|
||||
{
|
||||
text: '组件',
|
||||
label: '组件',
|
||||
value: ActionType.COMP,
|
||||
},
|
||||
];
|
||||
|
||||
if (!propsService.getDisabledCodeBlock()) {
|
||||
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 };
|
||||
});
|
||||
|
@ -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(() => {
|
||||
editorService.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 taskLength = computed(() => depService.get('taskLength'));
|
||||
@ -283,7 +283,19 @@ const getItemConfig = (data: SideItem): SideComponent => {
|
||||
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(
|
||||
sideBarItems,
|
||||
|
@ -57,6 +57,10 @@ class Props extends BaseService {
|
||||
propsConfigMap: {},
|
||||
propsValueMap: {},
|
||||
relateIdMap: {},
|
||||
/** 禁用数据源 */
|
||||
disabledDataSource: false,
|
||||
/** 禁用代码块 */
|
||||
disabledCodeBlock: false,
|
||||
});
|
||||
|
||||
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>) {
|
||||
Object.keys(configs).forEach((type: string) => {
|
||||
this.setPropsConfig(toLine(type), configs[type]);
|
||||
@ -74,7 +94,11 @@ class Props extends BaseService {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -188,6 +188,10 @@ export interface PropsState {
|
||||
propsConfigMap: Record<string, FormConfig>;
|
||||
propsValueMap: Record<string, Partial<MNode>>;
|
||||
relateIdMap: Record<Id, Id>;
|
||||
/** 禁用数据源 */
|
||||
disabledDataSource: boolean;
|
||||
/** 禁用代码块 */
|
||||
disabledCodeBlock: boolean;
|
||||
}
|
||||
|
||||
export interface StageOverlayState {
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
import { NODE_CONDS_KEY } from '@tmagic/core';
|
||||
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 = [
|
||||
{ text: '包含', value: 'include' },
|
||||
@ -165,7 +165,14 @@ export const displayTabConfig: TabPaneConfig = {
|
||||
* @param config 组件属性配置
|
||||
* @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 = [];
|
||||
|
||||
// 组件类型,必须要有
|
||||
@ -208,20 +215,34 @@ export const fillConfig = (config: FormConfig = [], labelWidth = '80px'): FormCo
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'tab',
|
||||
labelWidth,
|
||||
items: [
|
||||
{
|
||||
title: '属性',
|
||||
items: [...propsConfig, ...config],
|
||||
},
|
||||
{ ...styleTabConfig },
|
||||
{ ...eventTabConfig },
|
||||
{ ...advancedTabConfig },
|
||||
{ ...displayTabConfig },
|
||||
],
|
||||
},
|
||||
];
|
||||
const noCodeAdvancedTabItems = advancedTabConfig.items.filter((item) => item.type !== 'code-select');
|
||||
|
||||
if (noCodeAdvancedTabItems.length > 0 && disabledCodeBlock) {
|
||||
advancedTabConfig.items = noCodeAdvancedTabItems;
|
||||
}
|
||||
|
||||
const tabConfig: TabConfig = {
|
||||
type: 'tab',
|
||||
labelWidth,
|
||||
items: [
|
||||
{
|
||||
title: '属性',
|
||||
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