@tmagic/editor 1.8.0-beta.4 → 1.8.0-beta.6
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/components/CompareForm.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +25 -8
- package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +6 -4
- package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +25 -12
- package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +27 -5
- package/dist/es/index.js +6 -3
- package/dist/es/initService.js +1 -1
- package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +19 -55
- package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +22 -39
- package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +149 -103
- package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +32 -8
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +335 -213
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +36 -7
- package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +47 -60
- package/dist/es/layouts/history-list/composables.js +73 -32
- package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +16 -3
- package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +23 -1
- package/dist/es/services/codeBlock.js +96 -37
- package/dist/es/services/dataSource.js +70 -26
- package/dist/es/services/editor.js +266 -104
- package/dist/es/services/history.js +271 -212
- package/dist/es/services/ui.js +3 -0
- package/dist/es/style.css +53 -7
- package/dist/es/utils/data-source/index.js +2 -0
- package/dist/es/utils/editor.js +103 -49
- package/dist/es/utils/history.js +232 -0
- package/dist/es/utils/indexed-db.js +86 -0
- package/dist/es/utils/undo-redo.js +60 -1
- package/dist/style.css +53 -7
- package/dist/tmagic-editor.umd.cjs +2064 -1000
- package/package.json +7 -7
- package/src/components/CompareForm.vue +3 -1
- package/src/components/ToolButton.vue +2 -2
- package/src/fields/CodeSelectCol.vue +7 -1
- package/src/fields/DataSourceFieldSelect/FieldSelect.vue +16 -2
- package/src/fields/DataSourceFields.vue +37 -8
- package/src/fields/DataSourceMethodSelect.vue +9 -4
- package/src/fields/DataSourceMethods.vue +42 -21
- package/src/fields/StyleSetter/components/Border.vue +15 -6
- package/src/index.ts +1 -0
- package/src/initService.ts +1 -1
- package/src/layouts/Framework.vue +1 -1
- package/src/layouts/history-list/Bucket.vue +34 -71
- package/src/layouts/history-list/BucketTab.vue +46 -54
- package/src/layouts/history-list/GroupRow.vue +146 -111
- package/src/layouts/history-list/HistoryDiffDialog.vue +94 -68
- package/src/layouts/history-list/HistoryListPanel.vue +298 -115
- package/src/layouts/history-list/InitialRow.vue +28 -9
- package/src/layouts/history-list/PageTab.vue +57 -51
- package/src/layouts/history-list/composables.ts +157 -36
- package/src/layouts/page-bar/PageBar.vue +4 -2
- package/src/layouts/sidebar/Sidebar.vue +6 -1
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +30 -2
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +26 -1
- package/src/services/codeBlock.ts +113 -37
- package/src/services/dataSource.ts +94 -40
- package/src/services/editor.ts +376 -136
- package/src/services/history.ts +306 -209
- package/src/services/ui.ts +7 -0
- package/src/theme/history-list-panel.scss +72 -5
- package/src/theme/page-bar.scss +0 -4
- package/src/theme/style-setter/border.scss +4 -1
- package/src/type.ts +183 -64
- package/src/utils/data-source/index.ts +2 -0
- package/src/utils/editor.ts +166 -60
- package/src/utils/history.ts +308 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/indexed-db.ts +122 -0
- package/src/utils/undo-redo.ts +88 -0
- package/types/index.d.ts +813 -302
|
@@ -45,6 +45,28 @@
|
|
|
45
45
|
list-style: none;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// 历史列表工具条:放置「清空」等列表级操作,右对齐。
|
|
49
|
+
.m-editor-history-list-toolbar {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: flex-end;
|
|
53
|
+
padding: 0 4px 4px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 「清空」按钮:红色文字按钮,强调破坏性操作(点击后会二次确认)。
|
|
57
|
+
.m-editor-history-list-clear {
|
|
58
|
+
padding: 2px 8px;
|
|
59
|
+
border-radius: 4px;
|
|
60
|
+
font-size: 12px;
|
|
61
|
+
color: #f56c6c;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
user-select: none;
|
|
64
|
+
|
|
65
|
+
&:hover {
|
|
66
|
+
background-color: rgba(245, 108, 108, 0.12);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
48
70
|
.m-editor-history-list-item {
|
|
49
71
|
display: flex;
|
|
50
72
|
align-items: center;
|
|
@@ -215,6 +237,10 @@
|
|
|
215
237
|
|
|
216
238
|
.m-editor-history-list-item-index {
|
|
217
239
|
flex: 0 0 auto;
|
|
240
|
+
// 固定最小宽度并右对齐:序号位数不一(#6 / #16)时右边界仍统一,
|
|
241
|
+
// 使紧随其后的「类型」徽标在各行间对齐成整齐的一列。
|
|
242
|
+
min-width: 30px;
|
|
243
|
+
text-align: right;
|
|
218
244
|
color: #909399;
|
|
219
245
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
220
246
|
font-size: 11px;
|
|
@@ -222,6 +248,15 @@
|
|
|
222
248
|
white-space: nowrap;
|
|
223
249
|
}
|
|
224
250
|
|
|
251
|
+
// 合并组头部展示的是步骤区间(如 #10-#20),宽度本就不定、也无需与单步行对齐,
|
|
252
|
+
// 恢复自然宽度与左对齐,避免被强制成固定列后显得突兀。
|
|
253
|
+
.m-editor-history-list-group.is-merged
|
|
254
|
+
> .m-editor-history-list-group-head
|
|
255
|
+
> .m-editor-history-list-item-index {
|
|
256
|
+
min-width: 0;
|
|
257
|
+
text-align: left;
|
|
258
|
+
}
|
|
259
|
+
|
|
225
260
|
// 操作时间:弱化展示,紧贴在描述之后、各操作按钮之前。
|
|
226
261
|
.m-editor-history-list-item-time {
|
|
227
262
|
flex: 0 0 auto;
|
|
@@ -295,6 +330,20 @@
|
|
|
295
330
|
font-weight: 400; // 防止被合并组头部的粗体继承
|
|
296
331
|
}
|
|
297
332
|
|
|
333
|
+
// 「已保存」徽标:绿色实心胶囊,标记最近一次保存对应的历史记录(与 historyService.markSaved 对应)。
|
|
334
|
+
.m-editor-history-list-item-saved {
|
|
335
|
+
flex: 0 0 auto;
|
|
336
|
+
padding: 0 6px;
|
|
337
|
+
border-radius: 8px;
|
|
338
|
+
font-size: 10px;
|
|
339
|
+
line-height: 16px;
|
|
340
|
+
color: #fff;
|
|
341
|
+
background-color: #67c23a;
|
|
342
|
+
white-space: nowrap;
|
|
343
|
+
font-weight: 500;
|
|
344
|
+
letter-spacing: 0.2px;
|
|
345
|
+
}
|
|
346
|
+
|
|
298
347
|
// 「合并 N 步」徽标:紫色实心胶囊,与合并组卡片色系一致,醒目区分单步条目。
|
|
299
348
|
.m-editor-history-list-item-merge {
|
|
300
349
|
flex: 0 0 auto;
|
|
@@ -308,6 +357,24 @@
|
|
|
308
357
|
letter-spacing: 0.2px;
|
|
309
358
|
}
|
|
310
359
|
|
|
360
|
+
// 操作区:把「回滚 / 回到 / 查看差异」收敛为一个统一容器,默认隐藏,
|
|
361
|
+
// 仅在指针悬停于所在行时显示。静止状态下每行最右侧固定为「时间」,
|
|
362
|
+
// 各行因此能对齐成整齐的右侧列,避免按钮数量不一导致的参差错乱。
|
|
363
|
+
.m-editor-history-list-item-actions {
|
|
364
|
+
display: none;
|
|
365
|
+
flex: 0 0 auto;
|
|
366
|
+
align-items: center;
|
|
367
|
+
gap: 6px;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.m-editor-history-list-group-head:hover > .m-editor-history-list-item-actions,
|
|
371
|
+
.m-editor-history-list-substeps
|
|
372
|
+
> li:hover
|
|
373
|
+
> .m-editor-history-list-item-actions,
|
|
374
|
+
.m-editor-history-list-initial:hover > .m-editor-history-list-item-actions {
|
|
375
|
+
display: flex;
|
|
376
|
+
}
|
|
377
|
+
|
|
311
378
|
.m-editor-history-list-item-diff {
|
|
312
379
|
flex: 0 0 auto;
|
|
313
380
|
padding: 0 6px;
|
|
@@ -324,21 +391,21 @@
|
|
|
324
391
|
}
|
|
325
392
|
}
|
|
326
393
|
|
|
327
|
-
//
|
|
328
|
-
//
|
|
394
|
+
// 「回到」按钮:将历史游标移动到该 step。使用绿色色系,
|
|
395
|
+
// 与红色「回滚」、蓝色「查看差异」区分,也避免与紧邻的灰色「来源」徽标混淆。
|
|
329
396
|
.m-editor-history-list-item-goto {
|
|
330
397
|
flex: 0 0 auto;
|
|
331
398
|
padding: 0 6px;
|
|
332
399
|
border-radius: 2px;
|
|
333
400
|
font-size: 10px;
|
|
334
401
|
line-height: 16px;
|
|
335
|
-
color: #
|
|
336
|
-
background-color: rgba(
|
|
402
|
+
color: #529b2e;
|
|
403
|
+
background-color: rgba(103, 194, 58, 0.12);
|
|
337
404
|
cursor: pointer;
|
|
338
405
|
user-select: none;
|
|
339
406
|
|
|
340
407
|
&:hover {
|
|
341
|
-
background-color: rgba(
|
|
408
|
+
background-color: rgba(103, 194, 58, 0.24);
|
|
342
409
|
}
|
|
343
410
|
}
|
|
344
411
|
|
package/src/theme/page-bar.scss
CHANGED
|
@@ -24,9 +24,12 @@
|
|
|
24
24
|
& + .border-icon {
|
|
25
25
|
margin-left: 8px;
|
|
26
26
|
}
|
|
27
|
+
&.configured {
|
|
28
|
+
border-color: var(--el-color-success, var(--td-success-color, #2ba471));
|
|
29
|
+
}
|
|
27
30
|
&.active {
|
|
28
31
|
border-width: 1px;
|
|
29
|
-
border-color: var(--el-color-primary);
|
|
32
|
+
border-color: var(--el-color-primary, var(--td-brand-color, #0052d9));
|
|
30
33
|
}
|
|
31
34
|
&.border-icon-top {
|
|
32
35
|
border-top-width: 2px;
|
package/src/type.ts
CHANGED
|
@@ -56,7 +56,7 @@ import type { PropsService } from './services/props';
|
|
|
56
56
|
import type { StageOverlayService } from './services/stageOverlay';
|
|
57
57
|
import type { StorageService } from './services/storage';
|
|
58
58
|
import type { UiService } from './services/ui';
|
|
59
|
-
import type { UndoRedo } from './utils/undo-redo';
|
|
59
|
+
import type { SerializedUndoRedo, UndoRedo } from './utils/undo-redo';
|
|
60
60
|
|
|
61
61
|
export type EditorSlots = FrameworkSlots &
|
|
62
62
|
WorkspaceSlots &
|
|
@@ -312,6 +312,8 @@ export interface UiState {
|
|
|
312
312
|
hideSlideBar: boolean;
|
|
313
313
|
/** 侧边栏面板配置 */
|
|
314
314
|
sideBarItems: SideComponent[];
|
|
315
|
+
/** 当前激活的侧边栏面板 */
|
|
316
|
+
sideBarActiveTabName: string;
|
|
315
317
|
|
|
316
318
|
// navMenu 的宽高
|
|
317
319
|
navMenuRect: {
|
|
@@ -333,6 +335,7 @@ export interface EditorNodeInfo {
|
|
|
333
335
|
node: MNode | null;
|
|
334
336
|
parent: MContainer | null;
|
|
335
337
|
page: MPage | MPageFragment | null;
|
|
338
|
+
path: MNode[];
|
|
336
339
|
}
|
|
337
340
|
// #endregion EditorNodeInfo
|
|
338
341
|
|
|
@@ -390,6 +393,9 @@ export interface MenuButton {
|
|
|
390
393
|
items?: MenuButton[];
|
|
391
394
|
/** 唯一标识,用于高亮 */
|
|
392
395
|
id?: string | number;
|
|
396
|
+
buttonProps?: {
|
|
397
|
+
type?: string;
|
|
398
|
+
};
|
|
393
399
|
}
|
|
394
400
|
// #endregion MenuButton
|
|
395
401
|
|
|
@@ -680,7 +686,13 @@ export interface CodeParamStatement {
|
|
|
680
686
|
}
|
|
681
687
|
|
|
682
688
|
// #region HistoryOpType
|
|
683
|
-
|
|
689
|
+
/**
|
|
690
|
+
* 历史记录操作类型:
|
|
691
|
+
* - `add` / `remove` / `update`:普通可撤销/重做的节点变更;
|
|
692
|
+
* - `initial`:页面「未修改的初始状态」基线(设置 root 时生成),作为页面栈 index 0 的固定底线 step。
|
|
693
|
+
* 该 step 不可被撤销/回滚(cursor 不会低于它),仅用于历史面板底部的初始行展示。
|
|
694
|
+
*/
|
|
695
|
+
export type HistoryOpType = 'add' | 'remove' | 'update' | 'initial';
|
|
684
696
|
// #endregion HistoryOpType
|
|
685
697
|
|
|
686
698
|
// #region HistoryOpSource
|
|
@@ -705,11 +717,13 @@ export type HistoryOpType = 'add' | 'remove' | 'update';
|
|
|
705
717
|
* 通过 `(string & {})` 允许业务侧扩展自定义途径字符串,同时保留内置值的自动补全。
|
|
706
718
|
*/
|
|
707
719
|
export type HistoryOpSource =
|
|
720
|
+
| 'initial'
|
|
708
721
|
| 'stage'
|
|
709
722
|
| 'tree'
|
|
710
723
|
| 'component-panel'
|
|
711
724
|
| 'props'
|
|
712
725
|
| 'code'
|
|
726
|
+
| 'root-code'
|
|
713
727
|
| 'stage-contextmenu'
|
|
714
728
|
| 'tree-contextmenu'
|
|
715
729
|
| 'toolbar'
|
|
@@ -717,35 +731,69 @@ export type HistoryOpSource =
|
|
|
717
731
|
| 'rollback'
|
|
718
732
|
| 'api'
|
|
719
733
|
| 'ai'
|
|
734
|
+
// 同步
|
|
735
|
+
| 'sync'
|
|
720
736
|
| 'unknown'
|
|
721
737
|
| (string & {});
|
|
722
738
|
// #endregion HistoryOpSource
|
|
723
739
|
|
|
724
|
-
// #region
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
740
|
+
// #region DslOpWithHistoryIdsResult
|
|
741
|
+
/** *AndGetHistoryId 系列方法返回值:原操作结果 + 本次写入历史记录的 uuid 列表(未入栈时为 `[]`)。 */
|
|
742
|
+
export type DslOpWithHistoryIdsResult<T> = {
|
|
743
|
+
result: T;
|
|
744
|
+
historyIds: string[];
|
|
745
|
+
};
|
|
746
|
+
// #endregion DslOpWithHistoryIdsResult
|
|
747
|
+
|
|
748
|
+
// #region StepDiffItem
|
|
749
|
+
/**
|
|
750
|
+
* 单条变更的 diff 描述,统一表达「页面节点 / 代码块 / 数据源」的变化内容,
|
|
751
|
+
* 被 {@link StepValue} / {@link CodeBlockStepValue} / {@link DataSourceStepValue} 的 `diff` 复用。
|
|
752
|
+
*
|
|
753
|
+
* 按 `opType` 区分携带的字段:
|
|
754
|
+
* - `add`:仅 `newSchema`(页面节点还带 `parentId` / `index`);
|
|
755
|
+
* - `remove`:仅 `oldSchema`(页面节点还带 `parentId` / `index`);
|
|
756
|
+
* - `update`:`oldSchema` + `newSchema`,并可带 `changeRecords` 做局部更新。
|
|
757
|
+
*
|
|
758
|
+
* 泛型 `T` 为变化内容的快照类型:页面节点为 `MNode`,代码块为 `CodeBlockContent`,数据源为 `DataSourceSchema`。
|
|
759
|
+
*/
|
|
760
|
+
export interface StepDiffItem<T = unknown> {
|
|
761
|
+
/** 变更后的内容快照。`opType` 为 `add` / `update` 时有,`remove` 时无。 */
|
|
762
|
+
newSchema?: T;
|
|
763
|
+
/** 变更前的内容快照。`opType` 为 `remove` / `update` 时有,`add` 时无。 */
|
|
764
|
+
oldSchema?: T;
|
|
765
|
+
/** 父节点 id。仅页面节点有(数据源 / 代码块没有父节点)。 */
|
|
737
766
|
parentId?: Id;
|
|
738
|
-
/**
|
|
739
|
-
|
|
740
|
-
/** opType 'remove': 被删除的节点及其位置信息 */
|
|
741
|
-
removedItems?: { node: MNode; parentId: Id; index: number }[];
|
|
767
|
+
/** 在父节点 items 数组中的索引。仅页面节点有(数据源 / 代码块无需排序)。 */
|
|
768
|
+
index?: number;
|
|
742
769
|
/**
|
|
743
|
-
* opType
|
|
744
|
-
*
|
|
745
|
-
* `changeRecords` 来自 form 端的 propPath/value 列表,撤销/重做时只对这些 propPath 做局部更新;
|
|
746
|
-
* 缺省(未传 / 空数组)才退化为整节点替换。
|
|
770
|
+
* form 端 propPath/value 变更列表,仅 `opType` 为 `update` 时有;
|
|
771
|
+
* 撤销/重做时若有则按 propPath 局部更新,缺省才退化为整内容替换。
|
|
747
772
|
*/
|
|
748
|
-
|
|
773
|
+
changeRecords?: ChangeRecord[];
|
|
774
|
+
}
|
|
775
|
+
// #endregion StepDiffItem
|
|
776
|
+
|
|
777
|
+
// #region BaseStepValue
|
|
778
|
+
/**
|
|
779
|
+
* 历史记录条目公共字段,被 {@link StepValue} / {@link CodeBlockStepValue} / {@link DataSourceStepValue} 复用。
|
|
780
|
+
*
|
|
781
|
+
* 泛型 `T` 为 `diff` 中变化内容的快照类型(页面节点 `MNode` / 代码块 `CodeBlockContent` / 数据源 `DataSourceSchema`)。
|
|
782
|
+
*/
|
|
783
|
+
export interface BaseStepValue<T = unknown> {
|
|
784
|
+
/**
|
|
785
|
+
* 历史记录唯一标识(uuid)。入栈时自动写入(若调用方未指定),
|
|
786
|
+
* 用于精确定位 / 引用某一条历史记录(如 revert、埋点、跨端同步等)。
|
|
787
|
+
* 注意与各自的 `id`(关联的页面 / 代码块 / 数据源 id)区分。
|
|
788
|
+
*/
|
|
789
|
+
uuid: string;
|
|
790
|
+
/** 操作类型:新增 / 删除 / 更新(三类历史记录统一携带)。 */
|
|
791
|
+
opType: HistoryOpType;
|
|
792
|
+
/**
|
|
793
|
+
* 本次变更的内容(统一 diff 表达),每项见 {@link StepDiffItem}。
|
|
794
|
+
* 页面节点(add/remove 多节点、update 多节点)会有多项,代码块 / 数据源通常只有一项。
|
|
795
|
+
*/
|
|
796
|
+
diff: StepDiffItem<T>[];
|
|
749
797
|
/**
|
|
750
798
|
* 调用方可选传入的人类可读描述(如「调整按钮颜色」),用于历史面板展示。
|
|
751
799
|
* 不影响 undo/redo 行为;缺省时面板会根据节点 / propPath 自动生成描述。
|
|
@@ -758,65 +806,60 @@ export interface StepValue {
|
|
|
758
806
|
*/
|
|
759
807
|
source?: HistoryOpSource;
|
|
760
808
|
/**
|
|
761
|
-
*
|
|
809
|
+
* 入栈时间戳(毫秒)。入栈时自动写入(若调用方未指定),仅用于历史面板展示。
|
|
762
810
|
*/
|
|
763
811
|
timestamp?: number;
|
|
812
|
+
/**
|
|
813
|
+
* 是否为「已保存」记录:DSL 落库(如保存到后端 / 本地)时由 historyService.markSaved 标记。
|
|
814
|
+
* 同一栈内任意时刻最多只有一条记录为 true;从 IndexedDB 恢复时游标会被定位到最近一条已保存记录之后。
|
|
815
|
+
*/
|
|
816
|
+
saved?: boolean;
|
|
817
|
+
/**
|
|
818
|
+
* 是否为「整体设置 root」(set root)产生的记录(由 {@link Editor.pushRootDiffHistory} 写入)。
|
|
819
|
+
* 用于「连续 set root 合并」:当某页栈最新一条已是 root 记录时,下一条 set root 会替换它而非新增,
|
|
820
|
+
* 避免源码反复保存 / 外部重设 DSL 时堆积多条 root 记录。
|
|
821
|
+
*/
|
|
822
|
+
rootStep?: boolean;
|
|
823
|
+
}
|
|
824
|
+
// #endregion BaseStepValue
|
|
825
|
+
|
|
826
|
+
// #region StepValue
|
|
827
|
+
export interface StepValue extends BaseStepValue<MNode> {
|
|
828
|
+
/** 页面信息 */
|
|
829
|
+
data: { name: string; id: Id };
|
|
830
|
+
/** 操作前选中的节点 ID,用于撤销后恢复选择状态 */
|
|
831
|
+
selectedBefore: Id[];
|
|
832
|
+
/** 操作后选中的节点 ID,用于重做后恢复选择状态 */
|
|
833
|
+
selectedAfter: Id[];
|
|
834
|
+
modifiedNodeIds: Map<Id, Id>;
|
|
764
835
|
}
|
|
765
836
|
// #endregion StepValue
|
|
766
837
|
|
|
767
838
|
// #region CodeBlockStepValue
|
|
768
839
|
/**
|
|
769
840
|
* 代码块历史记录条目。按 codeBlock.id 分组保存到 historyState.codeBlockState。
|
|
770
|
-
*
|
|
771
|
-
* -
|
|
772
|
-
* -
|
|
841
|
+
* 变更内容统一由 `diff`(单项)表达,每项见 {@link StepDiffItem}:
|
|
842
|
+
* - 新增(opType 'add'):仅 `newSchema`(新内容);
|
|
843
|
+
* - 更新(opType 'update'):`oldSchema` + `newSchema`,并可带 `changeRecords` 做局部更新;
|
|
844
|
+
* - 删除(opType 'remove'):仅 `oldSchema`(删除前内容)。
|
|
773
845
|
*/
|
|
774
|
-
export interface CodeBlockStepValue {
|
|
846
|
+
export interface CodeBlockStepValue extends BaseStepValue<CodeBlockContent> {
|
|
775
847
|
/** 关联的代码块 id */
|
|
776
848
|
id: Id;
|
|
777
|
-
/** 变更前的代码块内容,新增时为 null */
|
|
778
|
-
oldContent: CodeBlockContent | null;
|
|
779
|
-
/** 变更后的代码块内容,删除时为 null */
|
|
780
|
-
newContent: CodeBlockContent | null;
|
|
781
|
-
/**
|
|
782
|
-
* form 端 propPath/value 列表。撤销/重做时若有则按 propPath 局部更新;
|
|
783
|
-
* 缺省才退化为整内容替换。新增/删除场景通常无 changeRecords。
|
|
784
|
-
*/
|
|
785
|
-
changeRecords?: ChangeRecord[];
|
|
786
|
-
/** 调用方可选传入的人类可读描述,用于历史面板展示;不影响 undo/redo 行为。 */
|
|
787
|
-
historyDescription?: string;
|
|
788
|
-
/** 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource};仅用于历史面板展示与埋点,不影响 undo/redo 行为。 */
|
|
789
|
-
source?: HistoryOpSource;
|
|
790
|
-
/** 入栈时间戳(毫秒),入栈时自动写入,仅用于历史面板展示。 */
|
|
791
|
-
timestamp?: number;
|
|
792
849
|
}
|
|
793
850
|
// #endregion CodeBlockStepValue
|
|
794
851
|
|
|
795
852
|
// #region DataSourceStepValue
|
|
796
853
|
/**
|
|
797
854
|
* 数据源历史记录条目。按 dataSource.id 分组保存到 historyState.dataSourceState。
|
|
798
|
-
*
|
|
799
|
-
* -
|
|
800
|
-
* -
|
|
855
|
+
* 变更内容统一由 `diff`(单项)表达,每项见 {@link StepDiffItem}:
|
|
856
|
+
* - 新增(opType 'add'):仅 `newSchema`(新 schema);
|
|
857
|
+
* - 更新(opType 'update'):`oldSchema` + `newSchema`,并可带 `changeRecords` 做局部更新;
|
|
858
|
+
* - 删除(opType 'remove'):仅 `oldSchema`(删除前 schema)。
|
|
801
859
|
*/
|
|
802
|
-
export interface DataSourceStepValue {
|
|
860
|
+
export interface DataSourceStepValue extends BaseStepValue<DataSourceSchema> {
|
|
803
861
|
/** 关联的数据源 id */
|
|
804
862
|
id: Id;
|
|
805
|
-
/** 变更前的数据源 schema,新增时为 null */
|
|
806
|
-
oldSchema: DataSourceSchema | null;
|
|
807
|
-
/** 变更后的数据源 schema,删除时为 null */
|
|
808
|
-
newSchema: DataSourceSchema | null;
|
|
809
|
-
/**
|
|
810
|
-
* form 端 propPath/value 列表。撤销/重做时若有则按 propPath 局部更新;
|
|
811
|
-
* 缺省才退化为整 schema 替换。新增/删除场景通常无 changeRecords。
|
|
812
|
-
*/
|
|
813
|
-
changeRecords?: ChangeRecord[];
|
|
814
|
-
/** 调用方可选传入的人类可读描述,用于历史面板展示;不影响 undo/redo 行为。 */
|
|
815
|
-
historyDescription?: string;
|
|
816
|
-
/** 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource};仅用于历史面板展示与埋点,不影响 undo/redo 行为。 */
|
|
817
|
-
source?: HistoryOpSource;
|
|
818
|
-
/** 入栈时间戳(毫秒),入栈时自动写入,仅用于历史面板展示。 */
|
|
819
|
-
timestamp?: number;
|
|
820
863
|
}
|
|
821
864
|
// #endregion DataSourceStepValue
|
|
822
865
|
|
|
@@ -837,6 +880,45 @@ export interface HistoryState {
|
|
|
837
880
|
dataSourceState: Record<Id, UndoRedo<DataSourceStepValue>>;
|
|
838
881
|
}
|
|
839
882
|
|
|
883
|
+
// #region PersistedHistoryState
|
|
884
|
+
/**
|
|
885
|
+
* 历史记录的可持久化快照。由 historyService.saveToIndexedDB 写入 IndexedDB,
|
|
886
|
+
* 再由 historyService.restoreFromIndexedDB 读出并重建各 UndoRedo 栈。
|
|
887
|
+
*/
|
|
888
|
+
export interface PersistedHistoryState {
|
|
889
|
+
/** 快照结构版本号,便于后续兼容升级。 */
|
|
890
|
+
version: number;
|
|
891
|
+
/** 保存时的活动页 id。 */
|
|
892
|
+
pageId?: Id;
|
|
893
|
+
/** 各页面历史栈的序列化快照,按 pageId 分组。 */
|
|
894
|
+
pageSteps: Record<Id, SerializedUndoRedo<StepValue>>;
|
|
895
|
+
/** 各代码块历史栈的序列化快照,按 codeBlockId 分组。 */
|
|
896
|
+
codeBlockState: Record<Id, SerializedUndoRedo<CodeBlockStepValue>>;
|
|
897
|
+
/** 各数据源历史栈的序列化快照,按 dataSourceId 分组。 */
|
|
898
|
+
dataSourceState: Record<Id, SerializedUndoRedo<DataSourceStepValue>>;
|
|
899
|
+
/** 保存时间戳(毫秒)。 */
|
|
900
|
+
savedAt: number;
|
|
901
|
+
}
|
|
902
|
+
// #endregion PersistedHistoryState
|
|
903
|
+
|
|
904
|
+
// #region HistoryPersistOptions
|
|
905
|
+
/** historyService 持久化相关 API 的可选配置。 */
|
|
906
|
+
export interface HistoryPersistOptions {
|
|
907
|
+
/** IndexedDB 数据库名,默认 `tmagic-editor`(最终库名会拼上当前 DSL app id)。 */
|
|
908
|
+
dbName?: string;
|
|
909
|
+
/** objectStore 名,默认 `history`。 */
|
|
910
|
+
storeName?: string;
|
|
911
|
+
/** 记录 key,用于区分不同活动页 / 项目,默认 `default`。 */
|
|
912
|
+
key?: IDBValidKey;
|
|
913
|
+
/**
|
|
914
|
+
* 显式指定用于库名隔离的 DSL app id。
|
|
915
|
+
* 缺省时回退到当前 editorService 的 `root.id`;在「先恢复历史再 set root」场景下 root 尚未设置,
|
|
916
|
+
* 需由调用方(如从待加载 DSL 取 id)显式传入,否则会读 / 写到未按 app 隔离的默认库。
|
|
917
|
+
*/
|
|
918
|
+
appId?: Id;
|
|
919
|
+
}
|
|
920
|
+
// #endregion HistoryPersistOptions
|
|
921
|
+
|
|
840
922
|
// #region HistoryListEntry
|
|
841
923
|
/**
|
|
842
924
|
* 历史面板用:当前页面的一条历史步骤(包含位置和是否已应用)。
|
|
@@ -1074,6 +1156,8 @@ export type SyncHookPlugin<
|
|
|
1074
1156
|
|
|
1075
1157
|
export interface EventBusEvent {
|
|
1076
1158
|
'edit-data-source': [id: string];
|
|
1159
|
+
'edit-data-source-method': [id: string, methodName: string];
|
|
1160
|
+
'edit-data-source-field': [id: string, fieldPath: string[]];
|
|
1077
1161
|
'remove-data-source': [id: string];
|
|
1078
1162
|
'edit-code': [id: string];
|
|
1079
1163
|
}
|
|
@@ -1107,7 +1191,11 @@ export type CustomContentMenuFunction = (
|
|
|
1107
1191
|
) => (MenuButton | MenuComponent)[];
|
|
1108
1192
|
|
|
1109
1193
|
export interface EditorEvents {
|
|
1110
|
-
'root-change': [
|
|
1194
|
+
'root-change': [
|
|
1195
|
+
value: StoreState['root'],
|
|
1196
|
+
preValue?: StoreState['root'],
|
|
1197
|
+
options?: { historySource?: HistoryOpSource },
|
|
1198
|
+
];
|
|
1111
1199
|
select: [node: MNode | null];
|
|
1112
1200
|
add: [nodes: MNode[]];
|
|
1113
1201
|
remove: [nodes: MNode[]];
|
|
@@ -1202,3 +1290,34 @@ export interface DiffDialogPayload {
|
|
|
1202
1290
|
/** 用于标题展示的目标 id */
|
|
1203
1291
|
id?: string | number;
|
|
1204
1292
|
}
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* 一组「描述 + 可操作性」的判定函数集合。页面 / 数据源 / 代码块及业务自定义历史
|
|
1296
|
+
* 各自实现一份,作为整体注入,避免把 describe* / isStep* 拆成多个独立 props 反复透传。
|
|
1297
|
+
*/
|
|
1298
|
+
export interface HistoryRowDescriptor<T extends BaseStepValue = BaseStepValue> {
|
|
1299
|
+
/** 组级描述文案生成器,接收一个 group,返回展示文本。 */
|
|
1300
|
+
describeGroup: (_group: any) => string;
|
|
1301
|
+
/** 单步描述文案生成器,接收一个 step,返回展示文本(合并组展开后的子步列表用)。 */
|
|
1302
|
+
describeStep: (_step: T) => string;
|
|
1303
|
+
/** 判断某个 step 是否可查看差异(前后值都存在)。不传则一律不展示差异入口。 */
|
|
1304
|
+
isStepDiffable?: (_step: T) => boolean;
|
|
1305
|
+
/** 判断某个 step 是否支持回滚(如更新需带 changeRecords)。不传则已应用即可回滚。 */
|
|
1306
|
+
isStepRevertable?: (_step: T) => boolean;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* 通用 bucket(数据源 / 代码块 / 业务自定义历史)的整体渲染配置。
|
|
1311
|
+
* 把原先散落在 Bucket / BucketTab 上的 title / prefix / describe* / isStep* / showInitial / gotoEnabled
|
|
1312
|
+
* 收敛成一个对象作为单一 prop 传递,调用方一次配齐、组件内部按需读取。
|
|
1313
|
+
*/
|
|
1314
|
+
export interface HistoryBucketConfig<T extends BaseStepValue = BaseStepValue> extends HistoryRowDescriptor<T> {
|
|
1315
|
+
/** bucket 头部标题,例如 "数据源" / "代码块"。 */
|
|
1316
|
+
title: string;
|
|
1317
|
+
/** 子项 key 的命名空间前缀(`ds` 数据源 / `cb` 代码块 / 业务自定义如 `mod`)。 */
|
|
1318
|
+
prefix: string;
|
|
1319
|
+
/** 是否展示底部「回到初始状态」入口,默认 true。无 undo cursor 语义的自定义历史可传 false。 */
|
|
1320
|
+
showInitial?: boolean;
|
|
1321
|
+
/** 是否支持「跳转到该记录」(goto),默认 true。 */
|
|
1322
|
+
gotoEnabled?: boolean;
|
|
1323
|
+
}
|
|
@@ -10,6 +10,7 @@ const dataSourceFormConfig: TabConfig = {
|
|
|
10
10
|
items: [
|
|
11
11
|
{
|
|
12
12
|
title: '数据定义',
|
|
13
|
+
status: 'fields',
|
|
13
14
|
items: [
|
|
14
15
|
{
|
|
15
16
|
name: 'fields',
|
|
@@ -20,6 +21,7 @@ const dataSourceFormConfig: TabConfig = {
|
|
|
20
21
|
},
|
|
21
22
|
{
|
|
22
23
|
title: '方法定义',
|
|
24
|
+
status: 'methods',
|
|
23
25
|
items: [
|
|
24
26
|
{
|
|
25
27
|
name: 'methods',
|