From 803bf323ceb0344c2b462fcfa95987a3b833b0f5 Mon Sep 17 00:00:00 2001 From: roymondchen Date: Sat, 7 Oct 2023 17:01:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor(editor):=20editor=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=94=B9=E6=88=90setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/src/utils/prepareEntryFile.ts | 2 +- packages/editor/src/Editor.vue | 115 +++++++------ packages/editor/src/editorProps.ts | 177 ++++++--------------- packages/editor/src/initService.ts | 48 +++--- 4 files changed, 132 insertions(+), 210 deletions(-) diff --git a/packages/cli/src/utils/prepareEntryFile.ts b/packages/cli/src/utils/prepareEntryFile.ts index 8ac4e187..e2f1f613 100644 --- a/packages/cli/src/utils/prepareEntryFile.ts +++ b/packages/cli/src/utils/prepareEntryFile.ts @@ -5,7 +5,7 @@ import { EntryType } from '../types'; export const prepareEntryFile = async (app: App) => { const { moduleMainFilePath, options } = app; - const { componentFileAffix, dynamicImport, hooks, useTs } = options; + const { componentFileAffix, dynamicImport, hooks, useTs = true } = options; let contentMap: Record = { 'comp-entry': generateContent(useTs, EntryType.COMPONENT, moduleMainFilePath.componentMap, componentFileAffix), diff --git a/packages/editor/src/Editor.vue b/packages/editor/src/Editor.vue index ee5f6438..60591917 100644 --- a/packages/editor/src/Editor.vue +++ b/packages/editor/src/Editor.vue @@ -80,11 +80,13 @@ - diff --git a/packages/editor/src/editorProps.ts b/packages/editor/src/editorProps.ts index 9d2cf1a5..a238fb6a 100644 --- a/packages/editor/src/editorProps.ts +++ b/packages/editor/src/editorProps.ts @@ -1,8 +1,6 @@ -import type { PropType } from 'vue'; - import type { EventOption } from '@tmagic/core'; import type { FormConfig, FormState } from '@tmagic/form'; -import type { DataSourceSchema, MApp, MNode } from '@tmagic/schema'; +import type { DataSourceSchema, Id, MApp, MNode } from '@tmagic/schema'; import StageCore, { CONTAINER_HIGHLIGHT_CLASS_NAME, ContainerHighlightType, @@ -21,145 +19,68 @@ import type { StageRect, } from './type'; -export default { +export interface EditorProps { /** 页面初始值 */ - modelValue: { - type: Object as PropType, - default: () => ({}), - require: true, - }, - - /** 左侧面板中的组件列表 */ - componentGroupList: { - type: Array as PropType, - default: () => [], - }, - - /** 左侧面板中的组件列表 */ - datasourceList: { - type: Array as PropType, - default: () => [], - }, - + modelValue?: MApp; + /** 左侧面板中的组件类型列表 */ + componentGroupList?: ComponentGroup[]; + /** 左侧面板中的数据源类型列表 */ + datasourceList?: DatasourceTypeOption[]; /** 左侧面板配置 */ - sidebar: { - type: Object as PropType, - }, - + sidebar?: SideBarData; /** 顶部工具栏配置 */ - menu: { - type: Object as PropType, - default: () => ({ left: [], right: [] }), - }, - + menu?: MenuBarData; /** 组件树右键菜单 */ - layerContentMenu: { - type: Array as PropType<(MenuButton | MenuComponent)[]>, - default: () => [], - }, - + layerContentMenu?: (MenuButton | MenuComponent)[]; /** 画布右键菜单 */ - stageContentMenu: { - type: Array as PropType<(MenuButton | MenuComponent)[]>, - default: () => [], - }, - + stageContentMenu?: (MenuButton | MenuComponent)[]; /** 中间工作区域中画布渲染的内容 */ - render: { - type: Function as PropType<(stage: StageCore) => HTMLDivElement | Promise>, - }, - + render?: (stage: StageCore) => HTMLDivElement | Promise; /** 中间工作区域中画布通过iframe渲染时的页面url */ - runtimeUrl: String, - + runtimeUrl?: string; /** 选中时是否自动滚动到可视区域 */ - autoScrollIntoView: Boolean, - + autoScrollIntoView?: boolean; /** 组件的属性配置表单的dsl */ - propsConfigs: { - type: Object as PropType>, - default: () => ({}), - }, - + propsConfigs?: Record; /** 添加组件时的默认值 */ - propsValues: { - type: Object as PropType>>, - default: () => ({}), - }, - + propsValues?: Record>; /** 组件联动事件选项列表 */ - eventMethodList: { - type: Object as PropType>, - default: () => ({}), - }, - + eventMethodList?: Record; /** 添加数据源时的默认值 */ - datasourceValues: { - type: Object as PropType>>, - default: () => ({}), - }, - + datasourceValues?: Record>; /** 数据源的属性配置表单的dsl */ - datasourceConfigs: { - type: Object as PropType>, - default: () => ({}), - }, - + datasourceConfigs?: Record; /** 画布中组件选中框的移动范围 */ - moveableOptions: { - type: [Object, Function] as PropType< - MoveableOptions | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions) - >, - }, - + moveableOptions?: MoveableOptions | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions); /** 编辑器初始化时默认选中的组件ID */ - defaultSelected: { - type: [Number, String], - }, + defaultSelected?: Id; + canSelect?: (el: HTMLElement) => boolean | Promise; + isContainer?: (el: HTMLElement) => boolean | Promise; + containerHighlightClassName?: string; + containerHighlightDuration?: number; + containerHighlightType?: ContainerHighlightType; + stageRect?: StageRect; + codeOptions?: { [key: string]: any }; + updateDragEl?: UpdateDragEl; + disabledDragStart?: boolean; + extendFormState?: (state: FormState) => Record | Promise>; +} - canSelect: { - type: Function as PropType<(el: HTMLElement) => boolean | Promise>, - default: (el: HTMLElement) => Boolean(el.id), - }, - - isContainer: { - type: Function as PropType<(el: HTMLElement) => boolean | Promise>, - default: (el: HTMLElement) => el.classList.contains('magic-ui-container'), - }, - - containerHighlightClassName: { - type: String, - default: CONTAINER_HIGHLIGHT_CLASS_NAME, - }, - - containerHighlightDuration: { - type: Number, - default: 800, - }, - - containerHighlightType: { - type: String as PropType, - default: ContainerHighlightType.DEFAULT, - }, - - stageRect: { - type: [String, Object] as PropType, - }, - - codeOptions: { - type: Object, - default: () => ({}), - }, - - updateDragEl: { - type: Function as PropType, - }, - - disabledDragStart: { - type: Boolean, - }, - - extendFormState: { - type: Function as PropType<(state: FormState) => Record | Promise>>, - }, +export const defaultEditorProps = { + componentGroupList: () => [], + datasourceList: () => [], + menu: () => ({ left: [], right: [] }), + layerContentMenu: () => [], + stageContentMenu: () => [], + propsConfigs: () => ({}), + propsValues: () => ({}), + eventMethodList: () => ({}), + datasourceValues: () => ({}), + datasourceConfigs: () => ({}), + canSelect: (el: HTMLElement) => Boolean(el.id), + isContainer: (el: HTMLElement) => el.classList.contains('magic-ui-container'), + containerHighlightClassName: CONTAINER_HIGHLIGHT_CLASS_NAME, + containerHighlightDuration: 800, + containerHighlightType: ContainerHighlightType.DEFAULT, + codeOptions: () => ({}), }; diff --git a/packages/editor/src/initService.ts b/packages/editor/src/initService.ts index 3b2e28d2..b0516b30 100644 --- a/packages/editor/src/initService.ts +++ b/packages/editor/src/initService.ts @@ -1,4 +1,3 @@ -import type { ExtractPropTypes } from 'vue'; import { onUnmounted, toRaw, watch } from 'vue'; import { cloneDeep } from 'lodash-es'; @@ -6,6 +5,7 @@ import type { EventOption } from '@tmagic/core'; import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema'; import { getNodes } from '@tmagic/utils'; +import PropsPanel from './layouts/PropsPanel.vue'; import type { Target } from './services/dep'; import { createCodeBlockTarget, @@ -13,7 +13,7 @@ import { createDataSourceMethodTarget, createDataSourceTarget, } from './utils/dep'; -import editorProps from './editorProps'; +import { EditorProps } from './editorProps'; import { DepTargetType, Services } from './type'; export declare type LooseRequired = { @@ -21,7 +21,7 @@ export declare type LooseRequired = { }; export const initServiceState = ( - props: Readonly>>>, + props: EditorProps, { editorService, historyService, @@ -38,7 +38,7 @@ export const initServiceState = ( watch( () => props.modelValue, (modelValue) => { - editorService.set('root', modelValue); + editorService.set('root', modelValue || null); }, { immediate: true, @@ -47,7 +47,7 @@ export const initServiceState = ( watch( () => props.componentGroupList, - (componentGroupList) => componentListService.setList(componentGroupList), + (componentGroupList) => componentGroupList && componentListService.setList(componentGroupList), { immediate: true, }, @@ -55,7 +55,7 @@ export const initServiceState = ( watch( () => props.datasourceList, - (datasourceList) => dataSourceService.set('datasourceTypeList', datasourceList), + (datasourceList) => datasourceList && dataSourceService.set('datasourceTypeList', datasourceList), { immediate: true, }, @@ -63,7 +63,7 @@ export const initServiceState = ( watch( () => props.propsConfigs, - (configs) => propsService.setPropsConfigs(configs), + (configs) => configs && propsService.setPropsConfigs(configs), { immediate: true, }, @@ -71,7 +71,7 @@ export const initServiceState = ( watch( () => props.propsValues, - (values) => propsService.setPropsValues(values), + (values) => values && propsService.setPropsValues(values), { immediate: true, }, @@ -83,10 +83,11 @@ export const initServiceState = ( const eventsList: Record = {}; const methodsList: Record = {}; - Object.keys(eventMethodList).forEach((type: string) => { - eventsList[type] = eventMethodList[type].events; - methodsList[type] = eventMethodList[type].methods; - }); + eventMethodList && + Object.keys(eventMethodList).forEach((type: string) => { + eventsList[type] = eventMethodList[type].events; + methodsList[type] = eventMethodList[type].methods; + }); eventsService.setEvents(eventsList); eventsService.setMethods(methodsList); @@ -99,9 +100,10 @@ export const initServiceState = ( watch( () => props.datasourceConfigs, (configs) => { - Object.entries(configs).forEach(([key, value]) => { - dataSourceService.setFormConfig(key, value); - }); + configs && + Object.entries(configs).forEach(([key, value]) => { + dataSourceService.setFormConfig(key, value); + }); }, { immediate: true, @@ -111,9 +113,10 @@ export const initServiceState = ( watch( () => props.datasourceValues, (values) => { - Object.entries(values).forEach(([key, value]) => { - dataSourceService.setFormValue(key, value); - }); + values && + Object.entries(values).forEach(([key, value]) => { + dataSourceService.setFormValue(key, value); + }); }, { immediate: true, @@ -148,8 +151,9 @@ export const initServiceState = ( }; export const initServiceEvents = ( - props: Readonly>>>, - emit: (event: 'props-panel-mounted' | 'update:modelValue', ...args: any[]) => void, + props: EditorProps, + emit: ((event: 'props-panel-mounted', instance: InstanceType) => void) & + ((event: 'update:modelValue', value: MApp | null) => void), { editorService, codeBlockService, dataSourceService, depService }: Services, ) => { const getApp = () => { @@ -247,7 +251,7 @@ export const initServiceEvents = ( depService.addTarget(createDataSourceCondTarget(ds.id)); }; - const rootChangeHandler = async (value: MApp, preValue?: MApp | null) => { + const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => { const nodeId = editorService.get('node')?.id || props.defaultSelected; let node; if (nodeId) { @@ -268,6 +272,8 @@ export const initServiceEvents = ( emit('update:modelValue', value); } + if (!value) return; + value.codeBlocks = value.codeBlocks || {}; value.dataSources = value.dataSources || [];