From 7b6dcedfad07af458d2496b69230fe2920dead70 Mon Sep 17 00:00:00 2001 From: roymondchen Date: Mon, 18 Dec 2023 19:51:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(core,editor,ui):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/Node.ts | 9 +- packages/core/src/Page.ts | 11 +- packages/editor/src/Editor.vue | 7 +- packages/editor/src/editorProps.ts | 5 + .../editor/src/fields/PageFragmentSelect.vue | 55 ++++++ packages/editor/src/index.ts | 3 + packages/editor/src/initService.ts | 4 +- packages/editor/src/layouts/AddPageBox.vue | 20 ++- packages/editor/src/layouts/Framework.vue | 17 +- .../editor/src/layouts/page-bar/AddButton.vue | 48 ++++++ .../editor/src/layouts/page-bar/PageBar.vue | 158 ++++++++++++++++++ .../PageBarScrollContainer.vue | 92 ++++++---- .../src/layouts/page-bar/SwitchTypeButton.vue | 45 +++++ .../layouts/sidebar/layer/use-node-status.ts | 6 +- .../editor/src/layouts/workspace/PageBar.vue | 87 ---------- .../src/layouts/workspace/Workspace.vue | 6 - packages/editor/src/services/editor.ts | 95 +++++++---- packages/editor/src/services/history.ts | 8 +- packages/editor/src/services/keybinding.ts | 6 +- packages/editor/src/theme/code-block.scss | 16 -- packages/editor/src/theme/page-bar.scss | 19 ++- packages/editor/src/type.ts | 22 ++- packages/editor/src/utils/editor.ts | 37 ++-- packages/editor/src/utils/operator.ts | 8 +- .../editor/tests/unit/utils/editor.spec.ts | 2 +- packages/schema/src/index.ts | 12 +- packages/ui-react/src/index.ts | 4 + .../src/page-fragment-container/index.ts | 24 +++ .../src/PageFragmentContainer.tsx | 55 ++++++ .../page-fragment-container/src/formConfig.ts | 25 +++ .../page-fragment-container/src/initValue.ts | 24 +++ packages/ui-react/src/page-fragment/index.ts | 24 +++ .../src/page-fragment/src/PageFragment.tsx | 51 ++++++ .../src/page-fragment/src/formConfig.ts | 50 ++++++ .../src/page-fragment/src/initValue.ts | 25 +++ packages/ui-vue2/src/index.ts | 4 + .../src/page-fragment-container/index.ts | 24 +++ .../src/PageFragmentContainer.vue | 59 +++++++ .../page-fragment-container/src/formConfig.ts | 25 +++ .../page-fragment-container/src/initValue.ts | 24 +++ packages/ui-vue2/src/page-fragment/index.ts | 24 +++ .../src/page-fragment/src/PageFragment.vue | 42 +++++ .../src/page-fragment/src/formConfig.ts | 50 ++++++ .../src/page-fragment/src/initValue.ts | 25 +++ packages/ui/src/index.ts | 4 + .../ui/src/page-fragment-container/index.ts | 24 +++ .../src/PageFragmentContainer.vue | 57 +++++++ .../page-fragment-container/src/formConfig.ts | 25 +++ .../page-fragment-container/src/initValue.ts | 24 +++ packages/ui/src/page-fragment/index.ts | 24 +++ .../ui/src/page-fragment/src/PageFragment.vue | 41 +++++ .../ui/src/page-fragment/src/formConfig.ts | 50 ++++++ .../ui/src/page-fragment/src/initValue.ts | 25 +++ packages/utils/src/index.ts | 5 + playground/src/configs/componentGroupList.ts | 7 +- runtime/react/playground/main.tsx | 2 +- runtime/vue2/playground/index.html | 2 +- runtime/vue3/playground/index.html | 2 +- 58 files changed, 1415 insertions(+), 234 deletions(-) create mode 100644 packages/editor/src/fields/PageFragmentSelect.vue create mode 100644 packages/editor/src/layouts/page-bar/AddButton.vue create mode 100644 packages/editor/src/layouts/page-bar/PageBar.vue rename packages/editor/src/layouts/{workspace => page-bar}/PageBarScrollContainer.vue (65%) create mode 100644 packages/editor/src/layouts/page-bar/SwitchTypeButton.vue delete mode 100644 packages/editor/src/layouts/workspace/PageBar.vue create mode 100644 packages/ui-react/src/page-fragment-container/index.ts create mode 100644 packages/ui-react/src/page-fragment-container/src/PageFragmentContainer.tsx create mode 100644 packages/ui-react/src/page-fragment-container/src/formConfig.ts create mode 100644 packages/ui-react/src/page-fragment-container/src/initValue.ts create mode 100644 packages/ui-react/src/page-fragment/index.ts create mode 100644 packages/ui-react/src/page-fragment/src/PageFragment.tsx create mode 100644 packages/ui-react/src/page-fragment/src/formConfig.ts create mode 100644 packages/ui-react/src/page-fragment/src/initValue.ts create mode 100644 packages/ui-vue2/src/page-fragment-container/index.ts create mode 100644 packages/ui-vue2/src/page-fragment-container/src/PageFragmentContainer.vue create mode 100644 packages/ui-vue2/src/page-fragment-container/src/formConfig.ts create mode 100644 packages/ui-vue2/src/page-fragment-container/src/initValue.ts create mode 100644 packages/ui-vue2/src/page-fragment/index.ts create mode 100644 packages/ui-vue2/src/page-fragment/src/PageFragment.vue create mode 100644 packages/ui-vue2/src/page-fragment/src/formConfig.ts create mode 100644 packages/ui-vue2/src/page-fragment/src/initValue.ts create mode 100644 packages/ui/src/page-fragment-container/index.ts create mode 100644 packages/ui/src/page-fragment-container/src/PageFragmentContainer.vue create mode 100644 packages/ui/src/page-fragment-container/src/formConfig.ts create mode 100644 packages/ui/src/page-fragment-container/src/initValue.ts create mode 100644 packages/ui/src/page-fragment/index.ts create mode 100644 packages/ui/src/page-fragment/src/PageFragment.vue create mode 100644 packages/ui/src/page-fragment/src/formConfig.ts create mode 100644 packages/ui/src/page-fragment/src/initValue.ts diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index da2ec9b4..6cbd6b38 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -20,7 +20,8 @@ import { EventEmitter } from 'events'; import { isEmpty } from 'lodash-es'; -import { DeprecatedEventConfig, EventConfig, HookType, MComponent, MContainer, MPage } from '@tmagic/schema'; +import type { DeprecatedEventConfig, EventConfig, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema'; +import { HookType } from '@tmagic/schema'; import type App from './App'; import type Page from './Page'; @@ -33,7 +34,7 @@ interface NodeOptions { app: App; } class Node extends EventEmitter { - public data: MComponent | MContainer | MPage; + public data: MComponent | MContainer | MPage | MPageFragment; public style?: { [key: string]: any; }; @@ -56,9 +57,9 @@ class Node extends EventEmitter { this.listenLifeSafe(); } - public setData(data: MComponent | MContainer | MPage) { + public setData(data: MComponent | MContainer | MPage | MPageFragment) { this.data = data; - this.emit('updata-data'); + this.emit('update-data'); } public destroy() { diff --git a/packages/core/src/Page.ts b/packages/core/src/Page.ts index 51def7aa..9dc1f7fa 100644 --- a/packages/core/src/Page.ts +++ b/packages/core/src/Page.ts @@ -16,12 +16,12 @@ * limitations under the License. */ -import type { Id, MComponent, MContainer, MPage } from '@tmagic/schema'; +import type { Id, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema'; import type App from './App'; import Node from './Node'; interface ConfigOptions { - config: MPage; + config: MPage | MPageFragment; app: App; } @@ -45,6 +45,13 @@ class Page extends Node { this.setNode(config.id, node); + if (config.type === 'page-fragment-container' && config.pageFragmentId) { + const pageFragment = this.app.dsl?.items?.find((page) => page.id === config.pageFragmentId); + if (pageFragment) { + config.items = [pageFragment]; + } + } + config.items?.forEach((element: MComponent | MContainer) => { this.initNode(element, node); }); diff --git a/packages/editor/src/Editor.vue b/packages/editor/src/Editor.vue index 76672144..ba1f5620 100644 --- a/packages/editor/src/Editor.vue +++ b/packages/editor/src/Editor.vue @@ -1,5 +1,5 @@ @@ -89,6 +87,9 @@ + + + diff --git a/packages/editor/src/editorProps.ts b/packages/editor/src/editorProps.ts index 076b3406..bd6cd550 100644 --- a/packages/editor/src/editorProps.ts +++ b/packages/editor/src/editorProps.ts @@ -72,8 +72,12 @@ export interface EditorProps { extendFormState?: (state: FormState) => Record | Promise>; /** 自定义依赖收集器,复制组件时会将关联依赖一并复制 */ collectorOptions?: CustomTargetOptions; + /** 标尺配置 */ guidesOptions?: Partial; + /** 禁止多选 */ disabledMultiSelect?: boolean; + /** 禁用页面片 */ + disabledPageFragment?: boolean; customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[]; } @@ -96,4 +100,5 @@ export const defaultEditorProps = { codeOptions: () => ({}), renderType: RenderType.IFRAME, disabledMultiSelect: false, + disabledPageFragment: false, }; diff --git a/packages/editor/src/fields/PageFragmentSelect.vue b/packages/editor/src/fields/PageFragmentSelect.vue new file mode 100644 index 00000000..dc20f195 --- /dev/null +++ b/packages/editor/src/fields/PageFragmentSelect.vue @@ -0,0 +1,55 @@ + + + diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index e8b81f7b..b36c4468 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -30,6 +30,7 @@ import DataSourceMocks from './fields/DataSourceMocks.vue'; import DataSourceSelect from './fields/DataSourceSelect.vue'; import EventSelect from './fields/EventSelect.vue'; import KeyValue from './fields/KeyValue.vue'; +import PageFragmentSelect from './fields/PageFragmentSelect.vue'; import uiSelect from './fields/UISelect.vue'; import CodeEditor from './layouts/CodeEditor.vue'; import { setConfig } from './utils/config'; @@ -79,6 +80,7 @@ export { default as LayoutContainer } from './components/SplitView.vue'; export { default as SplitView } from './components/SplitView.vue'; export { default as Resizer } from './components/Resizer.vue'; export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue'; +export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue'; const defaultInstallOpt: InstallOptions = { // eslint-disable-next-line no-eval @@ -108,5 +110,6 @@ export default { app.component('m-fields-data-source-methods', DataSourceMethods); app.component('m-fields-data-source-method-select', DataSourceMethodSelect); app.component('m-fields-data-source-field-select', DataSourceFieldSelect); + app.component('m-fields-page-fragment-select', PageFragmentSelect); }, }; diff --git a/packages/editor/src/initService.ts b/packages/editor/src/initService.ts index 4463649a..9f6734c2 100644 --- a/packages/editor/src/initService.ts +++ b/packages/editor/src/initService.ts @@ -11,7 +11,7 @@ import { DepTargetType, Target, } from '@tmagic/dep'; -import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema'; +import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { getNodes } from '@tmagic/utils'; import PropsPanel from './layouts/PropsPanel.vue'; @@ -350,7 +350,7 @@ export const initServiceEvents = ( }; // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖 - const historyChangeHandler = (page: MPage) => { + const historyChangeHandler = (page: MPage | MPageFragment) => { depService.collect([page], true); }; diff --git a/packages/editor/src/layouts/AddPageBox.vue b/packages/editor/src/layouts/AddPageBox.vue index 99f42ad7..d82f4265 100644 --- a/packages/editor/src/layouts/AddPageBox.vue +++ b/packages/editor/src/layouts/AddPageBox.vue @@ -1,12 +1,19 @@ @@ -25,9 +32,13 @@ defineOptions({ name: 'MEditorAddPageBox', }); +defineProps<{ + disabledPageFragment: boolean; +}>(); + const services = inject('services'); -const clickHandler = () => { +const clickHandler = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => { const { editorService } = services || {}; if (!editorService) return; @@ -36,8 +47,9 @@ const clickHandler = () => { if (!root) throw new Error('root 不能为空'); editorService.add({ - type: NodeType.PAGE, - name: generatePageNameByApp(root), + type, + name: generatePageNameByApp(root, type), + items: [], }); }; diff --git a/packages/editor/src/layouts/Framework.vue b/packages/editor/src/layouts/Framework.vue index bb6fce94..0df652dd 100644 --- a/packages/editor/src/layouts/Framework.vue +++ b/packages/editor/src/layouts/Framework.vue @@ -31,13 +31,18 @@ -