@tmagic/editor 1.8.0-beta.0 → 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 +13 -4
- 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 +9 -3
- 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 +38 -8
- package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +4 -2
- 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 +11 -3
- package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +17 -4
- package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +11 -3
- package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +15 -3
- package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +11 -3
- package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +11 -3
- 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 +38 -4
- 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 +106 -52
- 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 +9085 -4480
- 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 +9 -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/Index.vue +6 -0
- package/src/fields/StyleSetter/components/Border.vue +30 -7
- package/src/fields/StyleSetter/components/Box.vue +2 -0
- package/src/fields/StyleSetter/pro/Background.vue +15 -1
- package/src/fields/StyleSetter/pro/Border.vue +24 -2
- package/src/fields/StyleSetter/pro/Font.vue +15 -1
- package/src/fields/StyleSetter/pro/Layout.vue +17 -1
- package/src/fields/StyleSetter/pro/Position.vue +15 -1
- package/src/fields/StyleSetter/pro/Transform.vue +15 -1
- 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 +64 -12
- 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 +170 -61
- 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 +3173 -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/src/hooks/use-stage.ts
CHANGED
|
@@ -48,6 +48,7 @@ export const useStage = (stageOptions: StageOptions) => {
|
|
|
48
48
|
disabledMultiSelect: stageOptions.disabledMultiSelect,
|
|
49
49
|
alwaysMultiSelect: stageOptions.alwaysMultiSelect,
|
|
50
50
|
disabledRule: stageOptions.disabledRule,
|
|
51
|
+
disabledFlashTip: stageOptions.disabledFlashTip,
|
|
51
52
|
});
|
|
52
53
|
|
|
53
54
|
watch(
|
|
@@ -97,32 +98,48 @@ export const useStage = (stageOptions: StageOptions) => {
|
|
|
97
98
|
|
|
98
99
|
stage.on('update', (ev: UpdateEventData) => {
|
|
99
100
|
if (ev.parentEl) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
// 拖动多选元素到一个新容器:整批合成一次 moveToContainer,只产生一条历史记录
|
|
102
|
+
const pId = getIdFromEl()(ev.parentEl);
|
|
103
|
+
if (!pId) return;
|
|
104
|
+
const configs = ev.data
|
|
105
|
+
.map((data) => {
|
|
106
|
+
const id = getIdFromEl()(data.el);
|
|
107
|
+
if (!id) return null;
|
|
108
|
+
const cfg: MNode = { id, style: data.style };
|
|
109
|
+
return cfg;
|
|
110
|
+
})
|
|
111
|
+
.filter((cfg): cfg is MNode => Boolean(cfg));
|
|
112
|
+
if (configs.length > 0) {
|
|
113
|
+
editorService.moveToContainer(configs, pId);
|
|
104
114
|
}
|
|
105
115
|
return;
|
|
106
116
|
}
|
|
107
117
|
|
|
108
|
-
//
|
|
118
|
+
// 多选拖动 / 多选缩放:所有元素整批走一次 update,避免历史栈被切成 N 条
|
|
119
|
+
// changeRecordList 与 configs 同序,每个节点保留自己的 records;
|
|
120
|
+
// 不能把多个节点的 records 合并到同一个数组里,否则 doUpdate / nodeUpdateHandler 会把别的节点的 propPath 当成自己的。
|
|
121
|
+
const configs: MNode[] = [];
|
|
122
|
+
const changeRecordList: ReturnType<typeof buildChangeRecords>[] = [];
|
|
109
123
|
ev.data.forEach((data) => {
|
|
110
124
|
const id = getIdFromEl()(data.el);
|
|
111
125
|
if (!id) return;
|
|
112
126
|
|
|
113
127
|
const { style = {} } = data;
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
configs.push({ id, style });
|
|
129
|
+
changeRecordList.push(buildChangeRecords(style, 'style'));
|
|
116
130
|
});
|
|
131
|
+
if (configs.length === 0) return;
|
|
132
|
+
|
|
133
|
+
editorService.update(configs, { changeRecordList, historySource: 'stage' });
|
|
117
134
|
});
|
|
118
135
|
|
|
119
136
|
stage.on('sort', (ev: SortEventData) => {
|
|
120
|
-
editorService.sort(ev.src, ev.dist);
|
|
137
|
+
editorService.sort(ev.src, ev.dist, { historySource: 'stage' });
|
|
121
138
|
});
|
|
122
139
|
|
|
123
140
|
stage.on('remove', (ev: RemoveEventData) => {
|
|
124
141
|
const nodes = ev.data.map(({ el }) => editorService.getNodeById(getIdFromEl()(el) || ''));
|
|
125
|
-
editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[]);
|
|
142
|
+
editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[], { historySource: 'stage' });
|
|
126
143
|
});
|
|
127
144
|
|
|
128
145
|
stage.on('select-parent', () => {
|
package/src/index.ts
CHANGED
|
@@ -44,6 +44,8 @@ export { default as stageOverlayService } from './services/stageOverlay';
|
|
|
44
44
|
export { default as uiService } from './services/ui';
|
|
45
45
|
export { default as codeBlockService } from './services/codeBlock';
|
|
46
46
|
export { default as depService } from './services/dep';
|
|
47
|
+
export { default as componentListService } from './services/componentList';
|
|
48
|
+
export { default as keybindingService } from './services/keybinding';
|
|
47
49
|
export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue';
|
|
48
50
|
export { default as LayerPanel } from './layouts/sidebar/layer/LayerPanel.vue';
|
|
49
51
|
export { default as CodeSelect } from './fields/CodeSelect.vue';
|
|
@@ -70,6 +72,12 @@ export { default as LayoutContainer } from './components/SplitView.vue';
|
|
|
70
72
|
export { default as SplitView } from './components/SplitView.vue';
|
|
71
73
|
export { default as Resizer } from './components/Resizer.vue';
|
|
72
74
|
export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue';
|
|
75
|
+
export { default as CompareForm } from './components/CompareForm.vue';
|
|
76
|
+
export { default as HistoryListBucket } from './layouts/history-list/Bucket.vue';
|
|
77
|
+
export { default as HistoryListBucketTab } from './layouts/history-list/BucketTab.vue';
|
|
78
|
+
export { default as HistoryDiffDialog } from './layouts/history-list/HistoryDiffDialog.vue';
|
|
79
|
+
export { confirmHistoryAction } from './layouts/history-list/composables';
|
|
80
|
+
export { useHistoryRevert } from './layouts/history-list/useHistoryRevert';
|
|
73
81
|
export { default as FloatingBox } from './components/FloatingBox.vue';
|
|
74
82
|
export { default as Tree } from './components/Tree.vue';
|
|
75
83
|
export { default as TreeNode } from './components/TreeNode.vue';
|
package/src/initService.ts
CHANGED
|
@@ -21,12 +21,12 @@ import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTe
|
|
|
21
21
|
import { FullScreen } from '@element-plus/icons-vue';
|
|
22
22
|
import { throttle } from 'lodash-es';
|
|
23
23
|
import type * as Monaco from 'monaco-editor';
|
|
24
|
-
import serialize from 'serialize-javascript';
|
|
25
24
|
|
|
26
25
|
import { TMagicButton } from '@tmagic/design';
|
|
27
26
|
|
|
28
27
|
import MIcon from '@editor/components/Icon.vue';
|
|
29
28
|
import { getEditorConfig } from '@editor/utils/config';
|
|
29
|
+
import { serializeConfig } from '@editor/utils/editor';
|
|
30
30
|
import loadMonaco from '@editor/utils/monaco-editor';
|
|
31
31
|
|
|
32
32
|
defineOptions({
|
|
@@ -163,10 +163,7 @@ const toString = (v: string | any, language: string): string => {
|
|
|
163
163
|
if (language === 'json') {
|
|
164
164
|
value = JSON.stringify(v, null, 2);
|
|
165
165
|
} else {
|
|
166
|
-
value =
|
|
167
|
-
space: 2,
|
|
168
|
-
unsafe: true,
|
|
169
|
-
}).replace(/"(\w+)":\s/g, '$1: ');
|
|
166
|
+
value = serializeConfig(v);
|
|
170
167
|
}
|
|
171
168
|
} else {
|
|
172
169
|
value = v;
|
|
@@ -330,6 +327,21 @@ watch(
|
|
|
330
327
|
},
|
|
331
328
|
);
|
|
332
329
|
|
|
330
|
+
// diff 模式下,对比的"当前值"(modifiedValues)也可能在外部变化(例如 lastValues 不变、当前 model 变了),
|
|
331
|
+
// 此时同样需要重新设置编辑器值,否则右侧编辑器内容会停留在初始化时的快照。
|
|
332
|
+
watch(
|
|
333
|
+
() => props.modifiedValues,
|
|
334
|
+
(v, preV) => {
|
|
335
|
+
if (props.type !== 'diff') return;
|
|
336
|
+
if (v !== preV) {
|
|
337
|
+
setEditorValue(props.initValues, props.modifiedValues);
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
deep: true,
|
|
342
|
+
},
|
|
343
|
+
);
|
|
344
|
+
|
|
333
345
|
watch(
|
|
334
346
|
() => props.options,
|
|
335
347
|
(v) => {
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
left-class="m-editor-framework-left"
|
|
24
24
|
center-class="m-editor-framework-center"
|
|
25
25
|
right-class="m-editor-framework-right"
|
|
26
|
-
:left="columnWidth.left"
|
|
26
|
+
:left="hideSidebar ? undefined : columnWidth.left"
|
|
27
27
|
:right="columnWidth.right"
|
|
28
|
-
:min-left="MIN_LEFT_COLUMN_WIDTH"
|
|
28
|
+
:min-left="hideSidebar ? 0 : MIN_LEFT_COLUMN_WIDTH"
|
|
29
29
|
:min-right="MIN_RIGHT_COLUMN_WIDTH"
|
|
30
30
|
:min-center="MIN_CENTER_COLUMN_WIDTH"
|
|
31
31
|
:width="frameworkRect.width"
|
|
32
32
|
@change="columnWidthChange"
|
|
33
33
|
>
|
|
34
|
-
<template #left>
|
|
34
|
+
<template v-if="!hideSidebar" #left>
|
|
35
35
|
<slot name="sidebar"></slot>
|
|
36
36
|
</template>
|
|
37
37
|
|
|
@@ -94,10 +94,12 @@ defineOptions({
|
|
|
94
94
|
name: 'MEditorFramework',
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
defineProps<{
|
|
97
|
+
const props = defineProps<{
|
|
98
98
|
disabledPageFragment: boolean;
|
|
99
99
|
pageBarSortOptions?: PageBarSortOptions;
|
|
100
100
|
pageFilterFunction?: (_page: MPage | MPageFragment, _keyword: string) => boolean;
|
|
101
|
+
/** 是否隐藏左侧面板 */
|
|
102
|
+
hideSidebar?: boolean;
|
|
101
103
|
}>();
|
|
102
104
|
|
|
103
105
|
const codeOptions = inject('codeOptions', {});
|
|
@@ -132,7 +134,10 @@ watch(
|
|
|
132
134
|
);
|
|
133
135
|
|
|
134
136
|
const columnWidthChange = (columnW: GetColumnWidth) => {
|
|
135
|
-
|
|
137
|
+
// 隐藏左侧面板时 left 恒为 0,不覆盖已持久化的左栏宽度,避免重新展示时丢失宽度
|
|
138
|
+
if (!props.hideSidebar) {
|
|
139
|
+
storageService.setItem(LEFT_COLUMN_WIDTH_STORAGE_KEY, columnW.left, { protocol: Protocol.NUMBER });
|
|
140
|
+
}
|
|
136
141
|
storageService.setItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY, columnW.right, { protocol: Protocol.NUMBER });
|
|
137
142
|
|
|
138
143
|
uiService.set('columnWidth', columnW);
|
|
@@ -163,7 +168,7 @@ onBeforeUnmount(() => {
|
|
|
163
168
|
const saveCode = (value: string) => {
|
|
164
169
|
try {
|
|
165
170
|
const parseDSL = getEditorConfig('parseDSL');
|
|
166
|
-
editorService.set('root', parseDSL(value));
|
|
171
|
+
editorService.set('root', parseDSL(value), { historySource: 'root-code' });
|
|
167
172
|
} catch (e: any) {
|
|
168
173
|
console.error(e);
|
|
169
174
|
}
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -19,6 +19,7 @@ import { NodeType } from '@tmagic/core';
|
|
|
19
19
|
import { useServices } from '@editor/hooks/use-services';
|
|
20
20
|
import { ColumnLayout, MenuBarData, MenuButton, MenuComponent, MenuItem } from '@editor/type';
|
|
21
21
|
|
|
22
|
+
import HistoryListPanel from './history-list/HistoryListPanel.vue';
|
|
22
23
|
import NavMenuColumn from './NavMenuColumn.vue';
|
|
23
24
|
|
|
24
25
|
defineOptions({
|
|
@@ -79,7 +80,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
|
|
|
79
80
|
disabled: () => editorService.get('node')?.type === NodeType.PAGE,
|
|
80
81
|
handler: () => {
|
|
81
82
|
const node = editorService.get('node');
|
|
82
|
-
node && editorService.remove(node);
|
|
83
|
+
node && editorService.remove(node, { historySource: 'toolbar' });
|
|
83
84
|
},
|
|
84
85
|
});
|
|
85
86
|
break;
|
|
@@ -89,7 +90,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
|
|
|
89
90
|
className: 'undo',
|
|
90
91
|
icon: markRaw(Back),
|
|
91
92
|
tooltip: `后退(${ctrl}+z)`,
|
|
92
|
-
disabled: () => !historyService.
|
|
93
|
+
disabled: () => !historyService.canUndo('page', editorService.get('page')?.id),
|
|
93
94
|
handler: () => editorService.undo(),
|
|
94
95
|
});
|
|
95
96
|
break;
|
|
@@ -99,10 +100,18 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
|
|
|
99
100
|
className: 'redo',
|
|
100
101
|
icon: markRaw(Right),
|
|
101
102
|
tooltip: `前进(${ctrl}+Shift+z)`,
|
|
102
|
-
disabled: () => !historyService.
|
|
103
|
+
disabled: () => !historyService.canRedo('page', editorService.get('page')?.id),
|
|
103
104
|
handler: () => editorService.redo(),
|
|
104
105
|
});
|
|
105
106
|
break;
|
|
107
|
+
case 'history-list':
|
|
108
|
+
// 历史记录面板:以 component 形式挂入,自带 popover;点击 nav 上的图标弹出。
|
|
109
|
+
config.push({
|
|
110
|
+
type: 'component',
|
|
111
|
+
className: 'history-list',
|
|
112
|
+
component: markRaw(HistoryListPanel),
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
106
115
|
case 'zoom-in':
|
|
107
116
|
config.push({
|
|
108
117
|
type: 'button',
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-history-list-bucket">
|
|
3
|
+
<div class="m-editor-history-list-bucket-title">
|
|
4
|
+
<span>{{ config.title }}</span>
|
|
5
|
+
<code>{{ String(bucketId) }}</code>
|
|
6
|
+
<span class="m-editor-history-list-bucket-count">{{ groups.length }} 组</span>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<ul class="m-editor-history-list-ul">
|
|
10
|
+
<GroupRow
|
|
11
|
+
v-for="group in groups"
|
|
12
|
+
:key="rowKey(group)"
|
|
13
|
+
:group="toRow(group)"
|
|
14
|
+
:expanded="isHistoryGroupExpanded(expanded, rowKey(group))"
|
|
15
|
+
:goto-enabled="config.gotoEnabled"
|
|
16
|
+
@toggle="(key: string) => $emit('toggle', key)"
|
|
17
|
+
@goto="(index: number) => $emit('goto', bucketId, index)"
|
|
18
|
+
@diff-step="(index: number) => $emit('diff-step', bucketId, index)"
|
|
19
|
+
@revert-step="(index: number) => $emit('revert-step', bucketId, index)"
|
|
20
|
+
/>
|
|
21
|
+
<!--
|
|
22
|
+
初始状态项:永远位于该 bucket 列表底部(同样按倒序展示,最底部 = 最早状态)。
|
|
23
|
+
当 bucket 内所有 group 都未 applied 时即为当前位置。
|
|
24
|
+
config.showInitial=false 时不展示(用于没有"撤销到初始状态"语义的自定义历史,如业务模块历史)。
|
|
25
|
+
-->
|
|
26
|
+
<InitialRow
|
|
27
|
+
v-if="config.showInitial !== false"
|
|
28
|
+
:is-current="isInitial"
|
|
29
|
+
:goto-enabled="config.gotoEnabled"
|
|
30
|
+
@goto-initial="$emit('goto-initial', bucketId)"
|
|
31
|
+
/>
|
|
32
|
+
</ul>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script lang="ts" setup generic="T extends BaseStepValue = BaseStepValue">
|
|
37
|
+
import { computed } from 'vue';
|
|
38
|
+
|
|
39
|
+
import type { BaseStepValue, HistoryBucketConfig } from '@editor/type';
|
|
40
|
+
|
|
41
|
+
import type { HistoryBucketGroup, HistoryRowGroup } from './composables';
|
|
42
|
+
import { isHistoryGroupExpanded, toRowGroup } from './composables';
|
|
43
|
+
import GroupRow from './GroupRow.vue';
|
|
44
|
+
import InitialRow from './InitialRow.vue';
|
|
45
|
+
|
|
46
|
+
defineOptions({
|
|
47
|
+
name: 'MEditorHistoryListBucket',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const props = defineProps<{
|
|
51
|
+
/**
|
|
52
|
+
* 该类历史的整体渲染配置(title / prefix / describe* / isStep* / showInitial / gotoEnabled)。
|
|
53
|
+
* 由父组件按业务类型注入,组件内部按需读取,避免逐项透传多个 props。
|
|
54
|
+
*/
|
|
55
|
+
config: HistoryBucketConfig<T>;
|
|
56
|
+
/** 当前 bucket 对应的目标 id(dataSource.id 或 codeBlock.id),同时用于组装子项的 key。 */
|
|
57
|
+
bucketId: string | number;
|
|
58
|
+
/** 当前 bucket 下的所有历史分组,按时间倒序展示(最近的操作在前)。 */
|
|
59
|
+
groups: HistoryBucketGroup<T>[];
|
|
60
|
+
/** 共享的折叠状态表(key -> 是否展开,缺省或 true 为展开、false 为收起),由顶层 panel 统一维护以便跨 tab 复用。 */
|
|
61
|
+
expanded: Record<string, boolean>;
|
|
62
|
+
}>();
|
|
63
|
+
|
|
64
|
+
defineEmits<{
|
|
65
|
+
/** 透传子组件 GroupRow 的 toggle,由上层 panel 更新 expanded。 */
|
|
66
|
+
(_e: 'toggle', _key: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* 透传子组件 GroupRow 的 goto,并附带当前 bucket 对应的 id(dataSourceId / codeBlockId),
|
|
69
|
+
* 上层据此调用对应 service.goto(id, targetCursor)。
|
|
70
|
+
*/
|
|
71
|
+
(_e: 'goto', _bucketId: string | number, _index: number): void;
|
|
72
|
+
/** 用户点击初始项希望该 bucket 回到未修改状态;携带 bucketId 用于上层路由到正确的 service。 */
|
|
73
|
+
(_e: 'goto-initial', _bucketId: string | number): void;
|
|
74
|
+
/** 用户点击"查看差异",携带 bucketId 与 step 索引。 */
|
|
75
|
+
(_e: 'diff-step', _bucketId: string | number, _index: number): void;
|
|
76
|
+
/** 用户点击"回滚"按钮,携带 bucketId 与 step 索引,类 git revert。 */
|
|
77
|
+
(_e: 'revert-step', _bucketId: string | number, _index: number): void;
|
|
78
|
+
}>();
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 子项 / 折叠状态 key:`${prefix}-${bucketId}-${组内首步 index}`。
|
|
82
|
+
* 以稳定的 step 索引(而非展示位置)标识分组,历史数据更新后已展开的分组状态仍能正确保持。
|
|
83
|
+
*/
|
|
84
|
+
const rowKey = (group: HistoryBucketGroup<T>) => `${props.config.prefix}-${props.bucketId}-${group.steps[0]?.index}`;
|
|
85
|
+
|
|
86
|
+
/** 把原始分组派生为 GroupRow 直接消费的视图模型。 */
|
|
87
|
+
const toRow = (group: HistoryBucketGroup<T>): HistoryRowGroup => toRowGroup(group, rowKey(group), props.config);
|
|
88
|
+
|
|
89
|
+
/** 该 bucket 是否处于初始状态(栈 cursor=0),等价于全部 group 都未 applied。 */
|
|
90
|
+
const isInitial = computed(() => props.groups.length > 0 && props.groups.every((g) => !g.applied));
|
|
91
|
+
</script>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="!buckets.length" class="m-editor-history-list-empty">暂无操作记录</div>
|
|
3
|
+
<template v-else>
|
|
4
|
+
<div v-if="config.showClear !== false" class="m-editor-history-list-toolbar">
|
|
5
|
+
<span class="m-editor-history-list-clear" :title="`清空${config.title}的历史记录`" @click="$emit('clear')"
|
|
6
|
+
>清空</span
|
|
7
|
+
>
|
|
8
|
+
</div>
|
|
9
|
+
<TMagicScrollbar max-height="360px">
|
|
10
|
+
<Bucket
|
|
11
|
+
v-for="bucket in buckets"
|
|
12
|
+
:key="`${config.prefix}-${bucket.id}`"
|
|
13
|
+
:config="config"
|
|
14
|
+
:bucket-id="bucket.id"
|
|
15
|
+
:groups="bucket.groups"
|
|
16
|
+
:expanded="expanded"
|
|
17
|
+
@toggle="(key: string) => $emit('toggle', key)"
|
|
18
|
+
@goto="(id: string | number, index: number) => $emit('goto', id, index)"
|
|
19
|
+
@goto-initial="(id: string | number) => $emit('goto-initial', id)"
|
|
20
|
+
@diff-step="(id: string | number, index: number) => $emit('diff-step', id, index)"
|
|
21
|
+
@revert-step="(id: string | number, index: number) => $emit('revert-step', id, index)"
|
|
22
|
+
/>
|
|
23
|
+
</TMagicScrollbar>
|
|
24
|
+
</template>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script lang="ts" setup generic="T extends BaseStepValue = BaseStepValue">
|
|
28
|
+
import { TMagicScrollbar } from '@tmagic/design';
|
|
29
|
+
|
|
30
|
+
import type { BaseStepValue, HistoryBucketConfig } from '@editor/type';
|
|
31
|
+
|
|
32
|
+
import Bucket from './Bucket.vue';
|
|
33
|
+
import type { HistoryBucketGroup } from './composables';
|
|
34
|
+
|
|
35
|
+
defineOptions({
|
|
36
|
+
name: 'MEditorHistoryListBucketTab',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
defineProps<{
|
|
40
|
+
/**
|
|
41
|
+
* 该类历史的整体渲染配置(title / prefix / describe* / isStep* / showInitial / gotoEnabled / showClear),
|
|
42
|
+
* 由父组件按业务类型注入并整体透传给 Bucket,避免逐项透传多个 props。
|
|
43
|
+
*/
|
|
44
|
+
config: HistoryBucketConfig<T>;
|
|
45
|
+
/**
|
|
46
|
+
* 已按目标 id 聚拢成的 bucket 列表,每个 bucket 内部的 groups 已按时间倒序排好。
|
|
47
|
+
* 空数组时显示空态。
|
|
48
|
+
*/
|
|
49
|
+
buckets: { id: string | number; groups: HistoryBucketGroup<T>[] }[];
|
|
50
|
+
/**
|
|
51
|
+
* 共享的折叠状态表(key -> 是否展开),由顶层 panel 统一维护。
|
|
52
|
+
* key 形如 `${prefix}-${id}-${组内首步 index}`——以稳定的 step 索引而非展示位置标识分组,
|
|
53
|
+
* 这样历史数据更新后已展开的分组状态仍能正确保持。
|
|
54
|
+
*/
|
|
55
|
+
expanded: Record<string, boolean>;
|
|
56
|
+
}>();
|
|
57
|
+
|
|
58
|
+
defineEmits<{
|
|
59
|
+
/** 透传子组件 Bucket 的 toggle 事件给上层 panel,由其更新 expanded。 */
|
|
60
|
+
(_e: 'toggle', _key: string): void;
|
|
61
|
+
/** 透传 Bucket 的 goto 事件,携带目标 id 与目标 step 索引。 */
|
|
62
|
+
(_e: 'goto', _targetId: string | number, _index: number): void;
|
|
63
|
+
/** 透传 Bucket 的 goto-initial 事件,携带目标 id(回到该目标未修改时的状态)。 */
|
|
64
|
+
(_e: 'goto-initial', _targetId: string | number): void;
|
|
65
|
+
/** 透传 Bucket 的 diff-step 事件,携带目标 id 与 step 索引。 */
|
|
66
|
+
(_e: 'diff-step', _targetId: string | number, _index: number): void;
|
|
67
|
+
/** 透传 Bucket 的 revert-step 事件,携带目标 id 与 step 索引(类 git revert)。 */
|
|
68
|
+
(_e: 'revert-step', _targetId: string | number, _index: number): void;
|
|
69
|
+
/** 用户点击"清空"按钮,请求清空该类(数据源 / 代码块)的全部历史记录(由上层弹窗二次确认后执行)。 */
|
|
70
|
+
(_e: 'clear'): void;
|
|
71
|
+
}>();
|
|
72
|
+
</script>
|