@tmagic/editor 1.8.0-beta.1 → 1.8.0-beta.11
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 +294 -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 +313 -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 +11149 -6646
- 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 +281 -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 +421 -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 +613 -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 +3197 -896
- 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/src/fields/CodeLink.vue
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts" setup>
|
|
6
6
|
import { computed, reactive, watch } from 'vue';
|
|
7
|
-
import serialize from 'serialize-javascript';
|
|
8
7
|
|
|
9
8
|
import type { CodeLinkConfig, FieldProps, MLink } from '@tmagic/form';
|
|
10
9
|
|
|
11
10
|
import { getEditorConfig } from '@editor/utils/config';
|
|
11
|
+
import { serializeConfig } from '@editor/utils/editor';
|
|
12
12
|
|
|
13
13
|
defineOptions({
|
|
14
14
|
name: 'MFieldsCodeLink',
|
|
@@ -47,10 +47,7 @@ watch(
|
|
|
47
47
|
() => props.model[props.name],
|
|
48
48
|
(value) => {
|
|
49
49
|
modelValue.form = {
|
|
50
|
-
[props.name]:
|
|
51
|
-
space: 2,
|
|
52
|
-
unsafe: true,
|
|
53
|
-
}).replace(/"(\w+)":\s/g, '$1: '),
|
|
50
|
+
[props.name]: serializeConfig(value),
|
|
54
51
|
};
|
|
55
52
|
},
|
|
56
53
|
{
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
:size="size"
|
|
7
7
|
:prop="prop"
|
|
8
8
|
:disabled="disabled"
|
|
9
|
-
:
|
|
9
|
+
:is-compare="isCompareMode"
|
|
10
|
+
:last-values="lastValues?.[name]"
|
|
10
11
|
:model="model[name]"
|
|
11
12
|
@change="changeHandler"
|
|
12
13
|
>
|
|
@@ -38,6 +39,21 @@ const { dataSourceService, codeBlockService } = useServices();
|
|
|
38
39
|
|
|
39
40
|
const props = withDefaults(defineProps<FieldProps<CodeSelectConfig>>(), {});
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* 对比模式判定:
|
|
44
|
+
*
|
|
45
|
+
* code-select 仅是对内部「钩子列表」group-list 的包裹,本身不渲染叶子字段。父级 `MFormContainer`
|
|
46
|
+
* 已将其归入「自接管对比字段」(见 Container.vue 的 `SELF_DIFF_FIELD_TYPES`),即对比时只渲染一次
|
|
47
|
+
* 本组件,并把当前值 `model` 与历史值 `lastValues` 一并传入,由本组件把 `is-compare`/`lastValues`
|
|
48
|
+
* 透传给内部 MContainer,再由 group-list / code-select-col 等子级逐项展示前后差异。
|
|
49
|
+
*
|
|
50
|
+
* 注意:`model` 传入的是 `model[name]`(钩子值本身),因此 `lastValues` 也必须同层取 `lastValues[name]`,
|
|
51
|
+
* 否则前后值的嵌套层级不一致会导致对比错位。
|
|
52
|
+
*
|
|
53
|
+
* 仅当存在历史值时才启用对比,避免 lastValues 缺失时退化为「全部新增」的空对比。
|
|
54
|
+
*/
|
|
55
|
+
const isCompareMode = computed(() => Boolean(props.isCompare && props.lastValues));
|
|
56
|
+
|
|
41
57
|
const codeConfig = computed<GroupListConfig>(() => ({
|
|
42
58
|
type: 'group-list',
|
|
43
59
|
name: 'hookData',
|
|
@@ -2,7 +2,20 @@
|
|
|
2
2
|
<div class="m-fields-code-select-col">
|
|
3
3
|
<div class="code-select-container">
|
|
4
4
|
<!-- 代码块下拉框 -->
|
|
5
|
+
<!-- 对比模式下交由 MFormContainer 展示下拉框的前后差异(codeId 变化时高亮新旧代码块名),
|
|
6
|
+
普通模式仍直接渲染 MSelect 以保留选择 / 写值逻辑 -->
|
|
7
|
+
<MFormContainer
|
|
8
|
+
v-if="isCompareMode"
|
|
9
|
+
class="select"
|
|
10
|
+
:config="selectConfig"
|
|
11
|
+
:model="model"
|
|
12
|
+
:last-values="lastValues"
|
|
13
|
+
:is-compare="true"
|
|
14
|
+
:size="size"
|
|
15
|
+
:prop="prop"
|
|
16
|
+
></MFormContainer>
|
|
5
17
|
<MSelect
|
|
18
|
+
v-else
|
|
6
19
|
class="select"
|
|
7
20
|
:config="selectConfig"
|
|
8
21
|
:name="name"
|
|
@@ -12,9 +25,9 @@
|
|
|
12
25
|
@change="onCodeIdChangeHandler"
|
|
13
26
|
></MSelect>
|
|
14
27
|
|
|
15
|
-
<!--
|
|
28
|
+
<!-- 查看/编辑按钮:对比模式为只读,不展示 -->
|
|
16
29
|
<TMagicButton
|
|
17
|
-
v-if="model[name] && hasCodeBlockSidePanel"
|
|
30
|
+
v-if="!isCompareMode && model[name] && hasCodeBlockSidePanel"
|
|
18
31
|
class="m-fields-select-action-button"
|
|
19
32
|
:size="size"
|
|
20
33
|
@click="editCode(model[name])"
|
|
@@ -29,6 +42,8 @@
|
|
|
29
42
|
name="params"
|
|
30
43
|
:key="model[name]"
|
|
31
44
|
:model="model"
|
|
45
|
+
:last-values="lastValues"
|
|
46
|
+
:is-compare="isCompareMode"
|
|
32
47
|
:size="size"
|
|
33
48
|
:disabled="disabled"
|
|
34
49
|
:params-config="paramsConfig"
|
|
@@ -52,6 +67,7 @@ import {
|
|
|
52
67
|
filterFunction,
|
|
53
68
|
type FormItemConfig,
|
|
54
69
|
type FormState,
|
|
70
|
+
MContainer as MFormContainer,
|
|
55
71
|
MSelect,
|
|
56
72
|
type SelectConfig,
|
|
57
73
|
} from '@tmagic/form';
|
|
@@ -77,12 +93,26 @@ const props = withDefaults(defineProps<FieldProps<CodeSelectColConfig>>(), {
|
|
|
77
93
|
disabled: false,
|
|
78
94
|
});
|
|
79
95
|
|
|
96
|
+
/**
|
|
97
|
+
* 对比模式判定:
|
|
98
|
+
*
|
|
99
|
+
* code-select-col 由「代码块下拉框 + 参数子表单」组成,属于复合字段。父级 `MFormContainer` 已将其
|
|
100
|
+
* 归入「自接管对比字段」(见 Container.vue 的 `SELF_DIFF_FIELD_TYPES`),即对比时只渲染一次本组件,
|
|
101
|
+
* 并把当前值 `model` 与历史值 `lastValues` 一并传入,由本组件把 `is-compare`/`lastValues` 透传给
|
|
102
|
+
* 内部的下拉框(MFormContainer)与参数表单(CodeParams),逐项展示前后差异。
|
|
103
|
+
*
|
|
104
|
+
* 仅当存在历史值时才启用对比,避免 lastValues 缺失时退化为「全部新增」的空对比。
|
|
105
|
+
*/
|
|
106
|
+
const isCompareMode = computed(() => Boolean(props.isCompare && props.lastValues));
|
|
107
|
+
|
|
80
108
|
const notEditable = computed(() => filterFunction(mForm, props.config.notEditable, props));
|
|
81
109
|
|
|
82
|
-
const
|
|
110
|
+
const codeBlockSidePanel = computed(() =>
|
|
83
111
|
(uiService.get('sideBarItems') || []).find((item) => item.$key === SideItemKey.CODE_BLOCK),
|
|
84
112
|
);
|
|
85
113
|
|
|
114
|
+
const hasCodeBlockSidePanel = computed(() => codeBlockSidePanel.value);
|
|
115
|
+
|
|
86
116
|
/**
|
|
87
117
|
* 根据代码块id获取代码块参数配置
|
|
88
118
|
* @param codeId 代码块ID
|
|
@@ -163,6 +193,10 @@ const onParamsChangeHandler = (value: any, eventData: ContainerChangeEventData)
|
|
|
163
193
|
};
|
|
164
194
|
|
|
165
195
|
const editCode = (id: string) => {
|
|
196
|
+
const sideBarItem = codeBlockSidePanel.value;
|
|
197
|
+
if (sideBarItem) {
|
|
198
|
+
uiService.set('sideBarActiveTabName', sideBarItem.text || sideBarItem.$key || SideItemKey.CODE_BLOCK);
|
|
199
|
+
}
|
|
166
200
|
eventBus?.emit('edit-code', id);
|
|
167
201
|
};
|
|
168
202
|
</script>
|
|
@@ -72,7 +72,10 @@
|
|
|
72
72
|
@change="onChangeHandler"
|
|
73
73
|
></TMagicCascader>
|
|
74
74
|
|
|
75
|
-
<TMagicTooltip
|
|
75
|
+
<TMagicTooltip
|
|
76
|
+
v-if="selectDataSourceId && hasDataSourceSidePanel && !isCompare"
|
|
77
|
+
:content="notEditable ? '查看' : '编辑'"
|
|
78
|
+
>
|
|
76
79
|
<TMagicButton class="m-fields-select-action-button" :size="size" @click="editHandler(selectDataSourceId)"
|
|
77
80
|
><MIcon :icon="!notEditable ? Edit : View"></MIcon
|
|
78
81
|
></TMagicButton>
|
|
@@ -133,6 +136,9 @@ const dataSources = computed(() => {
|
|
|
133
136
|
const valueIsKey = computed(() => props.value === 'key');
|
|
134
137
|
const notEditable = computed(() => filterFunction(mForm, props.notEditable, props));
|
|
135
138
|
|
|
139
|
+
/** 对比模式下隐藏查看/编辑操作按钮,仅保留只读展示。 */
|
|
140
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
141
|
+
|
|
136
142
|
const dataSourcesOptions = computed<SelectOption[]>(() =>
|
|
137
143
|
dataSources.value.map((ds) => ({
|
|
138
144
|
text: ds.title || ds.id,
|
|
@@ -205,11 +211,25 @@ const onChangeHandler = (v: string[] = []) => {
|
|
|
205
211
|
emit('change', v);
|
|
206
212
|
};
|
|
207
213
|
|
|
208
|
-
const
|
|
214
|
+
const dataSourceSidePanel = computed(() =>
|
|
209
215
|
uiService.get('sideBarItems').find((item) => item.$key === SideItemKey.DATA_SOURCE),
|
|
210
216
|
);
|
|
211
217
|
|
|
218
|
+
const hasDataSourceSidePanel = computed(() => dataSourceSidePanel.value);
|
|
219
|
+
|
|
212
220
|
const editHandler = (id: string) => {
|
|
213
|
-
|
|
221
|
+
const sideBarItem = dataSourceSidePanel.value;
|
|
222
|
+
if (sideBarItem) {
|
|
223
|
+
uiService.set('sideBarActiveTabName', sideBarItem.text || sideBarItem.$key || SideItemKey.DATA_SOURCE);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const dataSourceId = removeDataSourceFieldPrefix(id);
|
|
227
|
+
const fieldPath = selectFieldsId.value;
|
|
228
|
+
|
|
229
|
+
if (fieldPath.length) {
|
|
230
|
+
eventBus?.emit('edit-data-source-field', dataSourceId, [...fieldPath]);
|
|
231
|
+
} else {
|
|
232
|
+
eventBus?.emit('edit-data-source', dataSourceId);
|
|
233
|
+
}
|
|
214
234
|
};
|
|
215
235
|
</script>
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
></component>
|
|
29
29
|
|
|
30
30
|
<TMagicTooltip
|
|
31
|
-
v-if="config.fieldConfig && !disabledDataSource"
|
|
31
|
+
v-if="config.fieldConfig && !disabledDataSource && !mForm?.isCompare"
|
|
32
32
|
:disabled="showDataSourceFieldSelect"
|
|
33
33
|
content="选择数据源"
|
|
34
34
|
>
|
|
35
35
|
<TMagicButton
|
|
36
36
|
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
|
37
37
|
:size="size"
|
|
38
|
-
:disabled="disabled
|
|
38
|
+
:disabled="disabled"
|
|
39
39
|
@click="onToggleDataSourceFieldSelectHandler"
|
|
40
40
|
><MIcon :icon="Coin"></MIcon
|
|
41
41
|
></TMagicButton>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-data-source-fields">
|
|
3
|
-
<MagicTable :data="model[name]" :columns="
|
|
3
|
+
<MagicTable :data="model[name]" :columns="displayColumns" :border="true"></MagicTable>
|
|
4
4
|
|
|
5
|
-
<div class="m-editor-data-source-fields-footer">
|
|
5
|
+
<div v-if="!isCompare" class="m-editor-data-source-fields-footer">
|
|
6
6
|
<TMagicButton size="small" :disabled="disabled" plain @click="newFromJsonHandler()">快速添加</TMagicButton>
|
|
7
7
|
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
|
|
8
8
|
</div>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
</template>
|
|
48
48
|
|
|
49
49
|
<script setup lang="ts">
|
|
50
|
-
import { inject, Ref, ref } from 'vue';
|
|
50
|
+
import { computed, type ComputedRef, inject, onMounted, provide, Ref, ref } from 'vue';
|
|
51
51
|
|
|
52
52
|
import type { DataSchema } from '@tmagic/core';
|
|
53
53
|
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
|
|
@@ -84,6 +84,10 @@ const emit = defineEmits<{
|
|
|
84
84
|
}>();
|
|
85
85
|
|
|
86
86
|
const { uiService } = useServices();
|
|
87
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
88
|
+
|
|
89
|
+
/** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
|
|
90
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
87
91
|
|
|
88
92
|
const fieldValues = ref<Record<string, any>>({});
|
|
89
93
|
const fieldTitle = ref('');
|
|
@@ -97,6 +101,16 @@ const newHandler = () => {
|
|
|
97
101
|
addDialogVisible.value = true;
|
|
98
102
|
};
|
|
99
103
|
|
|
104
|
+
const editField = (row: Record<string, any>, index: number) => {
|
|
105
|
+
fieldValues.value = {
|
|
106
|
+
...row,
|
|
107
|
+
index,
|
|
108
|
+
};
|
|
109
|
+
fieldTitle.value = `编辑${row.title}`;
|
|
110
|
+
calcBoxPosition();
|
|
111
|
+
addDialogVisible.value = true;
|
|
112
|
+
};
|
|
113
|
+
|
|
100
114
|
const fieldChange = ({ index, ...value }: Record<string, any>, data: ContainerChangeEventData) => {
|
|
101
115
|
addDialogVisible.value = false;
|
|
102
116
|
|
|
@@ -154,13 +168,7 @@ const fieldColumns: ColumnConfig[] = [
|
|
|
154
168
|
{
|
|
155
169
|
text: '编辑',
|
|
156
170
|
handler: (row: Record<string, any>, index: number) => {
|
|
157
|
-
|
|
158
|
-
...row,
|
|
159
|
-
index,
|
|
160
|
-
};
|
|
161
|
-
fieldTitle.value = `编辑${row.title}`;
|
|
162
|
-
calcBoxPosition();
|
|
163
|
-
addDialogVisible.value = true;
|
|
171
|
+
editField(row, index);
|
|
164
172
|
},
|
|
165
173
|
},
|
|
166
174
|
{
|
|
@@ -176,6 +184,11 @@ const fieldColumns: ColumnConfig[] = [
|
|
|
176
184
|
},
|
|
177
185
|
];
|
|
178
186
|
|
|
187
|
+
/** 对比模式下移除「操作」列(编辑/删除按钮),仅保留只读列。 */
|
|
188
|
+
const displayColumns = computed<ColumnConfig[]>(() =>
|
|
189
|
+
isCompare.value ? fieldColumns.filter((col) => !col.actions) : fieldColumns,
|
|
190
|
+
);
|
|
191
|
+
|
|
179
192
|
const dataSourceFieldsConfig: FormConfig = [
|
|
180
193
|
{ name: 'index', type: 'hidden', filter: 'number', defaultValue: -1 },
|
|
181
194
|
{
|
|
@@ -345,4 +358,29 @@ const { height: editorHeight } = useEditorContentHeight();
|
|
|
345
358
|
|
|
346
359
|
const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
|
|
347
360
|
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的字段路径(字段名数组)。
|
|
364
|
+
* 当前层消费 path[0],并把剩余路径下发给嵌套字段,实现逐层打开。
|
|
365
|
+
*/
|
|
366
|
+
const editingFieldPath = inject<ComputedRef<string[]>>(
|
|
367
|
+
'editingDataSourceFieldPath',
|
|
368
|
+
computed(() => []),
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
provide(
|
|
372
|
+
'editingDataSourceFieldPath',
|
|
373
|
+
computed(() => editingFieldPath.value.slice(1)),
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
onMounted(() => {
|
|
377
|
+
const path = editingFieldPath.value;
|
|
378
|
+
if (!path.length) return;
|
|
379
|
+
|
|
380
|
+
const fields: Record<string, any>[] = props.model[props.name] || [];
|
|
381
|
+
const index = fields.findIndex((field) => field.name === path[0]);
|
|
382
|
+
if (index === -1) return;
|
|
383
|
+
|
|
384
|
+
editField(fields[index], index);
|
|
385
|
+
});
|
|
348
386
|
</script>
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
<template #suffix>
|
|
31
31
|
<Icon :icon="Coin" />
|
|
32
32
|
</template>
|
|
33
|
-
<template #default="
|
|
33
|
+
<template #default="slotProps">
|
|
34
34
|
<div style="display: flex; flex-direction: column; line-height: 1.2em">
|
|
35
|
-
<div>{{ item
|
|
36
|
-
<span style="font-size: 10px; color: rgba(0, 0, 0, 0.6)">{{ item
|
|
35
|
+
<div>{{ slotProps?.item?.text || '' }}</div>
|
|
36
|
+
<span style="font-size: 10px; color: rgba(0, 0, 0, 0.6)">{{ slotProps?.item?.value || '' }}</span>
|
|
37
37
|
</div>
|
|
38
38
|
</template>
|
|
39
39
|
</component>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
></MCascader>
|
|
14
14
|
|
|
15
15
|
<TMagicTooltip
|
|
16
|
-
v-if="model[name] && isCustomMethod &&
|
|
16
|
+
v-if="model[name] && isCustomMethod && dataSourceSidePanel && !isCompare"
|
|
17
17
|
:content="notEditable ? '查看' : '编辑'"
|
|
18
18
|
>
|
|
19
19
|
<TMagicButton class="m-fields-select-action-button" :size="size" @click="editCodeHandler">
|
|
@@ -75,12 +75,15 @@ const props = withDefaults(defineProps<FieldProps<DataSourceMethodSelectConfig>>
|
|
|
75
75
|
disabled: false,
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
const
|
|
78
|
+
const dataSourceSidePanel = computed(() =>
|
|
79
79
|
(uiService.get('sideBarItems') || []).find((item) => item.$key === SideItemKey.DATA_SOURCE),
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
const notEditable = computed(() => filterFunction(mForm, props.config.notEditable, props));
|
|
83
83
|
|
|
84
|
+
/** 对比模式下隐藏查看/编辑操作按钮,仅保留只读展示。 */
|
|
85
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
86
|
+
|
|
84
87
|
const dataSources = computed(() => dataSourceService.get('dataSources'));
|
|
85
88
|
|
|
86
89
|
const isCustomMethod = computed(() => {
|
|
@@ -205,12 +208,17 @@ const onParamsChangeHandler = (value: any, eventData: ContainerChangeEventData)
|
|
|
205
208
|
};
|
|
206
209
|
|
|
207
210
|
const editCodeHandler = () => {
|
|
208
|
-
const [id] = props.model[props.name];
|
|
211
|
+
const [id, methodName] = props.model[props.name];
|
|
209
212
|
|
|
210
213
|
const dataSource = dataSourceService.getDataSourceById(id);
|
|
211
214
|
|
|
212
215
|
if (!dataSource) return;
|
|
213
216
|
|
|
214
|
-
|
|
217
|
+
const sideBarItem = dataSourceSidePanel.value;
|
|
218
|
+
if (sideBarItem) {
|
|
219
|
+
uiService.set('sideBarActiveTabName', sideBarItem.text || sideBarItem.$key || SideItemKey.DATA_SOURCE);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
eventBus?.emit('edit-data-source-method', id, methodName);
|
|
215
223
|
};
|
|
216
224
|
</script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-data-source-methods">
|
|
3
|
-
<MagicTable :data="model[name]" :columns="
|
|
3
|
+
<MagicTable :data="model[name]" :columns="displayColumns" :border="true"></MagicTable>
|
|
4
4
|
|
|
5
|
-
<div class="m-editor-data-source-methods-footer">
|
|
5
|
+
<div v-if="!isCompare" class="m-editor-data-source-methods-footer">
|
|
6
6
|
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="createCodeHandler"
|
|
7
7
|
>添加</TMagicButton
|
|
8
8
|
>
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
</template>
|
|
22
22
|
|
|
23
23
|
<script setup lang="ts">
|
|
24
|
-
import { nextTick, ref, useTemplateRef } from 'vue';
|
|
24
|
+
import { computed, type ComputedRef, inject, nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
|
25
25
|
import { cloneDeep } from 'lodash-es';
|
|
26
26
|
|
|
27
27
|
import type { CodeBlockContent } from '@tmagic/core';
|
|
28
28
|
import { TMagicButton, tMagicMessageBox } from '@tmagic/design';
|
|
29
|
-
import type { ContainerChangeEventData, DataSourceMethodsConfig, FieldProps } from '@tmagic/form';
|
|
29
|
+
import type { ContainerChangeEventData, DataSourceMethodsConfig, FieldProps, FormState } from '@tmagic/form';
|
|
30
30
|
import { type ColumnConfig, MagicTable } from '@tmagic/table';
|
|
31
31
|
|
|
32
32
|
import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
|
|
@@ -42,11 +42,39 @@ const props = withDefaults(defineProps<FieldProps<DataSourceMethodsConfig>>(), {
|
|
|
42
42
|
|
|
43
43
|
const emit = defineEmits(['change']);
|
|
44
44
|
|
|
45
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
46
|
+
|
|
47
|
+
/** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
|
|
48
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
49
|
+
|
|
45
50
|
const codeConfig = ref<Omit<CodeBlockContent, 'content'> & { content: string }>();
|
|
46
51
|
const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
|
|
47
52
|
|
|
48
53
|
let editIndex = -1;
|
|
49
54
|
|
|
55
|
+
const editMethod = (method: CodeBlockContent, index: number) => {
|
|
56
|
+
let codeContent: string = '({ params, dataSource, app }) => {\n // place your code here\n}';
|
|
57
|
+
|
|
58
|
+
if (method.content) {
|
|
59
|
+
if (typeof method.content !== 'string') {
|
|
60
|
+
codeContent = method.content.toString();
|
|
61
|
+
} else {
|
|
62
|
+
codeContent = method.content;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
codeConfig.value = {
|
|
67
|
+
...cloneDeep(method),
|
|
68
|
+
content: codeContent,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
editIndex = index;
|
|
72
|
+
|
|
73
|
+
nextTick(() => {
|
|
74
|
+
codeBlockEditorRef.value?.show();
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
50
78
|
const methodColumns: ColumnConfig[] = [
|
|
51
79
|
{
|
|
52
80
|
label: '名称',
|
|
@@ -72,26 +100,7 @@ const methodColumns: ColumnConfig[] = [
|
|
|
72
100
|
{
|
|
73
101
|
text: '编辑',
|
|
74
102
|
handler: (method: CodeBlockContent, index: number) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (method.content) {
|
|
78
|
-
if (typeof method.content !== 'string') {
|
|
79
|
-
codeContent = method.content.toString();
|
|
80
|
-
} else {
|
|
81
|
-
codeContent = method.content;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
codeConfig.value = {
|
|
86
|
-
...cloneDeep(method),
|
|
87
|
-
content: codeContent,
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
editIndex = index;
|
|
91
|
-
|
|
92
|
-
nextTick(() => {
|
|
93
|
-
codeBlockEditorRef.value?.show();
|
|
94
|
-
});
|
|
103
|
+
editMethod(method, index);
|
|
95
104
|
},
|
|
96
105
|
},
|
|
97
106
|
{
|
|
@@ -107,6 +116,11 @@ const methodColumns: ColumnConfig[] = [
|
|
|
107
116
|
},
|
|
108
117
|
];
|
|
109
118
|
|
|
119
|
+
/** 对比模式下移除「操作」列(编辑/删除按钮),仅保留只读列。 */
|
|
120
|
+
const displayColumns = computed<ColumnConfig[]>(() =>
|
|
121
|
+
isCompare.value ? methodColumns.filter((col) => !col.actions) : methodColumns,
|
|
122
|
+
);
|
|
123
|
+
|
|
110
124
|
const createCodeHandler = () => {
|
|
111
125
|
codeConfig.value = {
|
|
112
126
|
name: '',
|
|
@@ -148,4 +162,21 @@ const submitCodeHandler = (value: CodeBlockContent, data: ContainerChangeEventDa
|
|
|
148
162
|
|
|
149
163
|
codeBlockEditorRef.value?.hide();
|
|
150
164
|
};
|
|
165
|
+
|
|
166
|
+
/** 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的方法名 */
|
|
167
|
+
const editingMethodName = inject<ComputedRef<string | undefined>>(
|
|
168
|
+
'editingDataSourceMethodName',
|
|
169
|
+
computed(() => ''),
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
onMounted(() => {
|
|
173
|
+
const methodName = editingMethodName.value;
|
|
174
|
+
if (!methodName) return;
|
|
175
|
+
|
|
176
|
+
const methods: CodeBlockContent[] = props.model[props.name] || [];
|
|
177
|
+
const index = methods.findIndex((method) => method.name === methodName);
|
|
178
|
+
if (index === -1) return;
|
|
179
|
+
|
|
180
|
+
editMethod(methods[index], index);
|
|
181
|
+
});
|
|
151
182
|
</script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-data-source-fields">
|
|
3
|
-
<MagicTable :data="model[name]" :columns="
|
|
3
|
+
<MagicTable :data="model[name]" :columns="displayColumns"></MagicTable>
|
|
4
4
|
|
|
5
|
-
<div class="m-editor-data-source-fields-footer">
|
|
5
|
+
<div v-if="!isCompare" class="m-editor-data-source-fields-footer">
|
|
6
6
|
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</template>
|
|
29
29
|
|
|
30
30
|
<script setup lang="ts">
|
|
31
|
-
import { inject, Ref, ref } from 'vue';
|
|
31
|
+
import { computed, inject, Ref, ref } from 'vue';
|
|
32
32
|
|
|
33
33
|
import type { MockSchema } from '@tmagic/core';
|
|
34
34
|
import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
|
|
@@ -54,6 +54,11 @@ const props = withDefaults(defineProps<FieldProps<DataSourceMocksConfig>>(), {
|
|
|
54
54
|
const emit = defineEmits(['change']);
|
|
55
55
|
|
|
56
56
|
const { uiService } = useServices();
|
|
57
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
58
|
+
|
|
59
|
+
/** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
|
|
60
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
61
|
+
|
|
57
62
|
const width = defineModel<number>('width', { default: 670 });
|
|
58
63
|
|
|
59
64
|
const drawerTitle = ref('');
|
|
@@ -202,6 +207,11 @@ const columns: ColumnConfig[] = [
|
|
|
202
207
|
},
|
|
203
208
|
];
|
|
204
209
|
|
|
210
|
+
/** 对比模式下移除「操作」列(编辑/删除按钮),仅保留只读列。 */
|
|
211
|
+
const displayColumns = computed<ColumnConfig[]>(() =>
|
|
212
|
+
isCompare.value ? columns.filter((col) => !col.actions) : columns,
|
|
213
|
+
);
|
|
214
|
+
|
|
205
215
|
const newHandler = () => {
|
|
206
216
|
const isFirstRow = props.model[props.name].length === 0;
|
|
207
217
|
formValues.value = {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
@change="changeHandler"
|
|
12
12
|
></MSelect>
|
|
13
13
|
|
|
14
|
-
<TMagicTooltip v-if="model[name] && hasDataSourceSidePanel" :content="notEditable ? '查看' : '编辑'">
|
|
14
|
+
<TMagicTooltip v-if="model[name] && hasDataSourceSidePanel && !isCompare" :content="notEditable ? '查看' : '编辑'">
|
|
15
15
|
<TMagicButton class="m-fields-select-action-button" :size="size" @click="editHandler"
|
|
16
16
|
><MIcon :icon="!notEditable ? Edit : View"></MIcon
|
|
17
17
|
></TMagicButton>
|
|
@@ -56,6 +56,9 @@ const dataSources = computed(() => dataSourceService.get('dataSources'));
|
|
|
56
56
|
|
|
57
57
|
const notEditable = computed(() => filterFunction(mForm, props.config.notEditable, props));
|
|
58
58
|
|
|
59
|
+
/** 对比模式下隐藏查看/编辑操作按钮,仅保留只读展示。 */
|
|
60
|
+
const isCompare = computed(() => Boolean(mForm?.isCompare));
|
|
61
|
+
|
|
59
62
|
const hasDataSourceSidePanel = computed(() =>
|
|
60
63
|
uiService.get('sideBarItems').find((item) => item.$key === SideItemKey.DATA_SOURCE),
|
|
61
64
|
);
|
|
@@ -6,22 +6,32 @@
|
|
|
6
6
|
:size="size"
|
|
7
7
|
:disabled="disabled"
|
|
8
8
|
:model="model"
|
|
9
|
+
:last-values="lastValues"
|
|
10
|
+
:is-compare="isCompareMode"
|
|
9
11
|
:config="tableConfig"
|
|
10
12
|
@change="onChangeHandler"
|
|
11
13
|
></MTable>
|
|
12
14
|
|
|
13
15
|
<div v-else class="fullWidth">
|
|
14
|
-
<TMagicButton
|
|
16
|
+
<TMagicButton
|
|
17
|
+
v-if="!isCompareMode"
|
|
18
|
+
class="create-button"
|
|
19
|
+
type="primary"
|
|
20
|
+
:size="size"
|
|
21
|
+
:disabled="disabled"
|
|
22
|
+
@click="addEvent()"
|
|
15
23
|
>添加事件</TMagicButton
|
|
16
24
|
>
|
|
17
25
|
<MPanel
|
|
18
|
-
v-for="
|
|
19
|
-
:key="index"
|
|
26
|
+
v-for="entry in displayList"
|
|
27
|
+
:key="entry.index"
|
|
20
28
|
:disabled="disabled"
|
|
21
29
|
:size="size"
|
|
22
|
-
:prop="`${prop}.${index}`"
|
|
30
|
+
:prop="`${prop}.${entry.index}`"
|
|
23
31
|
:config="actionsConfig"
|
|
24
|
-
:model="cardItem"
|
|
32
|
+
:model="entry.cardItem"
|
|
33
|
+
:last-values="entry.lastCardItem"
|
|
34
|
+
:is-compare="isCompareMode"
|
|
25
35
|
:label-width="config.labelWidth || '100px'"
|
|
26
36
|
@change="onChangeHandler"
|
|
27
37
|
>
|
|
@@ -29,19 +39,22 @@
|
|
|
29
39
|
<MFormContainer
|
|
30
40
|
class="fullWidth"
|
|
31
41
|
:config="eventNameConfig"
|
|
32
|
-
:model="cardItem"
|
|
42
|
+
:model="entry.cardItem"
|
|
43
|
+
:last-values="entry.lastCardItem"
|
|
44
|
+
:is-compare="isCompareMode"
|
|
33
45
|
:disabled="disabled"
|
|
34
46
|
:size="size"
|
|
35
|
-
:prop="`${prop}.${index}`"
|
|
47
|
+
:prop="`${prop}.${entry.index}`"
|
|
36
48
|
@change="eventNameChangeHandler"
|
|
37
49
|
></MFormContainer>
|
|
38
50
|
<TMagicButton
|
|
51
|
+
v-if="!isCompareMode"
|
|
39
52
|
style="color: #f56c6c"
|
|
40
53
|
link
|
|
41
54
|
:icon="Delete"
|
|
42
55
|
:disabled="disabled"
|
|
43
56
|
:size="size"
|
|
44
|
-
@click="removeEvent(Number(index))"
|
|
57
|
+
@click="removeEvent(Number(entry.index))"
|
|
45
58
|
></TMagicButton>
|
|
46
59
|
</template>
|
|
47
60
|
</MPanel>
|
|
@@ -374,6 +387,42 @@ const isOldVersion = computed(() => {
|
|
|
374
387
|
return !has(props.model[props.name][0], 'actions');
|
|
375
388
|
});
|
|
376
389
|
|
|
390
|
+
/**
|
|
391
|
+
* 对比模式判定:
|
|
392
|
+
*
|
|
393
|
+
* event-select 内部由「事件列表 + 嵌套子表单」组成,属于复合字段。父级 `MFormContainer` 已将其
|
|
394
|
+
* 归入「自接管对比字段」(见 Container.vue 的 `SELF_DIFF_FIELD_TYPES`),即对比时只渲染一次本组件,
|
|
395
|
+
* 并把当前值 `model` 与历史值 `lastValues` 一并传入,由本组件把 `is-compare`/`lastValues` 透传给
|
|
396
|
+
* 内部的 MPanel / MFormContainer,逐项(事件名、动作)展示前后差异。
|
|
397
|
+
*
|
|
398
|
+
* 仅当存在历史值时才启用对比,避免 lastValues 缺失时退化为「全部新增」的空对比。
|
|
399
|
+
*/
|
|
400
|
+
const isCompareMode = computed(() => Boolean(props.isCompare && props.lastValues));
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* 待渲染的事件卡片列表。
|
|
404
|
+
*
|
|
405
|
+
* - 非对比模式:直接映射当前事件列表,`lastCardItem` 为空;
|
|
406
|
+
* - 对比模式:按索引对齐当前值与历史值,取两者长度的最大值,使得「新增」(仅当前有)与
|
|
407
|
+
* 「删除」(仅历史有)的事件都能被渲染出来;缺失的一侧用空对象兜底,从而让子级正确高亮差异。
|
|
408
|
+
*/
|
|
409
|
+
const displayList = computed<{ cardItem: any; lastCardItem: any; index: number }[]>(() => {
|
|
410
|
+
const current = props.model[props.name] || [];
|
|
411
|
+
|
|
412
|
+
if (!isCompareMode.value) {
|
|
413
|
+
return current.map((cardItem: any, index: number) => ({ cardItem, lastCardItem: undefined, index }));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const last = props.lastValues?.[props.name] || [];
|
|
417
|
+
const length = Math.max(current.length, last.length);
|
|
418
|
+
|
|
419
|
+
return Array.from({ length }, (_, index) => ({
|
|
420
|
+
cardItem: current[index] ?? {},
|
|
421
|
+
lastCardItem: last[index] ?? {},
|
|
422
|
+
index,
|
|
423
|
+
}));
|
|
424
|
+
});
|
|
425
|
+
|
|
377
426
|
// 添加事件
|
|
378
427
|
const addEvent = () => {
|
|
379
428
|
const defaultEvent = {
|