@tmagic/editor 1.8.0-beta.1 → 1.8.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +31 -5
- package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +21 -113
- package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/es/components/CompareForm.js +5 -0
- package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +196 -0
- package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/components/Icon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ScrollBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SearchInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SplitView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/editorProps.js +2 -0
- package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +20 -4
- package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +3 -6
- package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +19 -3
- package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +42 -8
- package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +14 -6
- package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +41 -16
- package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +9 -5
- package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +40 -19
- package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +17 -9
- package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +59 -12
- package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +12 -7
- package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +28 -6
- package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Block.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Flex.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Inline.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/InlineBlock.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/None.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Left.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Right.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +9 -6
- package/dist/es/hooks/use-code-block-edit.js +7 -4
- package/dist/es/hooks/use-data-source-edit.js +5 -2
- package/dist/es/hooks/use-stage.js +22 -10
- package/dist/es/icons/CenterIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/CodeIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/FolderMinusIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/index.js +14 -3
- package/dist/es/initService.js +7 -7
- package/dist/es/layouts/AddPageBox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +7 -6
- package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +14 -9
- package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +12 -4
- package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/Bucket.js +5 -0
- package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/es/layouts/history-list/BucketTab.js +5 -0
- package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/es/layouts/history-list/GroupRow.js +5 -0
- package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +269 -0
- package/dist/es/layouts/history-list/HistoryDiffDialog.js +5 -0
- package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +287 -0
- package/dist/es/layouts/history-list/HistoryListPanel.js +5 -0
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +327 -0
- package/dist/es/layouts/history-list/InitialRow.js +5 -0
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/es/layouts/history-list/PageTab.js +5 -0
- package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +95 -0
- package/dist/es/layouts/history-list/composables.js +184 -0
- package/dist/es/layouts/history-list/useHistoryList.js +56 -0
- package/dist/es/layouts/history-list/useHistoryRevert.js +306 -0
- package/dist/es/layouts/page-bar/AddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +5 -3
- package/dist/es/layouts/page-bar/PageBarScrollContainer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/Search.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +8 -4
- package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/sidebar/code-block/useContentMenu.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceAddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +19 -6
- package/dist/es/layouts/sidebar/data-source/DataSourceList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +25 -3
- package/dist/es/layouts/sidebar/data-source/useContentMenu.js +1 -1
- package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/layer/use-node-status.js +1 -1
- package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/workspace/viewer/StageOverlay.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/es/services/BaseService.js +31 -68
- package/dist/es/services/codeBlock.js +286 -8
- package/dist/es/services/componentList.js +2 -2
- package/dist/es/services/dataSource.js +287 -8
- package/dist/es/services/dep.js +21 -9
- package/dist/es/services/editor.js +655 -194
- package/dist/es/services/events.js +2 -2
- package/dist/es/services/history.js +390 -47
- package/dist/es/services/keybinding.js +5 -5
- package/dist/es/services/props.js +8 -8
- package/dist/es/services/stageOverlay.js +2 -2
- package/dist/es/services/storage.js +2 -2
- package/dist/es/services/ui.js +5 -2
- package/dist/es/style.css +456 -8
- package/dist/es/utils/code-block.js +122 -0
- package/dist/es/utils/content-menu.js +19 -12
- package/dist/es/utils/data-source/index.js +2 -0
- package/dist/es/utils/dep/worker.js +1 -1
- package/dist/es/utils/editor.js +105 -51
- package/dist/es/utils/history.js +220 -0
- package/dist/es/utils/indexed-db.js +86 -0
- package/dist/es/utils/undo-redo.js +80 -1
- package/dist/style.css +456 -8
- package/dist/tmagic-editor.umd.cjs +10135 -5646
- package/package.json +8 -8
- package/src/Editor.vue +25 -1
- package/src/components/CodeBlockEditor.vue +20 -109
- package/src/components/CodeParams.vue +6 -0
- package/src/components/CompareForm.vue +277 -0
- package/src/components/ToolButton.vue +2 -2
- package/src/editorProps.ts +9 -0
- package/src/fields/Code.vue +19 -3
- package/src/fields/CodeLink.vue +2 -5
- package/src/fields/CodeSelect.vue +17 -1
- package/src/fields/CodeSelectCol.vue +37 -3
- package/src/fields/DataSourceFieldSelect/FieldSelect.vue +23 -3
- package/src/fields/DataSourceFieldSelect/Index.vue +2 -2
- package/src/fields/DataSourceFields.vue +48 -10
- package/src/fields/DataSourceInput.vue +3 -3
- package/src/fields/DataSourceMethodSelect.vue +12 -4
- package/src/fields/DataSourceMethods.vue +55 -24
- package/src/fields/DataSourceMocks.vue +13 -3
- package/src/fields/DataSourceSelect.vue +4 -1
- package/src/fields/EventSelect.vue +57 -8
- package/src/fields/KeyValue.vue +17 -4
- package/src/fields/StyleSetter/components/Border.vue +15 -6
- package/src/fields/UISelect.vue +5 -2
- package/src/hooks/use-code-block-edit.ts +9 -5
- package/src/hooks/use-data-source-edit.ts +2 -2
- package/src/hooks/use-stage.ts +26 -9
- package/src/index.ts +8 -0
- package/src/initService.ts +1 -1
- package/src/layouts/CodeEditor.vue +17 -5
- package/src/layouts/Framework.vue +11 -6
- package/src/layouts/NavMenu.vue +12 -3
- package/src/layouts/history-list/Bucket.vue +91 -0
- package/src/layouts/history-list/BucketTab.vue +72 -0
- package/src/layouts/history-list/GroupRow.vue +304 -0
- package/src/layouts/history-list/HistoryDiffDialog.vue +273 -0
- package/src/layouts/history-list/HistoryListPanel.vue +367 -0
- package/src/layouts/history-list/InitialRow.vue +71 -0
- package/src/layouts/history-list/PageTab.vue +118 -0
- package/src/layouts/history-list/composables.ts +309 -0
- package/src/layouts/history-list/useHistoryList.ts +60 -0
- package/src/layouts/history-list/useHistoryRevert.ts +405 -0
- package/src/layouts/page-bar/PageBar.vue +4 -2
- package/src/layouts/props-panel/PropsPanel.vue +5 -1
- package/src/layouts/sidebar/ComponentListPanel.vue +9 -5
- package/src/layouts/sidebar/Sidebar.vue +8 -3
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -1
- package/src/layouts/sidebar/code-block/useContentMenu.ts +1 -1
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +31 -2
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +27 -2
- package/src/layouts/sidebar/data-source/useContentMenu.ts +1 -1
- package/src/layouts/sidebar/layer/LayerMenu.vue +19 -11
- package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
- package/src/layouts/sidebar/layer/use-node-status.ts +9 -6
- package/src/layouts/workspace/viewer/Stage.vue +1 -1
- package/src/layouts/workspace/viewer/ViewerMenu.vue +8 -8
- package/src/services/BaseService.ts +35 -86
- package/src/services/codeBlock.ts +361 -5
- package/src/services/dataSource.ts +336 -6
- package/src/services/dep.ts +32 -9
- package/src/services/editor.ts +834 -194
- package/src/services/history.ts +509 -49
- package/src/services/keybinding.ts +3 -3
- package/src/services/props.ts +2 -2
- package/src/services/ui.ts +7 -0
- package/src/theme/history-list-panel.scss +557 -0
- package/src/theme/page-bar.scss +0 -4
- package/src/theme/props-panel.scss +3 -3
- package/src/theme/style-setter/border.scss +4 -1
- package/src/theme/theme.scss +1 -0
- package/src/type.ts +594 -31
- package/src/utils/code-block.ts +150 -0
- package/src/utils/content-menu.ts +25 -13
- package/src/utils/data-source/index.ts +2 -0
- package/src/utils/dep/worker.ts +5 -3
- package/src/utils/editor.ts +166 -60
- package/src/utils/history.ts +286 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/indexed-db.ts +122 -0
- package/src/utils/undo-redo.ts +111 -0
- package/types/index.d.ts +3171 -889
- package/dist/es/utils/compose.js +0 -44
- package/dist/es/utils/editor-history.js +0 -100
- package/src/utils/compose.ts +0 -52
- package/src/utils/editor-history.ts +0 -138
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.8.0-beta.
|
|
2
|
+
"version": "1.8.0-beta.10",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
"moveable": "^0.53.0",
|
|
59
59
|
"serialize-javascript": "^7.0.0",
|
|
60
60
|
"sortablejs": "^1.15.6",
|
|
61
|
-
"@tmagic/design": "1.8.0-beta.
|
|
62
|
-
"@tmagic/form": "1.8.0-beta.
|
|
63
|
-
"@tmagic/
|
|
64
|
-
"@tmagic/
|
|
65
|
-
"@tmagic/
|
|
61
|
+
"@tmagic/design": "1.8.0-beta.10",
|
|
62
|
+
"@tmagic/form": "1.8.0-beta.10",
|
|
63
|
+
"@tmagic/table": "1.8.0-beta.10",
|
|
64
|
+
"@tmagic/utils": "1.8.0-beta.10",
|
|
65
|
+
"@tmagic/stage": "1.8.0-beta.10"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/events": "^3.0.3",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"monaco-editor": "^0.55.1 ",
|
|
76
76
|
"type-fest": "^5.2.0",
|
|
77
77
|
"typescript": "^6.0.3",
|
|
78
|
-
"vue": "^3.5.
|
|
79
|
-
"@tmagic/core": "1.8.0-beta.
|
|
78
|
+
"vue": "^3.5.38",
|
|
79
|
+
"@tmagic/core": "1.8.0-beta.10"
|
|
80
80
|
},
|
|
81
81
|
"peerDependenciesMeta": {
|
|
82
82
|
"typescript": {
|
package/src/Editor.vue
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
:disabled-page-fragment="disabledPageFragment"
|
|
4
4
|
:page-bar-sort-options="pageBarSortOptions"
|
|
5
5
|
:page-filter-function="pageFilterFunction"
|
|
6
|
+
:hide-sidebar="hideSidebar"
|
|
6
7
|
>
|
|
7
8
|
<template #header>
|
|
8
9
|
<slot name="header"></slot>
|
|
@@ -134,7 +135,7 @@
|
|
|
134
135
|
<script lang="ts" setup>
|
|
135
136
|
import { EventEmitter } from 'events';
|
|
136
137
|
|
|
137
|
-
import { provide } from 'vue';
|
|
138
|
+
import { provide, ref } from 'vue';
|
|
138
139
|
|
|
139
140
|
import type { MApp } from '@tmagic/core';
|
|
140
141
|
|
|
@@ -220,22 +221,45 @@ const stageOptions: StageOptions = {
|
|
|
220
221
|
guidesOptions: props.guidesOptions,
|
|
221
222
|
disabledMultiSelect: props.disabledMultiSelect,
|
|
222
223
|
alwaysMultiSelect: props.alwaysMultiSelect,
|
|
224
|
+
disabledFlashTip: props.disabledFlashTip,
|
|
223
225
|
beforeDblclick: props.beforeDblclick,
|
|
224
226
|
};
|
|
225
227
|
|
|
226
228
|
stageOverlayService.set('stageOptions', stageOptions);
|
|
227
229
|
|
|
230
|
+
const propsPanelRef = ref<InstanceType<typeof FormPanel> | null>(null);
|
|
231
|
+
|
|
228
232
|
provide('services', services);
|
|
229
233
|
|
|
230
234
|
provide('codeOptions', props.codeOptions);
|
|
231
235
|
provide('stageOptions', stageOptions);
|
|
236
|
+
/**
|
|
237
|
+
* 把顶层 `extendFormState` 提供给非 PropsPanel 链路上的组件使用(例如历史差异对话框 HistoryDiffDialog
|
|
238
|
+
* 内部的 CompareForm)。这样所有依赖业务上下文的表单 filterFunction 都能拿到一致的扩展状态,
|
|
239
|
+
* 与 PropsPanel 通过 `:extend-state` 显式传入的方式保持等价。
|
|
240
|
+
*/
|
|
241
|
+
provide('extendFormState', props.extendFormState);
|
|
242
|
+
/**
|
|
243
|
+
* 提供 PropsPanel 主属性表单的 formState getter,供历史差异弹窗复用,
|
|
244
|
+
* 让 CompareForm 与 PropsPanel 的 filterFunction 上下文保持一致。
|
|
245
|
+
*/
|
|
246
|
+
provide('getPropsPanelFormState', () => propsPanelRef.value?.configForm?.formState);
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* 把历史记录面板的自定义扩展 tab 提供给深层的 HistoryListPanel(它挂在 NavMenu 中,
|
|
250
|
+
* 以 markRaw component 形式渲染,无法直接通过 props 透传)。业务方可借此在历史记录
|
|
251
|
+
* 面板内追加自定义模块的历史 tab。
|
|
252
|
+
*/
|
|
253
|
+
provide('historyListExtraTabs', props.historyListExtraTabs);
|
|
232
254
|
|
|
233
255
|
provide<EventBus>('eventBus', new EventEmitter());
|
|
234
256
|
|
|
235
257
|
const propsPanelMountedHandler = (e: InstanceType<typeof FormPanel>) => {
|
|
258
|
+
propsPanelRef.value = e;
|
|
236
259
|
emit('props-panel-mounted', e);
|
|
237
260
|
};
|
|
238
261
|
const propsPanelUnmountedHandler = () => {
|
|
262
|
+
propsPanelRef.value = null;
|
|
239
263
|
emit('props-panel-unmounted');
|
|
240
264
|
};
|
|
241
265
|
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<Teleport to="body">
|
|
35
35
|
<TMagicDialog title="查看修改" v-model="difVisible" fullscreen destroy-on-close>
|
|
36
36
|
<div style="display: flex; margin-bottom: 10px">
|
|
37
|
-
<div style="flex: 1"><TMagicTag size="small" type="
|
|
37
|
+
<div style="flex: 1"><TMagicTag size="small" type="danger">修改前</TMagicTag></div>
|
|
38
38
|
<div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
|
|
39
39
|
</div>
|
|
40
40
|
|
|
@@ -63,14 +63,7 @@ import { computed, inject, nextTick, Ref, ref, useTemplateRef, watch } from 'vue
|
|
|
63
63
|
|
|
64
64
|
import type { CodeBlockContent } from '@tmagic/core';
|
|
65
65
|
import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
|
|
66
|
-
import {
|
|
67
|
-
type ContainerChangeEventData,
|
|
68
|
-
defineFormConfig,
|
|
69
|
-
defineFormItem,
|
|
70
|
-
type FormConfig,
|
|
71
|
-
MFormBox,
|
|
72
|
-
type TableColumnConfig,
|
|
73
|
-
} from '@tmagic/form';
|
|
66
|
+
import { type ContainerChangeEventData, type FormConfig, MFormBox } from '@tmagic/form';
|
|
74
67
|
|
|
75
68
|
import FloatingBox from '@editor/components/FloatingBox.vue';
|
|
76
69
|
import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
|
|
@@ -78,6 +71,7 @@ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-positi
|
|
|
78
71
|
import { useServices } from '@editor/hooks/use-services';
|
|
79
72
|
import { useWindowRect } from '@editor/hooks/use-window-rect';
|
|
80
73
|
import CodeEditor from '@editor/layouts/CodeEditor.vue';
|
|
74
|
+
import { getCodeBlockFormConfig } from '@editor/utils/code-block';
|
|
81
75
|
import { getEditorConfig } from '@editor/utils/config';
|
|
82
76
|
|
|
83
77
|
defineOptions({
|
|
@@ -119,106 +113,23 @@ const diffChange = () => {
|
|
|
119
113
|
difVisible.value = false;
|
|
120
114
|
};
|
|
121
115
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
label: '字符串',
|
|
140
|
-
value: 'text',
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
text: '组件',
|
|
144
|
-
label: '组件',
|
|
145
|
-
value: 'ui-select',
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
const functionConfig = computed(
|
|
153
|
-
() =>
|
|
154
|
-
defineFormConfig([
|
|
155
|
-
{
|
|
156
|
-
text: '名称',
|
|
157
|
-
name: 'name',
|
|
158
|
-
rules: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
text: '描述',
|
|
162
|
-
name: 'desc',
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
text: '执行时机',
|
|
166
|
-
name: 'timing',
|
|
167
|
-
type: 'select',
|
|
168
|
-
options: () => {
|
|
169
|
-
const options = [
|
|
170
|
-
{ text: '初始化前', value: 'beforeInit' },
|
|
171
|
-
{ text: '初始化后', value: 'afterInit' },
|
|
172
|
-
];
|
|
173
|
-
if (props.dataSourceType !== 'base') {
|
|
174
|
-
options.push({ text: '请求前', value: 'beforeRequest' });
|
|
175
|
-
options.push({ text: '请求后', value: 'afterRequest' });
|
|
176
|
-
}
|
|
177
|
-
return options;
|
|
178
|
-
},
|
|
179
|
-
display: () => props.isDataSource,
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
type: 'table',
|
|
183
|
-
border: true,
|
|
184
|
-
text: '参数',
|
|
185
|
-
enableFullscreen: false,
|
|
186
|
-
enableToggleMode: false,
|
|
187
|
-
name: 'params',
|
|
188
|
-
dropSort: false,
|
|
189
|
-
items: [
|
|
190
|
-
{
|
|
191
|
-
type: 'text',
|
|
192
|
-
label: '参数名',
|
|
193
|
-
name: 'name',
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
type: 'text',
|
|
197
|
-
label: '描述',
|
|
198
|
-
name: 'extra',
|
|
199
|
-
},
|
|
200
|
-
codeBlockService.getParamsColConfig() || defaultParamColConfig,
|
|
201
|
-
],
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: 'content',
|
|
205
|
-
type: 'vs-code',
|
|
206
|
-
options: inject('codeOptions', {}),
|
|
207
|
-
autosize: { minRows: 10, maxRows: 30 },
|
|
208
|
-
onChange: (_formState, code: string) => {
|
|
209
|
-
try {
|
|
210
|
-
// 检测js代码是否存在语法错误
|
|
211
|
-
getEditorConfig('parseDSL')(code);
|
|
212
|
-
|
|
213
|
-
return code;
|
|
214
|
-
} catch (error: any) {
|
|
215
|
-
tMagicMessage.error(error.message);
|
|
216
|
-
|
|
217
|
-
throw error;
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
]) as FormConfig,
|
|
116
|
+
const codeOptions = inject<Record<string, any>>('codeOptions', {});
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 代码块编辑表单配置。统一委托到 utils/code-block 的 `getCodeBlockFormConfig`,
|
|
120
|
+
* 与 CompareForm 等其它使用方共享同一份 schema,避免双份维护。
|
|
121
|
+
*
|
|
122
|
+
* 这里以 computed 包裹是为了让 `props.isDataSource` / `props.dataSourceType` 变化时
|
|
123
|
+
* "执行时机"字段的可见性与可选项实时刷新。
|
|
124
|
+
*/
|
|
125
|
+
const functionConfig = computed<FormConfig>(() =>
|
|
126
|
+
getCodeBlockFormConfig({
|
|
127
|
+
paramColConfig: codeBlockService.getParamsColConfig(),
|
|
128
|
+
isDataSource: () => Boolean(props.isDataSource),
|
|
129
|
+
dataSourceType: () => props.dataSourceType,
|
|
130
|
+
codeOptions,
|
|
131
|
+
editable: true,
|
|
132
|
+
}),
|
|
222
133
|
);
|
|
223
134
|
|
|
224
135
|
const parseContent = (content: any) => {
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
ref="form"
|
|
4
4
|
:config="codeParamsConfig"
|
|
5
5
|
:init-values="model"
|
|
6
|
+
:last-values="lastValues"
|
|
7
|
+
:is-compare="isCompare"
|
|
6
8
|
:disabled="disabled"
|
|
7
9
|
:size="size"
|
|
8
10
|
:watch-props="false"
|
|
@@ -24,6 +26,10 @@ defineOptions({
|
|
|
24
26
|
|
|
25
27
|
const props = defineProps<{
|
|
26
28
|
model: any;
|
|
29
|
+
/** 对比模式下的历史值,透传给内部 MForm 用于逐项展示参数差异 */
|
|
30
|
+
lastValues?: any;
|
|
31
|
+
/** 是否开启对比模式 */
|
|
32
|
+
isCompare?: boolean;
|
|
27
33
|
size?: 'small' | 'default' | 'large';
|
|
28
34
|
disabled?: boolean;
|
|
29
35
|
name: string;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-compare-form-wrapper" :style="wrapperStyle">
|
|
3
|
+
<MForm
|
|
4
|
+
v-if="config.length"
|
|
5
|
+
ref="form"
|
|
6
|
+
class="m-editor-compare-form"
|
|
7
|
+
:config="config"
|
|
8
|
+
:init-values="currentValues"
|
|
9
|
+
:last-values="lastValuesProcessed"
|
|
10
|
+
:is-compare="true"
|
|
11
|
+
:disabled="true"
|
|
12
|
+
:label-width="labelWidth"
|
|
13
|
+
:extend-state="mergedExtendState"
|
|
14
|
+
:show-diff="showDiff"
|
|
15
|
+
:self-diff-field-types="selfDiffFieldTypes"
|
|
16
|
+
></MForm>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script lang="ts" setup>
|
|
21
|
+
import { computed, inject, provide, type Ref, ref, type ShallowRef, useTemplateRef, watch, watchEffect } from 'vue';
|
|
22
|
+
import { isEqual } from 'lodash-es';
|
|
23
|
+
|
|
24
|
+
import { type CodeBlockContent, type DataSourceSchema, HookType, type MNode } from '@tmagic/core';
|
|
25
|
+
import { type FormConfig, type FormState, type FormValue, MForm } from '@tmagic/form';
|
|
26
|
+
|
|
27
|
+
import type { CompareCategory, CompareFormLoadConfig, Services } from '@editor/type';
|
|
28
|
+
import { getCodeBlockFormConfig } from '@editor/utils/code-block';
|
|
29
|
+
|
|
30
|
+
defineOptions({
|
|
31
|
+
name: 'MEditorCompareForm',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const props = withDefaults(
|
|
35
|
+
defineProps<{
|
|
36
|
+
/** 当前值(修改后的值) */
|
|
37
|
+
value: Partial<MNode> | Partial<DataSourceSchema> | Partial<CodeBlockContent> | Record<string, any>;
|
|
38
|
+
/** 用于对比的旧值(修改前的值) */
|
|
39
|
+
lastValue?: Partial<MNode> | Partial<DataSourceSchema> | Partial<CodeBlockContent> | Record<string, any>;
|
|
40
|
+
/**
|
|
41
|
+
* 类型说明:
|
|
42
|
+
* - `category` 为 `node` 时,`type` 为节点组件的类型,例如 'text'、'button'、'page'、'container' 等
|
|
43
|
+
* - `category` 为 `data-source` 时,`type` 为数据源类型,例如 'base'、'http'
|
|
44
|
+
* - `category` 为 `code-block` 时,`type` 可不传
|
|
45
|
+
*/
|
|
46
|
+
type?: string;
|
|
47
|
+
/** 表单配置类别,决定从哪里取 FormConfig */
|
|
48
|
+
category?: CompareCategory;
|
|
49
|
+
/** 数据源代码块场景下的数据源类型(base/http),用于代码块表单中"执行时机"展示 */
|
|
50
|
+
dataSourceType?: string;
|
|
51
|
+
labelWidth?: string;
|
|
52
|
+
/**
|
|
53
|
+
* 外层容器高度。设置后表单内容超出时会在 CompareForm 内部出现滚动条,
|
|
54
|
+
* 避免 dialog / 面板使用方需要自行处理滚动。可传任意 CSS 长度,例如 `60vh` / `400px` / `100%`。
|
|
55
|
+
*/
|
|
56
|
+
height?: string;
|
|
57
|
+
/**
|
|
58
|
+
* 用户自定义注入到 MForm.formState 的扩展字段,与 Editor 顶层的 `extendFormState`、
|
|
59
|
+
* PropsPanel 的 `extend-state` 语义一致。表单 item 的 `display` / `disabled` 等
|
|
60
|
+
* filterFunction 经常依赖这里注入的字段(如 stage、自定义业务上下文等),
|
|
61
|
+
* 因此在差异对比场景下也需要透传,避免出现 `formState.xxx is undefined` 的运行时错误。
|
|
62
|
+
*/
|
|
63
|
+
extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
64
|
+
/**
|
|
65
|
+
* 外部透传的基础 formState(通常来自 PropsPanel 主属性表单)。
|
|
66
|
+
* CompareForm 会提取其中的扩展字段覆盖到自己的 formState,保证 filterFunction 上下文一致。
|
|
67
|
+
*/
|
|
68
|
+
baseFormState?: FormState;
|
|
69
|
+
/** 需要走 self diff 的字段类型(例如 mod-cond)。 */
|
|
70
|
+
selfDiffFieldTypes?: string[];
|
|
71
|
+
/**
|
|
72
|
+
* 自定义 FormConfig 加载逻辑。传入后将接管内置的按 `category`(node/data-source/code-block)
|
|
73
|
+
* 取配置逻辑,调用方可根据业务自行返回(或异步返回)表单配置。可通过
|
|
74
|
+
* `ctx.defaultLoadConfig()` 复用默认结果再做二次加工。返回的 config 直接用于对比展示。
|
|
75
|
+
*/
|
|
76
|
+
loadConfig?: CompareFormLoadConfig;
|
|
77
|
+
/** 编辑器服务集合,由调用方传入(不再通过 inject('services') 获取)。 */
|
|
78
|
+
services?: Services;
|
|
79
|
+
}>(),
|
|
80
|
+
{
|
|
81
|
+
category: 'node',
|
|
82
|
+
labelWidth: '120px',
|
|
83
|
+
extendState: (state: FormState) => state,
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
provide('services', props.services);
|
|
88
|
+
|
|
89
|
+
const config = ref<FormConfig>([]);
|
|
90
|
+
|
|
91
|
+
/** vs-code 编辑器的 monaco 配置项,沿用 Editor 顶层 provide('codeOptions', ...) 的注入。 */
|
|
92
|
+
const codeOptions = inject<Record<string, any>>('codeOptions', {});
|
|
93
|
+
|
|
94
|
+
/** 将代码块的 content 字段统一成字符串,便于在表单/对比中展示 */
|
|
95
|
+
const normalizeCodeBlockValue = (
|
|
96
|
+
v: Partial<CodeBlockContent> | Record<string, any> | undefined,
|
|
97
|
+
): Record<string, any> => {
|
|
98
|
+
if (!v) return {};
|
|
99
|
+
const next: Record<string, any> = { ...v };
|
|
100
|
+
if (next.content && typeof next.content !== 'string') {
|
|
101
|
+
try {
|
|
102
|
+
next.content = next.content.toString();
|
|
103
|
+
} catch {
|
|
104
|
+
next.content = '';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return next;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const currentValues = computed<FormValue>(() => {
|
|
111
|
+
if (props.category === 'code-block') {
|
|
112
|
+
return normalizeCodeBlockValue(props.value as Partial<CodeBlockContent>);
|
|
113
|
+
}
|
|
114
|
+
return (props.value || {}) as FormValue;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const lastValuesProcessed = computed<FormValue>(() => {
|
|
118
|
+
if (props.category === 'code-block') {
|
|
119
|
+
return normalizeCodeBlockValue(props.lastValue as Partial<CodeBlockContent>);
|
|
120
|
+
}
|
|
121
|
+
return (props.lastValue || {}) as FormValue;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 外层包裹层的样式:当传入 `height` 时启用固定高度 + 内部滚动,
|
|
126
|
+
* 这样滚动条会出现在 CompareForm 内部,避免父容器(如 Dialog)自身也产生滚动。
|
|
127
|
+
*/
|
|
128
|
+
const wrapperStyle = computed(() => {
|
|
129
|
+
if (!props.height) return undefined;
|
|
130
|
+
return {
|
|
131
|
+
height: props.height,
|
|
132
|
+
overflow: 'auto',
|
|
133
|
+
} as Record<string, string>;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* `code-select` 字段在历史数据中存在两种"语义为空"的形态:
|
|
138
|
+
* - 字符串 `''`(旧数据 / 用户从未配置过钩子);
|
|
139
|
+
* - `{ hookType: HookType.CODE, hookData: [] }`(CodeSelect.vue 在挂载时
|
|
140
|
+
* 写入的默认结构,参见 packages/editor/src/fields/CodeSelect.vue 中
|
|
141
|
+
* `props.model[props.name] = { hookType: HookType.CODE, hookData: [] }`)。
|
|
142
|
+
*
|
|
143
|
+
* 直接 `isEqual` 会把两者判为不等,从而在历史对比里对每个未配置过钩子的组件
|
|
144
|
+
* 都展示一份"差异",体验很糟糕。这里把它们视为相等,跳过对比。
|
|
145
|
+
*
|
|
146
|
+
* 其它类型字段沿用 MForm/Container 的默认 `!isEqual` 判断逻辑。
|
|
147
|
+
*/
|
|
148
|
+
const isEmptyCodeSelectValue = (v: any): boolean => {
|
|
149
|
+
if (v === '' || v === undefined || v === null) return true;
|
|
150
|
+
if (Array.isArray(v) && v.length === 0) return true;
|
|
151
|
+
return typeof v === 'object' && v.hookType === HookType.CODE && Array.isArray(v.hookData) && v.hookData.length === 0;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const showDiff = ({ curValue, lastValue, config }: { curValue: any; lastValue: any; config: any }) => {
|
|
155
|
+
if (config?.type === 'code-select') {
|
|
156
|
+
// 双方都是"空形态",视为相等,不展示对比
|
|
157
|
+
if (isEmptyCodeSelectValue(curValue) && isEmptyCodeSelectValue(lastValue)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return !isEqual(curValue, lastValue);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const removeStyleDisplayConfig = (formConfig: FormConfig): FormConfig =>
|
|
165
|
+
formConfig.map((item) => {
|
|
166
|
+
if (!('type' in item)) return item;
|
|
167
|
+
if (item?.type !== 'tab' || !Array.isArray(item.items)) return item;
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
...item,
|
|
171
|
+
items: item.items.map((tabPane) => {
|
|
172
|
+
if (tabPane?.title !== '样式' || !Array.isArray(tabPane.items)) return tabPane;
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
...tabPane,
|
|
176
|
+
display: true,
|
|
177
|
+
};
|
|
178
|
+
}),
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const mergedExtendState = (state: FormState) => {
|
|
183
|
+
return props.extendState(props.baseFormState || state);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 内置的默认 FormConfig 加载逻辑:按 `category` 从对应 service / 工具取配置。
|
|
188
|
+
* 作为 ctx.defaultLoadConfig 透传给自定义 `loadConfig`,方便复用与二次加工。
|
|
189
|
+
*/
|
|
190
|
+
const defaultLoadConfig = async (): Promise<FormConfig> => {
|
|
191
|
+
if (!props.services) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
switch (props.category) {
|
|
196
|
+
case 'node': {
|
|
197
|
+
if (!props.type) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
return removeStyleDisplayConfig(
|
|
201
|
+
await props.services.propsService.getPropsConfig(props.type, { node: props.value as unknown as MNode }),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
case 'data-source': {
|
|
205
|
+
const config = props.services.dataSourceService.getFormConfig(props.type || 'base');
|
|
206
|
+
// 数据源表单外层 tab 的「数据定义」项 status 为 'fields',tab-pane name 随之为 'fields'。
|
|
207
|
+
// 未显式设置 active 时,Tabs 默认取 '0',与 'fields' 不匹配会导致打开弹窗时无默认激活项,
|
|
208
|
+
// 这里与 DataSourceConfigPanel 保持一致,默认激活「数据定义」tab。
|
|
209
|
+
return config.map((item) => ('type' in item && item.type === 'tab' ? { ...item, active: 'fields' } : item));
|
|
210
|
+
}
|
|
211
|
+
case 'code-block': {
|
|
212
|
+
return getCodeBlockFormConfig({
|
|
213
|
+
paramColConfig: props.services.codeBlockService.getParamsColConfig(),
|
|
214
|
+
// 通过传入 dataSourceType 间接表达"是数据源代码块"——在对比场景下 props.dataSourceType
|
|
215
|
+
// 由调用方按 step 上下文显式传入,未传则视为普通代码块,「执行时机」字段隐藏。
|
|
216
|
+
isDataSource: () => Boolean(props.dataSourceType),
|
|
217
|
+
dataSourceType: () => props.dataSourceType,
|
|
218
|
+
codeOptions,
|
|
219
|
+
// 对比模式只读,不需要校验/语法检查
|
|
220
|
+
editable: false,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
default:
|
|
224
|
+
return [];
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const loadConfig = async () => {
|
|
229
|
+
if (props.loadConfig) {
|
|
230
|
+
config.value = await props.loadConfig({
|
|
231
|
+
category: props.category,
|
|
232
|
+
type: props.type,
|
|
233
|
+
dataSourceType: props.dataSourceType,
|
|
234
|
+
defaultLoadConfig,
|
|
235
|
+
});
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
config.value = await defaultLoadConfig();
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
watch(
|
|
243
|
+
[() => props.category, () => props.type, () => props.dataSourceType, () => props.loadConfig],
|
|
244
|
+
() => {
|
|
245
|
+
loadConfig();
|
|
246
|
+
},
|
|
247
|
+
{ immediate: true },
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const formRef = useTemplateRef<InstanceType<typeof MForm>>('form');
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 把 services / stage 注入 MForm 的 formState,避免 propsService 注入的表单配置中
|
|
254
|
+
* 形如 `display: ({ services }) => services.uiService.get(...)` 的 filterFunction
|
|
255
|
+
* 在执行时拿不到 `formState.services` 而报错。
|
|
256
|
+
*
|
|
257
|
+
* 与 props-panel/FormPanel.vue 中的注入方式保持一致:
|
|
258
|
+
* - services:整个 useServices() 返回的服务集合;
|
|
259
|
+
* - stage:当前 editorService.get('stage') 的最新值。
|
|
260
|
+
*/
|
|
261
|
+
watchEffect(() => {
|
|
262
|
+
if (formRef.value && props.services) {
|
|
263
|
+
formRef.value.formState.stage = props.services.editorService.get('stage');
|
|
264
|
+
formRef.value.formState.services = props.services;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
defineExpose<{
|
|
269
|
+
form: ShallowRef<InstanceType<typeof MForm> | null>;
|
|
270
|
+
config: Ref<FormConfig>;
|
|
271
|
+
reload: () => Promise<void>;
|
|
272
|
+
}>({
|
|
273
|
+
form: formRef,
|
|
274
|
+
config,
|
|
275
|
+
reload: loadConfig,
|
|
276
|
+
});
|
|
277
|
+
</script>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<template v-else-if="data.type === 'button'">
|
|
15
15
|
<TMagicTooltip v-if="data.tooltip" effect="dark" placement="bottom-start" :content="data.tooltip">
|
|
16
|
-
<TMagicButton size="small" link :disabled="disabled">
|
|
16
|
+
<TMagicButton size="small" link :disabled="disabled" v-bind="data.buttonProps || {}">
|
|
17
17
|
<template #icon v-if="data.icon">
|
|
18
18
|
<MIcon :icon="data.icon"></MIcon>
|
|
19
19
|
</template>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
</TMagicButton>
|
|
22
22
|
</TMagicTooltip>
|
|
23
23
|
|
|
24
|
-
<TMagicButton v-else size="small" link :disabled="disabled" :title="data.text">
|
|
24
|
+
<TMagicButton v-else size="small" link :disabled="disabled" :title="data.text" v-bind="data.buttonProps || {}">
|
|
25
25
|
<template #icon v-if="data.icon">
|
|
26
26
|
<MIcon :icon="data.icon"></MIcon>
|
|
27
27
|
</template>
|
package/src/editorProps.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
ComponentGroup,
|
|
16
16
|
CustomContentMenuFunction,
|
|
17
17
|
DatasourceTypeOption,
|
|
18
|
+
HistoryListExtraTab,
|
|
18
19
|
IsExpandableFunction,
|
|
19
20
|
MenuBarData,
|
|
20
21
|
MenuButton,
|
|
@@ -34,6 +35,8 @@ export interface EditorProps {
|
|
|
34
35
|
datasourceList?: DatasourceTypeOption[];
|
|
35
36
|
/** 左侧面板配置 */
|
|
36
37
|
sidebar?: SideBarData;
|
|
38
|
+
/** 是否隐藏左侧面板 */
|
|
39
|
+
hideSidebar?: boolean;
|
|
37
40
|
/** 顶部工具栏配置 */
|
|
38
41
|
menu?: MenuBarData;
|
|
39
42
|
/** 组件树右键菜单 */
|
|
@@ -84,6 +87,8 @@ export interface EditorProps {
|
|
|
84
87
|
alwaysMultiSelect?: boolean;
|
|
85
88
|
/** 禁用页面片 */
|
|
86
89
|
disabledPageFragment?: boolean;
|
|
90
|
+
/** 禁用「非点击画布选中组件时(如从图层树、面包屑等外部选中),对选中区域做高亮闪烁提示」,默认 false(即默认开启闪烁) */
|
|
91
|
+
disabledFlashTip?: boolean;
|
|
87
92
|
/** 禁用双击在浮层中单独编辑选中组件 */
|
|
88
93
|
disabledStageOverlay?: boolean;
|
|
89
94
|
/** 禁用属性配置面板右下角显示源码的按钮 */
|
|
@@ -123,6 +128,8 @@ export interface EditorProps {
|
|
|
123
128
|
/** 组件树节点双击前的钩子函数,返回 false 则阻止默认的双击行为 */
|
|
124
129
|
beforeLayerNodeDblclick?: (event: MouseEvent, data: TreeNodeData) => Promise<boolean | void> | boolean | void;
|
|
125
130
|
extendFormState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
131
|
+
/** 历史记录面板的自定义扩展 tab,追加在内置的页面/数据源/代码块 tab 之后 */
|
|
132
|
+
historyListExtraTabs?: HistoryListExtraTab[];
|
|
126
133
|
/** 页面顺序拖拽配置参数 */
|
|
127
134
|
pageBarSortOptions?: PageBarSortOptions;
|
|
128
135
|
/** 页面搜索函数 */
|
|
@@ -134,6 +141,7 @@ export const defaultEditorProps = {
|
|
|
134
141
|
disabledMultiSelect: false,
|
|
135
142
|
alwaysMultiSelect: false,
|
|
136
143
|
disabledPageFragment: false,
|
|
144
|
+
disabledFlashTip: false,
|
|
137
145
|
disabledStageOverlay: false,
|
|
138
146
|
containerHighlightClassName: CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
139
147
|
containerHighlightDuration: 800,
|
|
@@ -143,6 +151,7 @@ export const defaultEditorProps = {
|
|
|
143
151
|
disabledCodeBlock: false,
|
|
144
152
|
componentGroupList: () => [],
|
|
145
153
|
datasourceList: () => [],
|
|
154
|
+
historyListExtraTabs: () => [],
|
|
146
155
|
menu: () => ({ left: [], right: [] }),
|
|
147
156
|
layerContentMenu: () => [],
|
|
148
157
|
stageContentMenu: () => [],
|
package/src/fields/Code.vue
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<MagicCodeEditor
|
|
3
3
|
:height="config.height"
|
|
4
|
-
:
|
|
4
|
+
:type="diffMode ? 'diff' : undefined"
|
|
5
|
+
:init-values="diffMode ? (lastValues || {})[name] : model[name]"
|
|
6
|
+
:modified-values="diffMode ? model[name] : undefined"
|
|
5
7
|
:language="config.language"
|
|
6
8
|
:options="{
|
|
7
9
|
...config.options,
|
|
8
|
-
readOnly: disabled,
|
|
10
|
+
readOnly: diffMode ? true : disabled,
|
|
9
11
|
}"
|
|
10
12
|
:autosize="config.autosize"
|
|
11
13
|
:parse="config.parse"
|
|
@@ -15,6 +17,8 @@
|
|
|
15
17
|
</template>
|
|
16
18
|
|
|
17
19
|
<script lang="ts" setup>
|
|
20
|
+
import { computed } from 'vue';
|
|
21
|
+
|
|
18
22
|
import type { CodeConfig, FieldProps } from '@tmagic/form';
|
|
19
23
|
|
|
20
24
|
import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
|
|
@@ -27,10 +31,22 @@ const emit = defineEmits<{
|
|
|
27
31
|
change: [value: string | any];
|
|
28
32
|
}>();
|
|
29
33
|
|
|
30
|
-
withDefaults(defineProps<FieldProps<CodeConfig>>(), {
|
|
34
|
+
const props = withDefaults(defineProps<FieldProps<CodeConfig>>(), {
|
|
31
35
|
disabled: false,
|
|
32
36
|
});
|
|
33
37
|
|
|
38
|
+
/**
|
|
39
|
+
* 对比模式判定:
|
|
40
|
+
*
|
|
41
|
+
* - 当 `isCompare === true` 时,由父级 `MFormContainer` 统一渲染一次本字段(不再渲染前后两份独立组件),
|
|
42
|
+
* 并把 `model`(当前值)与 `lastValues`(历史值)一并传入;
|
|
43
|
+
* - 此时本字段切换到 monaco 自带的 diff 编辑器(左侧旧、右侧新),相比"两个独立 monaco 实例"更直观,
|
|
44
|
+
* 也避免了同一表单内重复实例化重型编辑器带来的开销。
|
|
45
|
+
*
|
|
46
|
+
* 仅当存在历史值(lastValues)且开启了对比模式时启用 diff,避免在 lastValues 缺失时退化为空对比。
|
|
47
|
+
*/
|
|
48
|
+
const diffMode = computed(() => Boolean(props.isCompare && props.lastValues));
|
|
49
|
+
|
|
34
50
|
const save = (v: string | any) => {
|
|
35
51
|
emit('change', v);
|
|
36
52
|
};
|