@tmagic/editor 1.8.0-beta.5 → 1.8.0-beta.7
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/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 +2 -2
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +10 -14
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +12 -4
- package/dist/es/layouts/history-list/composables.js +28 -77
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +2 -2
- 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 +30 -19
- package/dist/es/services/dataSource.js +29 -21
- package/dist/es/services/editor.js +52 -33
- package/dist/es/services/history.js +10 -15
- package/dist/es/style.css +4 -1
- package/dist/es/utils/data-source/index.js +2 -0
- package/dist/es/utils/editor.js +68 -48
- package/dist/es/utils/history.js +42 -33
- package/dist/style.css +4 -1
- package/dist/tmagic-editor.umd.cjs +412 -295
- package/package.json +7 -7
- 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/layouts/history-list/HistoryListPanel.vue +12 -25
- package/src/layouts/history-list/InitialRow.vue +3 -0
- package/src/layouts/history-list/composables.ts +34 -94
- package/src/layouts/sidebar/Sidebar.vue +2 -2
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +31 -2
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +26 -1
- package/src/services/codeBlock.ts +28 -22
- package/src/services/dataSource.ts +29 -24
- package/src/services/editor.ts +41 -37
- package/src/services/history.ts +19 -25
- package/src/theme/style-setter/border.scss +4 -1
- package/src/type.ts +38 -26
- package/src/utils/data-source/index.ts +2 -0
- package/src/utils/editor.ts +125 -59
- package/src/utils/history.ts +48 -45
- package/types/index.d.ts +109 -112
|
@@ -5112,46 +5112,29 @@
|
|
|
5112
5112
|
};
|
|
5113
5113
|
/**
|
|
5114
5114
|
* 把单个「按 id 分栈」的历史栈(代码块 / 数据源)拆成若干 group:
|
|
5115
|
-
*
|
|
5116
|
-
* - 连续 'update' 合并到同一组,组内 steps 顺序就是发生顺序。
|
|
5115
|
+
* 每条操作记录独立成组,不做相邻 update 合并(与页面历史的合并策略不同)。
|
|
5117
5116
|
*
|
|
5118
5117
|
* 代码块与数据源除 `kind` 外结构完全一致,统一由本方法处理;`kind` 决定返回的具体分组类型。
|
|
5119
5118
|
*/
|
|
5120
5119
|
var mergeStackSteps = (kind, id, list, cursor) => {
|
|
5121
|
-
const groups = [];
|
|
5122
|
-
let current = null;
|
|
5123
5120
|
const currentIndex = cursor - 1;
|
|
5124
|
-
list.
|
|
5125
|
-
const { opType } = step;
|
|
5121
|
+
return list.map((step, index) => {
|
|
5126
5122
|
const applied = index < cursor;
|
|
5127
5123
|
const isCurrent = index === currentIndex;
|
|
5128
|
-
|
|
5129
|
-
|
|
5124
|
+
return {
|
|
5125
|
+
kind,
|
|
5126
|
+
id,
|
|
5127
|
+
opType: step.opType,
|
|
5128
|
+
steps: [{
|
|
5130
5129
|
step,
|
|
5131
5130
|
index,
|
|
5132
5131
|
applied,
|
|
5133
5132
|
isCurrent
|
|
5134
|
-
}
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
}
|
|
5138
|
-
current = {
|
|
5139
|
-
kind,
|
|
5140
|
-
id,
|
|
5141
|
-
opType,
|
|
5142
|
-
steps: [{
|
|
5143
|
-
step,
|
|
5144
|
-
index,
|
|
5145
|
-
applied,
|
|
5146
|
-
isCurrent
|
|
5147
|
-
}],
|
|
5148
|
-
applied,
|
|
5149
|
-
isCurrent
|
|
5150
|
-
};
|
|
5151
|
-
groups.push(current);
|
|
5152
|
-
}
|
|
5133
|
+
}],
|
|
5134
|
+
applied,
|
|
5135
|
+
isCurrent
|
|
5136
|
+
};
|
|
5153
5137
|
});
|
|
5154
|
-
return groups;
|
|
5155
5138
|
};
|
|
5156
5139
|
/**
|
|
5157
5140
|
* 把页面栈拆成若干 group:
|
|
@@ -5232,22 +5215,45 @@
|
|
|
5232
5215
|
return items?.length ? `${items.length} 个节点` : void 0;
|
|
5233
5216
|
}
|
|
5234
5217
|
};
|
|
5235
|
-
/**
|
|
5218
|
+
/**
|
|
5219
|
+
* 把 `Record<Id, UndoRedo>` 整体序列化为 `Record<Id, SerializedUndoRedo>`。
|
|
5220
|
+
*
|
|
5221
|
+
* 序列化(深克隆)的同一趟里,只把每条 step 中可能含函数的 `diff` 用 serialize-javascript 序列化成字符串,
|
|
5222
|
+
* 其余字段(uuid / opType / timestamp / `modifiedNodeIds` Map 等)原样保留,交给 IndexedDB 结构化克隆。
|
|
5223
|
+
* 这样既能写入函数,又避免序列化整份快照的开销;读取时再由 {@link parseStacksStepDiff} 还原 diff。
|
|
5224
|
+
* 不含 `diff` 的元素(如通用栈)原样透传。
|
|
5225
|
+
*/
|
|
5236
5226
|
var serializeStacks = (stacks) => {
|
|
5237
5227
|
const result = {};
|
|
5238
5228
|
Object.entries(stacks).forEach(([id, undoRedo]) => {
|
|
5239
|
-
if (undoRedo)
|
|
5229
|
+
if (!undoRedo) return;
|
|
5230
|
+
const serialized = undoRedo.serialize();
|
|
5231
|
+
result[id] = {
|
|
5232
|
+
...serialized,
|
|
5233
|
+
elementList: serialized.elementList.map((step) => step.diff === void 0 ? step : Object.assign({}, step, { diff: (0, serialize_javascript.default)(step.diff) }))
|
|
5234
|
+
};
|
|
5240
5235
|
});
|
|
5241
5236
|
return result;
|
|
5242
5237
|
};
|
|
5243
5238
|
/**
|
|
5244
5239
|
* 把 `Record<Id, SerializedUndoRedo>` 整体还原为 `Record<Id, UndoRedo>`。
|
|
5245
5240
|
* 还原时把每个栈的游标定位到最近一条已保存(`saved === true`)记录之后。
|
|
5241
|
+
*
|
|
5242
|
+
* 与 {@link serializeStacks} 相反:当传入 `parse`(parseDSL)时,把每条 step 中以字符串形式存储的 `diff`
|
|
5243
|
+
* 解析回真实对象(含函数);不含 `diff` 的元素(如通用栈)原样透传。
|
|
5246
5244
|
*/
|
|
5247
|
-
var deserializeStacks = (stacks = {}) => {
|
|
5245
|
+
var deserializeStacks = (stacks = {}, parse) => {
|
|
5248
5246
|
const result = {};
|
|
5249
5247
|
Object.entries(stacks).forEach(([id, serialized]) => {
|
|
5250
|
-
if (serialized)
|
|
5248
|
+
if (!serialized) return;
|
|
5249
|
+
const elementList = parse ? serialized.elementList.map((step) => {
|
|
5250
|
+
const { diff } = step;
|
|
5251
|
+
return typeof diff === "string" ? Object.assign({}, step, { diff: parse(`(${diff})`) }) : step;
|
|
5252
|
+
}) : serialized.elementList;
|
|
5253
|
+
result[id] = UndoRedo.fromSerialized({
|
|
5254
|
+
...serialized,
|
|
5255
|
+
elementList
|
|
5256
|
+
}, { isSavedStep: (element) => element.saved === true });
|
|
5251
5257
|
});
|
|
5252
5258
|
return result;
|
|
5253
5259
|
};
|
|
@@ -5265,6 +5271,8 @@
|
|
|
5265
5271
|
var undoFloor = (undoRedo) => {
|
|
5266
5272
|
return undoRedo.getElementList()[0]?.opType === "initial" ? 1 : 0;
|
|
5267
5273
|
};
|
|
5274
|
+
/** 将单次 push 产生的 history uuid(或 null)转为 *AndGetHistoryId 返回用的 uuid 列表。 */
|
|
5275
|
+
var getLastPushedHistoryIds = (historyId) => historyId ? [historyId] : [];
|
|
5268
5276
|
//#endregion
|
|
5269
5277
|
//#region packages/editor/src/utils/indexed-db.ts
|
|
5270
5278
|
/**
|
|
@@ -5356,7 +5364,7 @@
|
|
|
5356
5364
|
var DEFAULT_DB_NAME = "tmagic-editor";
|
|
5357
5365
|
var DEFAULT_STORE_NAME = "history";
|
|
5358
5366
|
var DEFAULT_KEY = "default";
|
|
5359
|
-
var PERSIST_VERSION =
|
|
5367
|
+
var PERSIST_VERSION = 2;
|
|
5360
5368
|
var History = class extends BaseService {
|
|
5361
5369
|
state = (0, vue.reactive)({
|
|
5362
5370
|
pageSteps: {},
|
|
@@ -5679,7 +5687,7 @@
|
|
|
5679
5687
|
dataSourceState: serializeStacks(this.state.dataSourceState),
|
|
5680
5688
|
savedAt: Date.now()
|
|
5681
5689
|
};
|
|
5682
|
-
await idbSet(this.resolveDbName(dbName, appId), storeName, key,
|
|
5690
|
+
await idbSet(this.resolveDbName(dbName, appId), storeName, key, snapshot);
|
|
5683
5691
|
this.emit("save-to-indexed-db", snapshot);
|
|
5684
5692
|
return snapshot;
|
|
5685
5693
|
}
|
|
@@ -5693,13 +5701,12 @@
|
|
|
5693
5701
|
*/
|
|
5694
5702
|
async restoreFromIndexedDB(options = {}) {
|
|
5695
5703
|
const { dbName = DEFAULT_DB_NAME, storeName = DEFAULT_STORE_NAME, key = DEFAULT_KEY, appId } = options;
|
|
5696
|
-
const
|
|
5697
|
-
if (!raw) return null;
|
|
5698
|
-
const snapshot = typeof raw === "string" ? getEditorConfig("parseDSL")(`(${raw})`) : raw;
|
|
5704
|
+
const snapshot = await idbGet(this.resolveDbName(dbName, appId), storeName, key);
|
|
5699
5705
|
if (!snapshot) return null;
|
|
5700
|
-
|
|
5701
|
-
this.state.
|
|
5702
|
-
this.state.
|
|
5706
|
+
const parseDSL = getEditorConfig("parseDSL");
|
|
5707
|
+
this.state.pageSteps = deserializeStacks(snapshot.pageSteps, parseDSL);
|
|
5708
|
+
this.state.codeBlockState = deserializeStacks(snapshot.codeBlockState, parseDSL);
|
|
5709
|
+
this.state.dataSourceState = deserializeStacks(snapshot.dataSourceState, parseDSL);
|
|
5703
5710
|
this.state.pageId = snapshot.pageId;
|
|
5704
5711
|
this.setCanUndoRedo();
|
|
5705
5712
|
this.emit("restore-from-indexed-db", snapshot);
|
|
@@ -5739,11 +5746,8 @@
|
|
|
5739
5746
|
return mergePageSteps(targetPageId, list, undoRedo.getCursor()).filter((group) => group.opType !== "initial");
|
|
5740
5747
|
}
|
|
5741
5748
|
/**
|
|
5742
|
-
* 取出全部代码块的历史栈,按 codeBlockId
|
|
5743
|
-
*
|
|
5744
|
-
* - 这正是"代码块/数据源各自按 id 分栈"的天然表现,再叠加"连续修改同目标的相邻步骤合并展示"。
|
|
5745
|
-
* - 合并后 group 暴露子步骤数组,UI 可展开查看每一步的 changeRecords。
|
|
5746
|
-
* - applied 字段:组内最后一步是否处于已应用段。
|
|
5749
|
+
* 取出全部代码块的历史栈,按 codeBlockId 分桶展示。
|
|
5750
|
+
* 同一栈内每条操作记录独立成组,不做相邻 update 合并。
|
|
5747
5751
|
*/
|
|
5748
5752
|
getCodeBlockHistoryGroups() {
|
|
5749
5753
|
const groups = [];
|
|
@@ -5840,7 +5844,7 @@
|
|
|
5840
5844
|
return null;
|
|
5841
5845
|
}
|
|
5842
5846
|
/**
|
|
5843
|
-
* 取出全部数据源的历史栈,按 dataSourceId
|
|
5847
|
+
* 取出全部数据源的历史栈,按 dataSourceId 分桶展示。同上,每条操作独立成组。
|
|
5844
5848
|
*/
|
|
5845
5849
|
getDataSourceHistoryGroups() {
|
|
5846
5850
|
const groups = [];
|
|
@@ -6073,12 +6077,26 @@
|
|
|
6073
6077
|
}
|
|
6074
6078
|
return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2;
|
|
6075
6079
|
};
|
|
6080
|
+
var removeConflictPosition = (style, primary, secondary) => {
|
|
6081
|
+
const isInvalid = (value) => value === "" || value === 0 || value === void 0 || value === null;
|
|
6082
|
+
if (!(primary in style) || !(secondary in style)) return;
|
|
6083
|
+
const primaryValue = style[primary];
|
|
6084
|
+
const secondaryValue = style[secondary];
|
|
6085
|
+
const primaryInvalid = isInvalid(primaryValue);
|
|
6086
|
+
const secondaryInvalid = isInvalid(secondaryValue);
|
|
6087
|
+
if (primaryInvalid && !secondaryInvalid) delete style[primary];
|
|
6088
|
+
else if (secondaryInvalid && !primaryInvalid) delete style[secondary];
|
|
6089
|
+
else if (primaryInvalid && secondaryInvalid) if (secondaryValue === 0 && primaryValue !== 0) delete style[primary];
|
|
6090
|
+
else delete style[secondary];
|
|
6091
|
+
};
|
|
6076
6092
|
var getInitPositionStyle = (style = {}, layout) => {
|
|
6077
6093
|
if (layout === Layout.ABSOLUTE) {
|
|
6078
6094
|
const newStyle = {
|
|
6079
6095
|
...style,
|
|
6080
6096
|
position: "absolute"
|
|
6081
6097
|
};
|
|
6098
|
+
removeConflictPosition(newStyle, "left", "right");
|
|
6099
|
+
removeConflictPosition(newStyle, "top", "bottom");
|
|
6082
6100
|
if (typeof newStyle.left === "undefined" && typeof newStyle.right === "undefined") newStyle.left = 0;
|
|
6083
6101
|
return newStyle;
|
|
6084
6102
|
}
|
|
@@ -6103,58 +6121,63 @@
|
|
|
6103
6121
|
}
|
|
6104
6122
|
return node;
|
|
6105
6123
|
};
|
|
6106
|
-
var
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6124
|
+
var hasPositionValue = (style, key) => typeof style?.[key] !== "undefined" && style?.[key] !== "";
|
|
6125
|
+
/**
|
|
6126
|
+
* 沿节点路径累加(或抵消)某一方向上的定位偏移量
|
|
6127
|
+
* 当路径上的祖先使用了反方向定位(例如计算 left 时祖先用了 right)或非数值定位时,
|
|
6128
|
+
* 无法简单地通过求和换算坐标,此时返回 0 表示放弃补偿、保持原值
|
|
6129
|
+
* @param path 从根到目标节点的路径(含节点自身)
|
|
6130
|
+
* @param dir 需要累加的定位方向
|
|
6131
|
+
* @param opposite 反方向定位属性
|
|
6132
|
+
* @param sign change2Fixed 取 1(累加祖先偏移),Fixed2Other 取 -1(抵消祖先偏移)
|
|
6133
|
+
* @param init 偏移量初始值
|
|
6134
|
+
*/
|
|
6135
|
+
var accumulatePositionOffset = (path, dir, opposite, sign, init = 0) => {
|
|
6136
|
+
let offset = init;
|
|
6137
|
+
for (const value of path) {
|
|
6138
|
+
if (hasPositionValue(value.style, opposite) || !(0, _tmagic_utils.isNumber)(value.style?.[dir] || 0)) return 0;
|
|
6139
|
+
offset = offset + sign * Number(value.style?.[dir] || 0);
|
|
6119
6140
|
}
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6141
|
+
return offset;
|
|
6142
|
+
};
|
|
6143
|
+
var change2Fixed = (node, path) => {
|
|
6144
|
+
const style = { ...node.style || {} };
|
|
6145
|
+
if (!hasPositionValue(node.style, "right") && (0, _tmagic_utils.isNumber)(node.style?.left || 0)) {
|
|
6146
|
+
const left = accumulatePositionOffset(path, "left", "right", 1);
|
|
6147
|
+
if (left) style.left = left;
|
|
6148
|
+
} else if (hasPositionValue(node.style, "right") && (0, _tmagic_utils.isNumber)(node.style?.right || 0)) {
|
|
6149
|
+
const right = accumulatePositionOffset(path, "right", "left", 1);
|
|
6150
|
+
if (right) style.right = right;
|
|
6151
|
+
}
|
|
6152
|
+
if (!hasPositionValue(node.style, "bottom") && (0, _tmagic_utils.isNumber)(node.style?.top || 0)) {
|
|
6153
|
+
const top = accumulatePositionOffset(path, "top", "bottom", 1);
|
|
6154
|
+
if (top) style.top = top;
|
|
6155
|
+
} else if (hasPositionValue(node.style, "bottom") && (0, _tmagic_utils.isNumber)(node.style?.bottom || 0)) {
|
|
6156
|
+
const bottom = accumulatePositionOffset(path, "bottom", "top", 1);
|
|
6157
|
+
if (bottom) style.bottom = bottom;
|
|
6126
6158
|
}
|
|
6127
|
-
if (offset.left) style.left = offset.left;
|
|
6128
|
-
if (offset.top) style.top = offset.top;
|
|
6129
6159
|
return style;
|
|
6130
6160
|
};
|
|
6131
|
-
var Fixed2Other = async (node,
|
|
6132
|
-
const path = (0, _tmagic_utils.getNodePath)(node.id, root.items);
|
|
6161
|
+
var Fixed2Other = async (node, path, getLayout) => {
|
|
6133
6162
|
const cur = path.pop();
|
|
6134
6163
|
const offset = {
|
|
6135
|
-
left:
|
|
6136
|
-
top:
|
|
6164
|
+
left: 0,
|
|
6165
|
+
top: 0,
|
|
6166
|
+
right: 0,
|
|
6167
|
+
bottom: 0
|
|
6137
6168
|
};
|
|
6138
|
-
if (!node.style
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
}
|
|
6143
|
-
offset.left = offset.left - Number(value.style?.left || 0);
|
|
6144
|
-
}
|
|
6145
|
-
if (!node.style?.bottom && (0, _tmagic_utils.isNumber)(node.style?.top || 0)) for (const value of path) {
|
|
6146
|
-
if (value.style?.bottom || !(0, _tmagic_utils.isNumber)(value.style?.top || 0)) {
|
|
6147
|
-
offset.top = 0;
|
|
6148
|
-
break;
|
|
6149
|
-
}
|
|
6150
|
-
offset.top = offset.top - Number(value.style?.top || 0);
|
|
6151
|
-
}
|
|
6169
|
+
if (!hasPositionValue(node.style, "right") && (0, _tmagic_utils.isNumber)(node.style?.left || 0)) offset.left = accumulatePositionOffset(path, "left", "right", -1, Number(cur?.style?.left || 0));
|
|
6170
|
+
else if (hasPositionValue(node.style, "right") && (0, _tmagic_utils.isNumber)(node.style?.right || 0)) offset.right = accumulatePositionOffset(path, "right", "left", -1, Number(cur?.style?.right || 0));
|
|
6171
|
+
if (!hasPositionValue(node.style, "bottom") && (0, _tmagic_utils.isNumber)(node.style?.top || 0)) offset.top = accumulatePositionOffset(path, "top", "bottom", -1, Number(cur?.style?.top || 0));
|
|
6172
|
+
else if (hasPositionValue(node.style, "bottom") && (0, _tmagic_utils.isNumber)(node.style?.bottom || 0)) offset.bottom = accumulatePositionOffset(path, "bottom", "top", -1, Number(cur?.style?.bottom || 0));
|
|
6152
6173
|
const style = node.style || {};
|
|
6153
6174
|
const parent = path.pop();
|
|
6154
6175
|
if (!parent) return getRelativeStyle(style);
|
|
6155
6176
|
if (await getLayout(parent) !== Layout.RELATIVE) {
|
|
6156
6177
|
if (offset.left) style.left = offset.left;
|
|
6157
6178
|
if (offset.top) style.top = offset.top;
|
|
6179
|
+
if (offset.right) style.right = offset.right;
|
|
6180
|
+
if (offset.bottom) style.bottom = offset.bottom;
|
|
6158
6181
|
return {
|
|
6159
6182
|
...style,
|
|
6160
6183
|
position: "absolute"
|
|
@@ -6186,11 +6209,11 @@
|
|
|
6186
6209
|
};
|
|
6187
6210
|
var fixNodePosition = (config, parent, stage) => {
|
|
6188
6211
|
if (config.style?.position !== "absolute") return config.style;
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6212
|
+
const style = { ...config.style || {} };
|
|
6213
|
+
const baseStyle = config.style || {};
|
|
6214
|
+
if (!("right" in baseStyle)) style.left = fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document);
|
|
6215
|
+
if (!("top" in baseStyle) && !("bottom" in baseStyle)) style.top = getMiddleTop(config, parent, stage);
|
|
6216
|
+
return style;
|
|
6194
6217
|
};
|
|
6195
6218
|
var serializeConfig = (config) => (0, serialize_javascript.default)(config, {
|
|
6196
6219
|
space: 2,
|
|
@@ -6267,13 +6290,14 @@
|
|
|
6267
6290
|
var resolveSelectedNode = (config, getNodeInfoFn, rootId) => {
|
|
6268
6291
|
const id = typeof config === "string" || typeof config === "number" ? config : config.id;
|
|
6269
6292
|
if (!id) throw new Error("没有ID,无法选中");
|
|
6270
|
-
const { node, parent, page } = getNodeInfoFn(id);
|
|
6293
|
+
const { node, parent, page, path } = getNodeInfoFn(id);
|
|
6271
6294
|
if (!node) throw new Error("获取不到组件信息");
|
|
6272
6295
|
if (node.id === rootId) throw new Error("不能选根节点");
|
|
6273
6296
|
return {
|
|
6274
6297
|
node,
|
|
6275
6298
|
parent,
|
|
6276
|
-
page
|
|
6299
|
+
page,
|
|
6300
|
+
path
|
|
6277
6301
|
};
|
|
6278
6302
|
};
|
|
6279
6303
|
/**
|
|
@@ -6285,11 +6309,11 @@
|
|
|
6285
6309
|
* @param getLayoutFn 获取父节点布局方式的回调函数
|
|
6286
6310
|
* @returns 处理后的节点配置(深拷贝)
|
|
6287
6311
|
*/
|
|
6288
|
-
var toggleFixedPosition = async (dist, src,
|
|
6312
|
+
var toggleFixedPosition = async (dist, src, path, getLayoutFn) => {
|
|
6289
6313
|
const newConfig = cloneDeep$1(dist);
|
|
6290
6314
|
if (!(0, _tmagic_utils.isPop)(src) && newConfig.style?.position) {
|
|
6291
|
-
if ((0, _tmagic_stage.isFixed)(newConfig.style) && !(0, _tmagic_stage.isFixed)(src.style || {})) newConfig.style = change2Fixed(newConfig,
|
|
6292
|
-
else if (!(0, _tmagic_stage.isFixed)(newConfig.style) && (0, _tmagic_stage.isFixed)(src.style || {})) newConfig.style = await Fixed2Other(newConfig,
|
|
6315
|
+
if ((0, _tmagic_stage.isFixed)(newConfig.style) && !(0, _tmagic_stage.isFixed)(src.style || {})) newConfig.style = change2Fixed(newConfig, path);
|
|
6316
|
+
else if (!(0, _tmagic_stage.isFixed)(newConfig.style) && (0, _tmagic_stage.isFixed)(src.style || {})) newConfig.style = await Fixed2Other(newConfig, path, getLayoutFn);
|
|
6293
6317
|
}
|
|
6294
6318
|
return newConfig;
|
|
6295
6319
|
};
|
|
@@ -6603,7 +6627,7 @@
|
|
|
6603
6627
|
this.state.pageFragmentLength = 0;
|
|
6604
6628
|
this.state.stageLoading = false;
|
|
6605
6629
|
}
|
|
6606
|
-
this.emit("root-change", value, preValue);
|
|
6630
|
+
this.emit("root-change", value, preValue, options);
|
|
6607
6631
|
}
|
|
6608
6632
|
}
|
|
6609
6633
|
/**
|
|
@@ -6626,12 +6650,14 @@
|
|
|
6626
6650
|
if (!root) return {
|
|
6627
6651
|
node: null,
|
|
6628
6652
|
parent: null,
|
|
6629
|
-
page: null
|
|
6653
|
+
page: null,
|
|
6654
|
+
path: []
|
|
6630
6655
|
};
|
|
6631
6656
|
if (id === root.id) return {
|
|
6632
6657
|
node: root,
|
|
6633
6658
|
parent: null,
|
|
6634
|
-
page: null
|
|
6659
|
+
page: null,
|
|
6660
|
+
path: []
|
|
6635
6661
|
};
|
|
6636
6662
|
const pageIdStr = `${this.get("page")?.id || ""}`;
|
|
6637
6663
|
const currentPageNode = root.items?.find((item) => `${item.id}` === pageIdStr);
|
|
@@ -6951,13 +6977,12 @@
|
|
|
6951
6977
|
this.emit("remove", nodes);
|
|
6952
6978
|
}
|
|
6953
6979
|
async doUpdate(config, { changeRecords = [], historySource } = {}) {
|
|
6954
|
-
|
|
6955
|
-
if (!root) throw new Error("root为空");
|
|
6980
|
+
if (!this.get("root")) throw new Error("root为空");
|
|
6956
6981
|
if (!config?.id) throw new Error("没有配置或者配置缺少id值");
|
|
6957
6982
|
const info = this.getNodeInfo(config.id, false);
|
|
6958
6983
|
if (!info.node) throw new Error(`获取不到id为${config.id}的节点`);
|
|
6959
6984
|
const node = (0, vue.toRaw)(info.node);
|
|
6960
|
-
let newConfig = await toggleFixedPosition((0, vue.toRaw)(config), node,
|
|
6985
|
+
let newConfig = await toggleFixedPosition((0, vue.toRaw)(config), node, info.path, this.getLayout);
|
|
6961
6986
|
newConfig = mergeWith(cloneDeep$1(node), newConfig, editorNodeMergeCustomizer);
|
|
6962
6987
|
if (!newConfig.type) throw new Error("配置缺少type值");
|
|
6963
6988
|
if (newConfig.type === _tmagic_core.NodeType.ROOT) {
|
|
@@ -7332,46 +7357,61 @@
|
|
|
7332
7357
|
}
|
|
7333
7358
|
/**
|
|
7334
7359
|
* 下列 *AndGetHistoryId 方法与对应的普通操作(add / remove / update ...)行为完全一致,
|
|
7335
|
-
*
|
|
7336
|
-
*
|
|
7360
|
+
* 返回值在 {@link DslOpWithHistoryIdsResult} 中同时包含原操作结果与本次写入历史栈的 uuid 列表({@link StepValue.uuid}),
|
|
7361
|
+
* 可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
7337
7362
|
*
|
|
7338
|
-
* 当本次操作未写入历史(doNotPushHistory 为 true、或操作无实际变更 /
|
|
7363
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或操作无实际变更 / 提前返回)时 historyIds 为 `[]`。
|
|
7339
7364
|
*/
|
|
7340
|
-
/** 等价于 {@link add}
|
|
7365
|
+
/** 等价于 {@link add},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7341
7366
|
async addAndGetHistoryId(addNode, parent, options = {}) {
|
|
7342
7367
|
this.lastPushedHistoryId = null;
|
|
7343
|
-
|
|
7344
|
-
|
|
7368
|
+
return {
|
|
7369
|
+
result: await this.add(addNode, parent, options),
|
|
7370
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7371
|
+
};
|
|
7345
7372
|
}
|
|
7346
|
-
/** 等价于 {@link remove}
|
|
7373
|
+
/** 等价于 {@link remove},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7347
7374
|
async removeAndGetHistoryId(nodeOrNodeList, options = {}) {
|
|
7348
7375
|
this.lastPushedHistoryId = null;
|
|
7349
7376
|
await this.remove(nodeOrNodeList, options);
|
|
7350
|
-
return
|
|
7377
|
+
return {
|
|
7378
|
+
result: void 0,
|
|
7379
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7380
|
+
};
|
|
7351
7381
|
}
|
|
7352
|
-
/** 等价于 {@link update}
|
|
7382
|
+
/** 等价于 {@link update},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7353
7383
|
async updateAndGetHistoryId(config, data = {}) {
|
|
7354
7384
|
this.lastPushedHistoryId = null;
|
|
7355
|
-
|
|
7356
|
-
|
|
7385
|
+
return {
|
|
7386
|
+
result: await this.update(config, data),
|
|
7387
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7388
|
+
};
|
|
7357
7389
|
}
|
|
7358
|
-
/** 等价于 {@link moveLayer}
|
|
7390
|
+
/** 等价于 {@link moveLayer},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7359
7391
|
async moveLayerAndGetHistoryId(offset, options = {}) {
|
|
7360
7392
|
this.lastPushedHistoryId = null;
|
|
7361
7393
|
await this.moveLayer(offset, options);
|
|
7362
|
-
return
|
|
7394
|
+
return {
|
|
7395
|
+
result: void 0,
|
|
7396
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7397
|
+
};
|
|
7363
7398
|
}
|
|
7364
|
-
/** 等价于 {@link moveToContainer}
|
|
7399
|
+
/** 等价于 {@link moveToContainer},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7365
7400
|
async moveToContainerAndGetHistoryId(config, targetId, options = {}) {
|
|
7366
7401
|
this.lastPushedHistoryId = null;
|
|
7367
|
-
|
|
7368
|
-
|
|
7402
|
+
return {
|
|
7403
|
+
result: await this.moveToContainer(config, targetId, options),
|
|
7404
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7405
|
+
};
|
|
7369
7406
|
}
|
|
7370
|
-
/** 等价于 {@link dragTo}
|
|
7407
|
+
/** 等价于 {@link dragTo},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
7371
7408
|
async dragToAndGetHistoryId(config, targetParent, targetIndex, options = {}) {
|
|
7372
7409
|
this.lastPushedHistoryId = null;
|
|
7373
7410
|
await this.dragTo(config, targetParent, targetIndex, options);
|
|
7374
|
-
return
|
|
7411
|
+
return {
|
|
7412
|
+
result: void 0,
|
|
7413
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
7414
|
+
};
|
|
7375
7415
|
}
|
|
7376
7416
|
/**
|
|
7377
7417
|
* 撤销当前操作
|
|
@@ -7480,17 +7520,19 @@
|
|
|
7480
7520
|
return revertedStep;
|
|
7481
7521
|
}
|
|
7482
7522
|
/**
|
|
7483
|
-
* 通过历史记录 uuid
|
|
7484
|
-
* 仅入参从 index 改为 uuid
|
|
7485
|
-
*
|
|
7523
|
+
* 通过历史记录 uuid 回滚当前页面的历史步骤,语义与 {@link revertPageStep} 完全一致,
|
|
7524
|
+
* 仅入参从 index 改为 uuid 列表({@link StepValue.uuid})。按数组顺序依次回滚,
|
|
7525
|
+
* 返回与入参同序的结果列表(某项失败时为 `null`)。
|
|
7486
7526
|
*
|
|
7487
|
-
* @param
|
|
7488
|
-
* @returns 反向后产生的新 step;找不到对应 uuid / 未应用 / 反向失败时返回 null
|
|
7527
|
+
* @param uuids 目标历史记录的 uuid 列表,通常由 *AndGetHistoryId 方法返回的 `historyIds`
|
|
7489
7528
|
*/
|
|
7490
|
-
async revertPageStepById(
|
|
7491
|
-
const
|
|
7492
|
-
|
|
7493
|
-
|
|
7529
|
+
async revertPageStepById(uuids) {
|
|
7530
|
+
const results = [];
|
|
7531
|
+
for (const uuid of uuids) {
|
|
7532
|
+
const index = history_default.getPageStepIndexByUuid(uuid);
|
|
7533
|
+
results.push(index < 0 ? null : await this.revertPageStep(index));
|
|
7534
|
+
}
|
|
7535
|
+
return results;
|
|
7494
7536
|
}
|
|
7495
7537
|
/**
|
|
7496
7538
|
* 跳转当前页面历史栈到指定游标位置。
|
|
@@ -8472,6 +8514,7 @@
|
|
|
8472
8514
|
items: [
|
|
8473
8515
|
{
|
|
8474
8516
|
title: "数据定义",
|
|
8517
|
+
status: "fields",
|
|
8475
8518
|
items: [{
|
|
8476
8519
|
name: "fields",
|
|
8477
8520
|
type: "data-source-fields",
|
|
@@ -8480,6 +8523,7 @@
|
|
|
8480
8523
|
},
|
|
8481
8524
|
{
|
|
8482
8525
|
title: "方法定义",
|
|
8526
|
+
status: "methods",
|
|
8483
8527
|
items: [{
|
|
8484
8528
|
name: "methods",
|
|
8485
8529
|
type: "data-source-methods",
|
|
@@ -10131,12 +10175,13 @@
|
|
|
10131
10175
|
var toRowGroup = (group, key, descriptor) => {
|
|
10132
10176
|
const { describeGroup, describeStep, isStepDiffable, isStepRevertable } = descriptor;
|
|
10133
10177
|
const timestamp = groupTimestamp(group);
|
|
10178
|
+
const lastStep = group.steps[group.steps.length - 1]?.step;
|
|
10134
10179
|
return {
|
|
10135
10180
|
key,
|
|
10136
10181
|
applied: group.applied,
|
|
10137
10182
|
isCurrent: Boolean(group.isCurrent),
|
|
10138
10183
|
opType: group.opType,
|
|
10139
|
-
desc: describeGroup(group),
|
|
10184
|
+
desc: describeGroup ? describeGroup(group) : describeStep(lastStep),
|
|
10140
10185
|
source: groupSource(group),
|
|
10141
10186
|
time: formatHistoryTime(timestamp),
|
|
10142
10187
|
timeTitle: formatHistoryFullTime(timestamp),
|
|
@@ -10169,28 +10214,36 @@
|
|
|
10169
10214
|
var pickLastDescription = (descs) => {
|
|
10170
10215
|
for (let i = descs.length - 1; i >= 0; i--) if (descs[i]) return descs[i];
|
|
10171
10216
|
};
|
|
10172
|
-
|
|
10217
|
+
/**
|
|
10218
|
+
* 页面 / 数据源 / 代码块三类历史共用的单步描述核心。
|
|
10219
|
+
* 各类型只在「取展示名」与「实体单位名」上有差异,通过参数注入,文案模板完全一致:
|
|
10220
|
+
* - 新增 / 删除:单实体展示「label」,多实体(仅页面可能出现)退化为「N 个X」;
|
|
10221
|
+
* - 修改:展示「label · propPath」,无 diff 时兜底「X」,多实体退化为「N 个X」。
|
|
10222
|
+
* 操作类型(新增 / 删除 / 修改)已由列表行的 op 徽标单独展示,故描述文案不再重复动词。
|
|
10223
|
+
* 展示 id 统一取 schema.id;调用方显式传入的 historyDescription 永远优先。
|
|
10224
|
+
*/
|
|
10225
|
+
var describeStep = (step, getLabel, unit) => {
|
|
10173
10226
|
if (step.historyDescription) return step.historyDescription;
|
|
10174
|
-
const { opType } = step;
|
|
10175
10227
|
const items = step.diff ?? [];
|
|
10176
|
-
|
|
10177
|
-
|
|
10228
|
+
const label = (schema) => labelWithId(getLabel(schema), schema?.id);
|
|
10229
|
+
if (step.opType === "add") {
|
|
10178
10230
|
const node = items[0]?.newSchema;
|
|
10179
|
-
return
|
|
10231
|
+
return items.length === 1 && node ? label(node) : `${items.length} 个${unit}`;
|
|
10180
10232
|
}
|
|
10181
|
-
if (opType === "remove") {
|
|
10182
|
-
const count = items.length;
|
|
10233
|
+
if (step.opType === "remove") {
|
|
10183
10234
|
const node = items[0]?.oldSchema;
|
|
10184
|
-
return
|
|
10235
|
+
return items.length === 1 && node ? label(node) : `${items.length} 个${unit}`;
|
|
10185
10236
|
}
|
|
10186
|
-
if (!items.length) return
|
|
10237
|
+
if (!items.length) return unit;
|
|
10187
10238
|
if (items.length === 1) {
|
|
10188
|
-
const { newSchema, changeRecords } = items[0];
|
|
10189
|
-
const propPath = changeRecords?.
|
|
10190
|
-
|
|
10239
|
+
const { newSchema, oldSchema, changeRecords } = items[0];
|
|
10240
|
+
const propPath = changeRecords?.map((changeRecord) => changeRecord.propPath).join(",");
|
|
10241
|
+
const target = label(newSchema ?? oldSchema);
|
|
10242
|
+
return propPath ? `${target} · ${propPath}` : target;
|
|
10191
10243
|
}
|
|
10192
|
-
return
|
|
10244
|
+
return `${items.length} 个${unit}`;
|
|
10193
10245
|
};
|
|
10246
|
+
var describePageStep = (step) => describeStep(step, (node) => nameOf(node), "节点");
|
|
10194
10247
|
/**
|
|
10195
10248
|
* 合并组的展示文案:
|
|
10196
10249
|
* - 若组内任一步显式提供了 historyDescription:取最后一条非空 historyDescription(最近一次的描述更准确);
|
|
@@ -10201,55 +10254,7 @@
|
|
|
10201
10254
|
const lastDesc = pickLastDescription(group.steps.map((s) => s.step.historyDescription));
|
|
10202
10255
|
if (lastDesc) return lastDesc;
|
|
10203
10256
|
if (group.steps.length === 1) return describePageStep(group.steps[0].step);
|
|
10204
|
-
|
|
10205
|
-
group.steps.forEach((s) => {
|
|
10206
|
-
s.step.diff?.[0]?.changeRecords?.forEach((r) => r.propPath && paths.add(r.propPath));
|
|
10207
|
-
});
|
|
10208
|
-
const pathList = Array.from(paths).slice(0, 3).join(", ");
|
|
10209
|
-
const target = labelWithId(group.targetName ?? (group.targetId !== void 0 ? `${group.targetId}` : "节点"), group.targetId);
|
|
10210
|
-
return pathList ? `修改 ${target} · ${pathList}${paths.size > 3 ? "…" : ""}` : `修改 ${target}`;
|
|
10211
|
-
};
|
|
10212
|
-
var describeDataSourceStep = (step) => {
|
|
10213
|
-
if (step.historyDescription) return step.historyDescription;
|
|
10214
|
-
const { oldSchema, newSchema, changeRecords } = step.diff?.[0] ?? {};
|
|
10215
|
-
if (!oldSchema && newSchema) return `创建 ${labelWithId(newSchema.title, newSchema.id ?? step.id)}`;
|
|
10216
|
-
if (!newSchema && oldSchema) return `删除 ${labelWithId(oldSchema.title, oldSchema.id ?? step.id)}`;
|
|
10217
|
-
const propPath = changeRecords?.[0]?.propPath;
|
|
10218
|
-
const title = labelWithId(newSchema?.title || oldSchema?.title, step.id);
|
|
10219
|
-
return propPath ? `修改 ${title} · ${propPath}` : `修改 ${title}`;
|
|
10220
|
-
};
|
|
10221
|
-
var describeDataSourceGroup = (group) => {
|
|
10222
|
-
const lastDesc = pickLastDescription(group.steps.map((s) => s.step.historyDescription));
|
|
10223
|
-
if (lastDesc) return lastDesc;
|
|
10224
|
-
if (group.steps.length === 1) return describeDataSourceStep(group.steps[0].step);
|
|
10225
|
-
const paths = /* @__PURE__ */ new Set();
|
|
10226
|
-
group.steps.forEach((s) => {
|
|
10227
|
-
s.step.diff?.[0]?.changeRecords?.forEach((r) => r.propPath && paths.add(r.propPath));
|
|
10228
|
-
});
|
|
10229
|
-
const pathList = Array.from(paths).slice(0, 3).join(", ");
|
|
10230
|
-
const target = labelWithId(group.steps[group.steps.length - 1].step.diff?.[0]?.newSchema?.title || group.steps[0].step.diff?.[0]?.oldSchema?.title, group.id);
|
|
10231
|
-
return pathList ? `修改 ${target} · ${pathList}${paths.size > 3 ? "…" : ""}` : `修改 ${target}`;
|
|
10232
|
-
};
|
|
10233
|
-
var describeCodeBlockStep = (step) => {
|
|
10234
|
-
if (step.historyDescription) return step.historyDescription;
|
|
10235
|
-
const { oldSchema: oldContent, newSchema: newContent, changeRecords } = step.diff?.[0] ?? {};
|
|
10236
|
-
if (!oldContent && newContent) return `创建 ${labelWithId(newContent.name, newContent.id ?? step.id)}`;
|
|
10237
|
-
if (!newContent && oldContent) return `删除 ${labelWithId(oldContent.name, oldContent.id ?? step.id)}`;
|
|
10238
|
-
const propPath = changeRecords?.[0]?.propPath;
|
|
10239
|
-
const title = labelWithId(newContent?.name || oldContent?.name, step.id);
|
|
10240
|
-
return propPath ? `修改 ${title} · ${propPath}` : `修改 ${title}`;
|
|
10241
|
-
};
|
|
10242
|
-
var describeCodeBlockGroup = (group) => {
|
|
10243
|
-
const lastDesc = pickLastDescription(group.steps.map((s) => s.step.historyDescription));
|
|
10244
|
-
if (lastDesc) return lastDesc;
|
|
10245
|
-
if (group.steps.length === 1) return describeCodeBlockStep(group.steps[0].step);
|
|
10246
|
-
const paths = /* @__PURE__ */ new Set();
|
|
10247
|
-
group.steps.forEach((s) => {
|
|
10248
|
-
s.step.diff?.[0]?.changeRecords?.forEach((r) => r.propPath && paths.add(r.propPath));
|
|
10249
|
-
});
|
|
10250
|
-
const pathList = Array.from(paths).slice(0, 3).join(", ");
|
|
10251
|
-
const target = labelWithId(group.steps[group.steps.length - 1].step.diff?.[0]?.newSchema?.name || group.steps[0].step.diff?.[0]?.oldSchema?.name, group.id);
|
|
10252
|
-
return pathList ? `修改 ${target} · ${pathList}${paths.size > 3 ? "…" : ""}` : `修改 ${target}`;
|
|
10257
|
+
return labelWithId(group.targetName ?? (group.targetId !== void 0 ? `${group.targetId}` : "节点"), group.targetId);
|
|
10253
10258
|
};
|
|
10254
10259
|
/**
|
|
10255
10260
|
* 页面 step 是否支持「回滚」(类 git revert):
|
|
@@ -10264,21 +10269,11 @@
|
|
|
10264
10269
|
return items.every((item) => Boolean(item.changeRecords?.length));
|
|
10265
10270
|
};
|
|
10266
10271
|
/**
|
|
10267
|
-
*
|
|
10268
|
-
* - 新增(无 oldSchema)/ 删除(无 newSchema):不依赖 changeRecords,始终可回滚;
|
|
10269
|
-
* - 更新(前后 schema 都存在):必须有 changeRecords 才支持局部反向 patch,否则不支持回滚。
|
|
10270
|
-
*/
|
|
10271
|
-
var isDataSourceStepRevertable = (step) => {
|
|
10272
|
-
const item = step.diff?.[0];
|
|
10273
|
-
if (!item?.oldSchema || !item?.newSchema) return true;
|
|
10274
|
-
return Boolean(item.changeRecords?.length);
|
|
10275
|
-
};
|
|
10276
|
-
/**
|
|
10277
|
-
* 代码块 step 是否支持「回滚」:
|
|
10272
|
+
* 单 diff 项历史(数据源 / 代码块)是否支持「回滚」:
|
|
10278
10273
|
* - 新增(无 oldSchema)/ 删除(无 newSchema):不依赖 changeRecords,始终可回滚;
|
|
10279
|
-
* -
|
|
10274
|
+
* - 更新(前后内容都存在):必须有 changeRecords 才支持局部反向 patch,否则不支持回滚。
|
|
10280
10275
|
*/
|
|
10281
|
-
var
|
|
10276
|
+
var isSingleDiffStepRevertable = (step) => {
|
|
10282
10277
|
const item = step.diff?.[0];
|
|
10283
10278
|
if (!item?.oldSchema || !item?.newSchema) return true;
|
|
10284
10279
|
return Boolean(item.changeRecords?.length);
|
|
@@ -10293,7 +10288,7 @@
|
|
|
10293
10288
|
class: "m-editor-history-list-item-saved",
|
|
10294
10289
|
title: "该记录为最近一次保存的状态"
|
|
10295
10290
|
};
|
|
10296
|
-
var _hoisted_5$
|
|
10291
|
+
var _hoisted_5$4 = {
|
|
10297
10292
|
key: 1,
|
|
10298
10293
|
class: "m-editor-history-list-item-actions"
|
|
10299
10294
|
};
|
|
@@ -10453,7 +10448,7 @@
|
|
|
10453
10448
|
(0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["m-editor-history-list-item-op", `op-${__props.group.opType}`]) }, (0, vue.toDisplayString)((0, vue.unref)(opLabel)(__props.group.opType)), 3),
|
|
10454
10449
|
(0, vue.createElementVNode)("span", _hoisted_3$11, (0, vue.toDisplayString)(__props.group.desc), 1),
|
|
10455
10450
|
headSaved.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$8, "已保存")) : (0, vue.createCommentVNode)("v-if", true),
|
|
10456
|
-
!merged.value && (headRevertable.value || headDiffable.value || canHeadGoto.value) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$
|
|
10451
|
+
!merged.value && (headRevertable.value || headDiffable.value || canHeadGoto.value) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$4, [
|
|
10457
10452
|
headRevertable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
10458
10453
|
key: 0,
|
|
10459
10454
|
class: "m-editor-history-list-item-revert",
|
|
@@ -10546,9 +10541,14 @@
|
|
|
10546
10541
|
var _hoisted_2$22 = { class: "m-editor-history-list-item-desc" };
|
|
10547
10542
|
var _hoisted_3$10 = {
|
|
10548
10543
|
key: 0,
|
|
10544
|
+
class: "m-editor-history-list-item-saved",
|
|
10545
|
+
title: "该记录为最近一次保存的状态"
|
|
10546
|
+
};
|
|
10547
|
+
var _hoisted_4$7 = {
|
|
10548
|
+
key: 1,
|
|
10549
10549
|
class: "m-editor-history-list-item-actions"
|
|
10550
10550
|
};
|
|
10551
|
-
var
|
|
10551
|
+
var _hoisted_5$3 = ["title"];
|
|
10552
10552
|
var InitialRow_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
10553
10553
|
name: "MEditorHistoryListInitialRow",
|
|
10554
10554
|
__name: "InitialRow",
|
|
@@ -10573,6 +10573,8 @@
|
|
|
10573
10573
|
*/
|
|
10574
10574
|
const props = __props;
|
|
10575
10575
|
const desc = (0, vue.computed)(() => props.marker?.historyDescription || "未修改的初始状态");
|
|
10576
|
+
/** 基线(初始状态)是否为最近一次保存点:仅页面栈的 `initial` 基线 step 会被 markSaved 标记。 */
|
|
10577
|
+
const saved = (0, vue.computed)(() => Boolean(props.marker?.saved));
|
|
10576
10578
|
const time = (0, vue.computed)(() => formatHistoryTime(props.marker?.timestamp));
|
|
10577
10579
|
const timeTitle = (0, vue.computed)(() => formatHistoryFullTime(props.marker?.timestamp));
|
|
10578
10580
|
const rowTitle = (0, vue.computed)(() => {
|
|
@@ -10598,16 +10600,17 @@
|
|
|
10598
10600
|
}, "#0", -1)),
|
|
10599
10601
|
_cache[1] || (_cache[1] = (0, vue.createElementVNode)("span", { class: "m-editor-history-list-item-op op-initial" }, "初始", -1)),
|
|
10600
10602
|
(0, vue.createElementVNode)("span", _hoisted_2$22, (0, vue.toDisplayString)(desc.value), 1),
|
|
10601
|
-
|
|
10603
|
+
saved.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$10, "已保存")) : (0, vue.createCommentVNode)("v-if", true),
|
|
10604
|
+
__props.gotoEnabled && !__props.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$7, [(0, vue.createElementVNode)("span", {
|
|
10602
10605
|
class: "m-editor-history-list-item-goto",
|
|
10603
10606
|
title: "回到该记录",
|
|
10604
10607
|
onClick: (0, vue.withModifiers)(onClick, ["stop"])
|
|
10605
10608
|
}, "回到")])) : (0, vue.createCommentVNode)("v-if", true),
|
|
10606
10609
|
time.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
10607
|
-
key:
|
|
10610
|
+
key: 2,
|
|
10608
10611
|
class: "m-editor-history-list-item-time",
|
|
10609
10612
|
title: timeTitle.value
|
|
10610
|
-
}, (0, vue.toDisplayString)(time.value), 9,
|
|
10613
|
+
}, (0, vue.toDisplayString)(time.value), 9, _hoisted_5$3)) : (0, vue.createCommentVNode)("v-if", true)
|
|
10611
10614
|
], 10, _hoisted_1$60);
|
|
10612
10615
|
};
|
|
10613
10616
|
}
|
|
@@ -11299,8 +11302,8 @@
|
|
|
11299
11302
|
/**
|
|
11300
11303
|
* 历史记录面板:在顶部 NavMenu 上点击图标打开 popover,分三个 tab:
|
|
11301
11304
|
* - 页面:当前活动页面的历史栈,连续修改同一节点的多步会被合并成一组
|
|
11302
|
-
* - 数据源:以 dataSource.id
|
|
11303
|
-
* - 代码块:同上,按 codeBlock.id
|
|
11305
|
+
* - 数据源:以 dataSource.id 分桶,每条操作记录独立展示
|
|
11306
|
+
* - 代码块:同上,按 codeBlock.id 分桶,每条操作记录独立展示
|
|
11304
11307
|
*
|
|
11305
11308
|
* 数据通过 historyService 暴露的聚合 API 读取,UI 仅用于只读展示,
|
|
11306
11309
|
* 同时支持点击任意一条记录跳转至该状态:
|
|
@@ -11355,10 +11358,8 @@
|
|
|
11355
11358
|
* 基于 historyService 的 reactive state 派生,活动页切换或标记写入后自动刷新。
|
|
11356
11359
|
*/
|
|
11357
11360
|
const pageMarker = (0, vue.computed)(() => historyService.getPageMarker());
|
|
11358
|
-
/** 数据源 step 仅 update(前后 schema 都存在)时可查看差异。 */
|
|
11359
|
-
const isDataSourceStepDiffable = (step) => Boolean(step.diff?.[0]?.oldSchema && step.diff?.[0]?.newSchema);
|
|
11360
11361
|
/** 代码块 step 仅 update(前后 content 都存在)时可查看差异。 */
|
|
11361
|
-
const
|
|
11362
|
+
const isStepDiffable = (step) => Boolean(step.diff?.[0]?.oldSchema && step.diff?.[0]?.newSchema);
|
|
11362
11363
|
/**
|
|
11363
11364
|
* 数据源 / 代码块两类 bucket 历史的整体渲染配置:把 title / prefix 与各自的描述、
|
|
11364
11365
|
* 可差异、可回滚判定收敛为单一对象整体注入 BucketTab,组件内部按需读取。
|
|
@@ -11366,18 +11367,16 @@
|
|
|
11366
11367
|
const dataSourceConfig = {
|
|
11367
11368
|
title: "数据源",
|
|
11368
11369
|
prefix: "ds",
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
isStepRevertable: isDataSourceStepRevertable
|
|
11370
|
+
describeStep: (step) => describeStep(step, (schema) => schema?.title, "数据源"),
|
|
11371
|
+
isStepDiffable,
|
|
11372
|
+
isStepRevertable: isSingleDiffStepRevertable
|
|
11373
11373
|
};
|
|
11374
11374
|
const codeBlockConfig = {
|
|
11375
11375
|
title: "代码块",
|
|
11376
11376
|
prefix: "cb",
|
|
11377
|
-
|
|
11378
|
-
|
|
11379
|
-
|
|
11380
|
-
isStepRevertable: isCodeBlockStepRevertable
|
|
11377
|
+
describeStep: (step) => describeStep(step, (content) => content?.name, "代码块"),
|
|
11378
|
+
isStepDiffable,
|
|
11379
|
+
isStepRevertable: isSingleDiffStepRevertable
|
|
11381
11380
|
};
|
|
11382
11381
|
/** 把"目标 step 索引"翻译成"目标 cursor"(已应用步骤数量)。 */
|
|
11383
11382
|
const indexToCursor = (index) => index + 1;
|
|
@@ -13644,7 +13643,9 @@
|
|
|
13644
13643
|
props: /* @__PURE__ */ (0, vue.mergeModels)({
|
|
13645
13644
|
title: {},
|
|
13646
13645
|
values: {},
|
|
13647
|
-
disabled: { type: Boolean }
|
|
13646
|
+
disabled: { type: Boolean },
|
|
13647
|
+
editMethodName: {},
|
|
13648
|
+
editFieldPath: {}
|
|
13648
13649
|
}, {
|
|
13649
13650
|
"visible": {
|
|
13650
13651
|
type: Boolean,
|
|
@@ -13669,9 +13670,20 @@
|
|
|
13669
13670
|
const dataSourceConfig = (0, vue.ref)([]);
|
|
13670
13671
|
const { height: editorHeight } = useEditorContentHeight();
|
|
13671
13672
|
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, (0, vue.inject)("parentFloating", (0, vue.ref)(null)));
|
|
13673
|
+
/** 供「方法定义」tab 内的字段消费,用于打开数据源详情后自动打开指定方法 */
|
|
13674
|
+
(0, vue.provide)("editingDataSourceMethodName", (0, vue.computed)(() => props.editMethodName));
|
|
13675
|
+
/** 供「数据定义」tab 内的字段消费,用于打开数据源详情后自动打开指定字段 */
|
|
13676
|
+
(0, vue.provide)("editingDataSourceFieldPath", (0, vue.computed)(() => props.editFieldPath || []));
|
|
13672
13677
|
(0, vue.watchEffect)(() => {
|
|
13673
13678
|
initValues.value = props.values;
|
|
13674
|
-
|
|
13679
|
+
const config = dataSourceService.getFormConfig(initValues.value.type);
|
|
13680
|
+
let activeTab = "fields";
|
|
13681
|
+
if (props.editMethodName) activeTab = "methods";
|
|
13682
|
+
else if (props.editFieldPath?.length) activeTab = "fields";
|
|
13683
|
+
dataSourceConfig.value = config.map((item) => item.type === "tab" ? {
|
|
13684
|
+
...item,
|
|
13685
|
+
active: activeTab
|
|
13686
|
+
} : item);
|
|
13675
13687
|
});
|
|
13676
13688
|
const submitHandler = (values, data) => {
|
|
13677
13689
|
emit("submit", values, data);
|
|
@@ -13960,7 +13972,13 @@
|
|
|
13960
13972
|
const eventBus = (0, vue.inject)("eventBus");
|
|
13961
13973
|
const { dataSourceService } = useServices();
|
|
13962
13974
|
const { editDialog, dataSourceValues, dialogTitle, editable, editHandler, submitDataSourceHandler } = useDataSourceEdit(dataSourceService);
|
|
13975
|
+
/** 打开数据源详情时需要直接定位并打开的方法名,为空则正常展示「数据定义」tab */
|
|
13976
|
+
const editMethodName = (0, vue.ref)("");
|
|
13977
|
+
/** 打开数据源详情时需要直接定位并打开的字段路径,为空则不自动打开字段配置 */
|
|
13978
|
+
const editFieldPath = (0, vue.ref)([]);
|
|
13963
13979
|
const editDialogCloseHandler = () => {
|
|
13980
|
+
editMethodName.value = "";
|
|
13981
|
+
editFieldPath.value = [];
|
|
13964
13982
|
if (dataSourceListRef.value) for (const [, status] of dataSourceListRef.value.nodeStatusMap.entries()) status.selected = false;
|
|
13965
13983
|
};
|
|
13966
13984
|
(0, vue.watch)(dataSourceValues, (dataSourceValues) => {
|
|
@@ -13998,6 +14016,18 @@
|
|
|
13998
14016
|
dataSourceListRef.value?.filter(val);
|
|
13999
14017
|
};
|
|
14000
14018
|
eventBus?.on("edit-data-source", (id) => {
|
|
14019
|
+
editMethodName.value = "";
|
|
14020
|
+
editFieldPath.value = [];
|
|
14021
|
+
editHandler(id);
|
|
14022
|
+
});
|
|
14023
|
+
eventBus?.on("edit-data-source-method", (id, methodName) => {
|
|
14024
|
+
editMethodName.value = methodName;
|
|
14025
|
+
editFieldPath.value = [];
|
|
14026
|
+
editHandler(id);
|
|
14027
|
+
});
|
|
14028
|
+
eventBus?.on("edit-data-source-field", (id, fieldPath) => {
|
|
14029
|
+
editMethodName.value = "";
|
|
14030
|
+
editFieldPath.value = fieldPath;
|
|
14001
14031
|
editHandler(id);
|
|
14002
14032
|
});
|
|
14003
14033
|
eventBus?.on("remove-data-source", (id) => {
|
|
@@ -14046,12 +14076,16 @@
|
|
|
14046
14076
|
disabled: !(0, vue.unref)(editable),
|
|
14047
14077
|
values: (0, vue.unref)(dataSourceValues),
|
|
14048
14078
|
title: (0, vue.unref)(dialogTitle),
|
|
14079
|
+
"edit-method-name": editMethodName.value,
|
|
14080
|
+
"edit-field-path": editFieldPath.value,
|
|
14049
14081
|
onSubmit: (0, vue.unref)(submitDataSourceHandler),
|
|
14050
14082
|
onClose: editDialogCloseHandler
|
|
14051
14083
|
}, null, 8, [
|
|
14052
14084
|
"disabled",
|
|
14053
14085
|
"values",
|
|
14054
14086
|
"title",
|
|
14087
|
+
"edit-method-name",
|
|
14088
|
+
"edit-field-path",
|
|
14055
14089
|
"onSubmit"
|
|
14056
14090
|
]),
|
|
14057
14091
|
((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: "body" }, [menuData.value.length ? ((0, vue.openBlock)(), (0, vue.createBlock)(ContentMenu_default, {
|
|
@@ -15047,7 +15081,7 @@
|
|
|
15047
15081
|
slots: {}
|
|
15048
15082
|
},
|
|
15049
15083
|
layer: {
|
|
15050
|
-
$key:
|
|
15084
|
+
$key: SideItemKey.LAYER,
|
|
15051
15085
|
type: "component",
|
|
15052
15086
|
icon: _element_plus_icons_vue.List,
|
|
15053
15087
|
text: "已选组件",
|
|
@@ -15065,7 +15099,7 @@
|
|
|
15065
15099
|
slots: {}
|
|
15066
15100
|
},
|
|
15067
15101
|
[SideItemKey.CODE_BLOCK]: {
|
|
15068
|
-
$key:
|
|
15102
|
+
$key: SideItemKey.CODE_BLOCK,
|
|
15069
15103
|
type: "component",
|
|
15070
15104
|
icon: _element_plus_icons_vue.EditPen,
|
|
15071
15105
|
text: "代码编辑",
|
|
@@ -16436,31 +16470,40 @@
|
|
|
16436
16470
|
}
|
|
16437
16471
|
/**
|
|
16438
16472
|
* 下列 *AndGetHistoryId 方法与对应的写入方法行为完全一致,
|
|
16439
|
-
*
|
|
16473
|
+
* 返回值在 {@link DslOpWithHistoryIdsResult} 中同时包含原操作结果与本次写入的历史 uuid 列表,
|
|
16440
16474
|
* 可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
16441
16475
|
*
|
|
16442
|
-
* 当本次操作未写入历史(doNotPushHistory 为 true
|
|
16476
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或无对应记录)时 historyIds 为 `[]`。
|
|
16443
16477
|
*/
|
|
16444
|
-
/** 等价于 {@link setCodeDslById}
|
|
16478
|
+
/** 等价于 {@link setCodeDslById},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
16445
16479
|
async setCodeDslByIdAndGetHistoryId(id, codeConfig, options = {}) {
|
|
16446
16480
|
this.lastPushedHistoryId = null;
|
|
16447
16481
|
await this.setCodeDslById(id, codeConfig, options);
|
|
16448
|
-
return
|
|
16482
|
+
return {
|
|
16483
|
+
result: void 0,
|
|
16484
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
16485
|
+
};
|
|
16449
16486
|
}
|
|
16450
|
-
/** 等价于 {@link setCodeDslByIdSync}
|
|
16487
|
+
/** 等价于 {@link setCodeDslByIdSync},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
16451
16488
|
setCodeDslByIdSyncAndGetHistoryId(id, codeConfig, force = true, options = {}) {
|
|
16452
16489
|
this.lastPushedHistoryId = null;
|
|
16453
16490
|
this.setCodeDslByIdSync(id, codeConfig, force, options);
|
|
16454
|
-
return
|
|
16491
|
+
return {
|
|
16492
|
+
result: void 0,
|
|
16493
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
16494
|
+
};
|
|
16455
16495
|
}
|
|
16456
16496
|
/**
|
|
16457
|
-
* 等价于 {@link deleteCodeDslByIds}
|
|
16458
|
-
*
|
|
16497
|
+
* 等价于 {@link deleteCodeDslByIds},并额外返回本次写入的全部历史记录 uuid(按删除顺序)。
|
|
16498
|
+
* 一次删除多个代码块会产生多条历史记录;未写入任何历史时 historyIds 为 `[]`。
|
|
16459
16499
|
*/
|
|
16460
16500
|
async deleteCodeDslByIdsAndGetHistoryId(codeIds, options = {}) {
|
|
16461
16501
|
this.lastDeletedHistoryIds = [];
|
|
16462
16502
|
await this.deleteCodeDslByIds(codeIds, options);
|
|
16463
|
-
return
|
|
16503
|
+
return {
|
|
16504
|
+
result: void 0,
|
|
16505
|
+
historyIds: [...this.lastDeletedHistoryIds]
|
|
16506
|
+
};
|
|
16464
16507
|
}
|
|
16465
16508
|
setParamsColConfig(config) {
|
|
16466
16509
|
this.state.paramsColConfig = config;
|
|
@@ -16543,17 +16586,19 @@
|
|
|
16543
16586
|
return await this.applyRevertStep(entry.step, description);
|
|
16544
16587
|
}
|
|
16545
16588
|
/**
|
|
16546
|
-
* 通过历史记录 uuid
|
|
16547
|
-
* 仅无需调用方再传 codeBlockId 与 index:内部会按 uuid
|
|
16548
|
-
*
|
|
16589
|
+
* 通过历史记录 uuid 回滚代码块历史步骤,语义同 {@link revert},
|
|
16590
|
+
* 仅无需调用方再传 codeBlockId 与 index:内部会按 uuid 在全部代码块栈中定位对应步骤后再回滚。
|
|
16591
|
+
* 按数组顺序依次回滚,返回与入参同序的结果列表(某项失败时为 `null`)。
|
|
16549
16592
|
*
|
|
16550
|
-
* @param
|
|
16551
|
-
* @returns 反向后产生的新 step;找不到对应 uuid / 未应用时返回 null
|
|
16593
|
+
* @param uuids 目标历史记录的 uuid 列表,通常由 {@link setCodeDslByIdAndGetHistoryId} 等方法返回的 `historyIds`
|
|
16552
16594
|
*/
|
|
16553
|
-
async revertById(
|
|
16554
|
-
const
|
|
16555
|
-
|
|
16556
|
-
|
|
16595
|
+
async revertById(uuids) {
|
|
16596
|
+
const results = [];
|
|
16597
|
+
for (const uuid of uuids) {
|
|
16598
|
+
const location = history_default.findCodeBlockStepLocationByUuid(uuid);
|
|
16599
|
+
results.push(location ? await this.revert(location.id, location.index) : null);
|
|
16600
|
+
}
|
|
16601
|
+
return results;
|
|
16557
16602
|
}
|
|
16558
16603
|
/**
|
|
16559
16604
|
* 生成代码块唯一id
|
|
@@ -16883,28 +16928,35 @@
|
|
|
16883
16928
|
}
|
|
16884
16929
|
/**
|
|
16885
16930
|
* 下列 *AndGetHistoryId 方法与对应的 add / update / remove 行为完全一致,
|
|
16886
|
-
*
|
|
16887
|
-
*
|
|
16931
|
+
* 返回值在 {@link DslOpWithHistoryIdsResult} 中同时包含原操作结果与本次写入历史栈的 uuid 列表({@link DataSourceStepValue.uuid}),
|
|
16932
|
+
* 可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
16888
16933
|
*
|
|
16889
|
-
* 当本次操作未写入历史(doNotPushHistory 为 true
|
|
16934
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或无对应记录)时 historyIds 为 `[]`。
|
|
16890
16935
|
*/
|
|
16891
|
-
/** 等价于 {@link add}
|
|
16936
|
+
/** 等价于 {@link add},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
16892
16937
|
addAndGetHistoryId(config, options = {}) {
|
|
16893
16938
|
this.lastPushedHistoryId = null;
|
|
16894
|
-
|
|
16895
|
-
|
|
16939
|
+
return {
|
|
16940
|
+
result: this.add(config, options),
|
|
16941
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
16942
|
+
};
|
|
16896
16943
|
}
|
|
16897
|
-
/** 等价于 {@link update}
|
|
16944
|
+
/** 等价于 {@link update},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
16898
16945
|
updateAndGetHistoryId(config, options = {}) {
|
|
16899
16946
|
this.lastPushedHistoryId = null;
|
|
16900
|
-
|
|
16901
|
-
|
|
16947
|
+
return {
|
|
16948
|
+
result: this.update(config, options),
|
|
16949
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
16950
|
+
};
|
|
16902
16951
|
}
|
|
16903
|
-
/** 等价于 {@link remove}
|
|
16952
|
+
/** 等价于 {@link remove},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
16904
16953
|
removeAndGetHistoryId(id, options = {}) {
|
|
16905
16954
|
this.lastPushedHistoryId = null;
|
|
16906
16955
|
this.remove(id, options);
|
|
16907
|
-
return
|
|
16956
|
+
return {
|
|
16957
|
+
result: void 0,
|
|
16958
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
16959
|
+
};
|
|
16908
16960
|
}
|
|
16909
16961
|
/**
|
|
16910
16962
|
* 撤销指定数据源的最近一次变更。
|
|
@@ -16980,17 +17032,18 @@
|
|
|
16980
17032
|
return this.applyRevertStep(entry.step, description);
|
|
16981
17033
|
}
|
|
16982
17034
|
/**
|
|
16983
|
-
* 通过历史记录 uuid
|
|
16984
|
-
* 仅无需调用方再传 dataSourceId 与 index:内部会按 uuid
|
|
16985
|
-
*
|
|
17035
|
+
* 通过历史记录 uuid 回滚数据源历史步骤,语义同 {@link revert},
|
|
17036
|
+
* 仅无需调用方再传 dataSourceId 与 index:内部会按 uuid 在全部数据源栈中定位对应步骤后再回滚。
|
|
17037
|
+
* 按数组顺序依次回滚,返回与入参同序的结果列表(某项失败时为 `null`)。
|
|
16986
17038
|
*
|
|
16987
|
-
* @param
|
|
16988
|
-
* @returns 反向后产生的新 step;找不到对应 uuid / 未应用时返回 null
|
|
17039
|
+
* @param uuids 目标历史记录的 uuid 列表,通常由 {@link addAndGetHistoryId} 等方法返回的 `historyIds`
|
|
16989
17040
|
*/
|
|
16990
|
-
revertById(
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
17041
|
+
revertById(uuids) {
|
|
17042
|
+
return uuids.map((uuid) => {
|
|
17043
|
+
const location = history_default.findDataSourceStepLocationByUuid(uuid);
|
|
17044
|
+
if (!location) return null;
|
|
17045
|
+
return this.revert(location.id, location.index);
|
|
17046
|
+
});
|
|
16994
17047
|
}
|
|
16995
17048
|
createId() {
|
|
16996
17049
|
return `ds_${(0, _tmagic_utils.guid)()}`;
|
|
@@ -18630,7 +18683,8 @@
|
|
|
18630
18683
|
*/
|
|
18631
18684
|
const isCompareMode = (0, vue.computed)(() => Boolean(props.isCompare && props.lastValues));
|
|
18632
18685
|
const notEditable = (0, vue.computed)(() => (0, _tmagic_form.filterFunction)(mForm, props.config.notEditable, props));
|
|
18633
|
-
const
|
|
18686
|
+
const codeBlockSidePanel = (0, vue.computed)(() => (uiService.get("sideBarItems") || []).find((item) => item.$key === SideItemKey.CODE_BLOCK));
|
|
18687
|
+
const hasCodeBlockSidePanel = (0, vue.computed)(() => codeBlockSidePanel.value);
|
|
18634
18688
|
/**
|
|
18635
18689
|
* 根据代码块id获取代码块参数配置
|
|
18636
18690
|
* @param codeId 代码块ID
|
|
@@ -18685,6 +18739,8 @@
|
|
|
18685
18739
|
emit("change", props.model[props.name], eventData);
|
|
18686
18740
|
};
|
|
18687
18741
|
const editCode = (id) => {
|
|
18742
|
+
const sideBarItem = codeBlockSidePanel.value;
|
|
18743
|
+
if (sideBarItem) uiService.set("sideBarActiveTabName", sideBarItem.text || sideBarItem.$key || SideItemKey.CODE_BLOCK);
|
|
18688
18744
|
eventBus?.emit("edit-code", id);
|
|
18689
18745
|
};
|
|
18690
18746
|
return (_ctx, _cache) => {
|
|
@@ -18817,6 +18873,15 @@
|
|
|
18817
18873
|
calcBoxPosition();
|
|
18818
18874
|
addDialogVisible.value = true;
|
|
18819
18875
|
};
|
|
18876
|
+
const editField = (row, index) => {
|
|
18877
|
+
fieldValues.value = {
|
|
18878
|
+
...row,
|
|
18879
|
+
index
|
|
18880
|
+
};
|
|
18881
|
+
fieldTitle.value = `编辑${row.title}`;
|
|
18882
|
+
calcBoxPosition();
|
|
18883
|
+
addDialogVisible.value = true;
|
|
18884
|
+
};
|
|
18820
18885
|
const fieldChange = ({ index, ...value }, data) => {
|
|
18821
18886
|
addDialogVisible.value = false;
|
|
18822
18887
|
if (index > -1) emit("change", value, {
|
|
@@ -18868,13 +18933,7 @@
|
|
|
18868
18933
|
actions: [{
|
|
18869
18934
|
text: "编辑",
|
|
18870
18935
|
handler: (row, index) => {
|
|
18871
|
-
|
|
18872
|
-
...row,
|
|
18873
|
-
index
|
|
18874
|
-
};
|
|
18875
|
-
fieldTitle.value = `编辑${row.title}`;
|
|
18876
|
-
calcBoxPosition();
|
|
18877
|
-
addDialogVisible.value = true;
|
|
18936
|
+
editField(row, index);
|
|
18878
18937
|
}
|
|
18879
18938
|
}, {
|
|
18880
18939
|
text: "删除",
|
|
@@ -19061,6 +19120,20 @@
|
|
|
19061
19120
|
const addFromJsonDialogVisible = (0, vue.useModel)(__props, "visible1");
|
|
19062
19121
|
const { height: editorHeight } = useEditorContentHeight();
|
|
19063
19122
|
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, (0, vue.inject)("parentFloating", (0, vue.ref)(null)));
|
|
19123
|
+
/**
|
|
19124
|
+
* 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的字段路径(字段名数组)。
|
|
19125
|
+
* 当前层消费 path[0],并把剩余路径下发给嵌套字段,实现逐层打开。
|
|
19126
|
+
*/
|
|
19127
|
+
const editingFieldPath = (0, vue.inject)("editingDataSourceFieldPath", (0, vue.computed)(() => []));
|
|
19128
|
+
(0, vue.provide)("editingDataSourceFieldPath", (0, vue.computed)(() => editingFieldPath.value.slice(1)));
|
|
19129
|
+
(0, vue.onMounted)(() => {
|
|
19130
|
+
const path = editingFieldPath.value;
|
|
19131
|
+
if (!path.length) return;
|
|
19132
|
+
const fields = props.model[props.name] || [];
|
|
19133
|
+
const index = fields.findIndex((field) => field.name === path[0]);
|
|
19134
|
+
if (index === -1) return;
|
|
19135
|
+
editField(fields[index], index);
|
|
19136
|
+
});
|
|
19064
19137
|
return (_ctx, _cache) => {
|
|
19065
19138
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$36, [
|
|
19066
19139
|
(0, vue.createVNode)((0, vue.unref)(_tmagic_table.MagicTable), {
|
|
@@ -19442,6 +19515,19 @@
|
|
|
19442
19515
|
const codeConfig = (0, vue.ref)();
|
|
19443
19516
|
const codeBlockEditorRef = (0, vue.useTemplateRef)("codeBlockEditor");
|
|
19444
19517
|
let editIndex = -1;
|
|
19518
|
+
const editMethod = (method, index) => {
|
|
19519
|
+
let codeContent = "({ params, dataSource, app }) => {\n // place your code here\n}";
|
|
19520
|
+
if (method.content) if (typeof method.content !== "string") codeContent = method.content.toString();
|
|
19521
|
+
else codeContent = method.content;
|
|
19522
|
+
codeConfig.value = {
|
|
19523
|
+
...cloneDeep$1(method),
|
|
19524
|
+
content: codeContent
|
|
19525
|
+
};
|
|
19526
|
+
editIndex = index;
|
|
19527
|
+
(0, vue.nextTick)(() => {
|
|
19528
|
+
codeBlockEditorRef.value?.show();
|
|
19529
|
+
});
|
|
19530
|
+
};
|
|
19445
19531
|
const methodColumns = [
|
|
19446
19532
|
{
|
|
19447
19533
|
label: "名称",
|
|
@@ -19466,17 +19552,7 @@
|
|
|
19466
19552
|
actions: [{
|
|
19467
19553
|
text: "编辑",
|
|
19468
19554
|
handler: (method, index) => {
|
|
19469
|
-
|
|
19470
|
-
if (method.content) if (typeof method.content !== "string") codeContent = method.content.toString();
|
|
19471
|
-
else codeContent = method.content;
|
|
19472
|
-
codeConfig.value = {
|
|
19473
|
-
...cloneDeep$1(method),
|
|
19474
|
-
content: codeContent
|
|
19475
|
-
};
|
|
19476
|
-
editIndex = index;
|
|
19477
|
-
(0, vue.nextTick)(() => {
|
|
19478
|
-
codeBlockEditorRef.value?.show();
|
|
19479
|
-
});
|
|
19555
|
+
editMethod(method, index);
|
|
19480
19556
|
}
|
|
19481
19557
|
}, {
|
|
19482
19558
|
text: "删除",
|
|
@@ -19524,6 +19600,16 @@
|
|
|
19524
19600
|
codeConfig.value = void 0;
|
|
19525
19601
|
codeBlockEditorRef.value?.hide();
|
|
19526
19602
|
};
|
|
19603
|
+
/** 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的方法名 */
|
|
19604
|
+
const editingMethodName = (0, vue.inject)("editingDataSourceMethodName", (0, vue.computed)(() => ""));
|
|
19605
|
+
(0, vue.onMounted)(() => {
|
|
19606
|
+
const methodName = editingMethodName.value;
|
|
19607
|
+
if (!methodName) return;
|
|
19608
|
+
const methods = props.model[props.name] || [];
|
|
19609
|
+
const index = methods.findIndex((method) => method.name === methodName);
|
|
19610
|
+
if (index === -1) return;
|
|
19611
|
+
editMethod(methods[index], index);
|
|
19612
|
+
});
|
|
19527
19613
|
return (_ctx, _cache) => {
|
|
19528
19614
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$34, [
|
|
19529
19615
|
(0, vue.createVNode)((0, vue.unref)(_tmagic_table.MagicTable), {
|
|
@@ -19951,7 +20037,7 @@
|
|
|
19951
20037
|
const eventBus = (0, vue.inject)("eventBus");
|
|
19952
20038
|
const emit = __emit;
|
|
19953
20039
|
const props = __props;
|
|
19954
|
-
const
|
|
20040
|
+
const dataSourceSidePanel = (0, vue.computed)(() => (uiService.get("sideBarItems") || []).find((item) => item.$key === SideItemKey.DATA_SOURCE));
|
|
19955
20041
|
const notEditable = (0, vue.computed)(() => (0, _tmagic_form.filterFunction)(mForm, props.config.notEditable, props));
|
|
19956
20042
|
/** 对比模式下隐藏查看/编辑操作按钮,仅保留只读展示。 */
|
|
19957
20043
|
const isCompare = (0, vue.computed)(() => Boolean(mForm?.isCompare));
|
|
@@ -20039,9 +20125,11 @@
|
|
|
20039
20125
|
emit("change", props.model[props.name], eventData);
|
|
20040
20126
|
};
|
|
20041
20127
|
const editCodeHandler = () => {
|
|
20042
|
-
const [id] = props.model[props.name];
|
|
20128
|
+
const [id, methodName] = props.model[props.name];
|
|
20043
20129
|
if (!dataSourceService.getDataSourceById(id)) return;
|
|
20044
|
-
|
|
20130
|
+
const sideBarItem = dataSourceSidePanel.value;
|
|
20131
|
+
if (sideBarItem) uiService.set("sideBarActiveTabName", sideBarItem.text || sideBarItem.$key || SideItemKey.DATA_SOURCE);
|
|
20132
|
+
eventBus?.emit("edit-data-source-method", id, methodName);
|
|
20045
20133
|
};
|
|
20046
20134
|
return (_ctx, _cache) => {
|
|
20047
20135
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$31, [(0, vue.createElementVNode)("div", _hoisted_2$6, [(0, vue.createVNode)((0, vue.unref)(_tmagic_form.MCascader), {
|
|
@@ -20060,7 +20148,7 @@
|
|
|
20060
20148
|
"size",
|
|
20061
20149
|
"disabled",
|
|
20062
20150
|
"prop"
|
|
20063
|
-
]), __props.model[__props.name] && isCustomMethod.value &&
|
|
20151
|
+
]), __props.model[__props.name] && isCustomMethod.value && dataSourceSidePanel.value && !isCompare.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
|
|
20064
20152
|
key: 0,
|
|
20065
20153
|
content: notEditable.value ? "查看" : "编辑"
|
|
20066
20154
|
}, {
|
|
@@ -20176,9 +20264,15 @@
|
|
|
20176
20264
|
modelValue.value = v;
|
|
20177
20265
|
emit("change", v);
|
|
20178
20266
|
};
|
|
20179
|
-
const
|
|
20267
|
+
const dataSourceSidePanel = (0, vue.computed)(() => uiService.get("sideBarItems").find((item) => item.$key === SideItemKey.DATA_SOURCE));
|
|
20268
|
+
const hasDataSourceSidePanel = (0, vue.computed)(() => dataSourceSidePanel.value);
|
|
20180
20269
|
const editHandler = (id) => {
|
|
20181
|
-
|
|
20270
|
+
const sideBarItem = dataSourceSidePanel.value;
|
|
20271
|
+
if (sideBarItem) uiService.set("sideBarActiveTabName", sideBarItem.text || sideBarItem.$key || SideItemKey.DATA_SOURCE);
|
|
20272
|
+
const dataSourceId = (0, _tmagic_utils.removeDataSourceFieldPrefix)(id);
|
|
20273
|
+
const fieldPath = selectFieldsId.value;
|
|
20274
|
+
if (fieldPath.length) eventBus?.emit("edit-data-source-field", dataSourceId, [...fieldPath]);
|
|
20275
|
+
else eventBus?.emit("edit-data-source", dataSourceId);
|
|
20182
20276
|
};
|
|
20183
20277
|
return (_ctx, _cache) => {
|
|
20184
20278
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$30, [__props.dataSourceId ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicCascader), {
|
|
@@ -22397,6 +22491,13 @@
|
|
|
22397
22491
|
] }));
|
|
22398
22492
|
const selectDirection = (d) => direction.value = d || "";
|
|
22399
22493
|
const emit = __emit;
|
|
22494
|
+
const props = __props;
|
|
22495
|
+
const hasValue = (value) => value !== void 0 && value !== null && value !== "";
|
|
22496
|
+
const isConfigured = (d) => [
|
|
22497
|
+
"Width",
|
|
22498
|
+
"Color",
|
|
22499
|
+
"Style"
|
|
22500
|
+
].some((key) => hasValue(props.model?.[`border${d}${key}`]));
|
|
22400
22501
|
const change = (value, eventData) => {
|
|
22401
22502
|
eventData.changeRecords?.forEach((record) => {
|
|
22402
22503
|
emit("change", record.value, { modifyKey: record.propPath });
|
|
@@ -22406,25 +22507,40 @@
|
|
|
22406
22507
|
return (_ctx, _cache) => {
|
|
22407
22508
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$1, [(0, vue.createElementVNode)("div", _hoisted_2, [
|
|
22408
22509
|
(0, vue.createElementVNode)("div", _hoisted_3, [(0, vue.createElementVNode)("div", {
|
|
22409
|
-
class: (0, vue.normalizeClass)(["border-icon border-icon-top", {
|
|
22510
|
+
class: (0, vue.normalizeClass)(["border-icon border-icon-top", {
|
|
22511
|
+
active: direction.value === "Top",
|
|
22512
|
+
configured: isConfigured("Top")
|
|
22513
|
+
}]),
|
|
22410
22514
|
onClick: _cache[0] || (_cache[0] = ($event) => selectDirection("Top"))
|
|
22411
22515
|
}, null, 2)]),
|
|
22412
22516
|
(0, vue.createElementVNode)("div", _hoisted_4, [
|
|
22413
22517
|
(0, vue.createElementVNode)("div", {
|
|
22414
|
-
class: (0, vue.normalizeClass)(["border-icon border-icon-left", {
|
|
22518
|
+
class: (0, vue.normalizeClass)(["border-icon border-icon-left", {
|
|
22519
|
+
active: direction.value === "Left",
|
|
22520
|
+
configured: isConfigured("Left")
|
|
22521
|
+
}]),
|
|
22415
22522
|
onClick: _cache[1] || (_cache[1] = ($event) => selectDirection("Left"))
|
|
22416
22523
|
}, null, 2),
|
|
22417
22524
|
(0, vue.createElementVNode)("div", {
|
|
22418
|
-
class: (0, vue.normalizeClass)(["border-icon", {
|
|
22525
|
+
class: (0, vue.normalizeClass)(["border-icon", {
|
|
22526
|
+
active: direction.value === "",
|
|
22527
|
+
configured: isConfigured("")
|
|
22528
|
+
}]),
|
|
22419
22529
|
onClick: _cache[2] || (_cache[2] = ($event) => selectDirection())
|
|
22420
22530
|
}, null, 2),
|
|
22421
22531
|
(0, vue.createElementVNode)("div", {
|
|
22422
|
-
class: (0, vue.normalizeClass)(["border-icon border-icon-right", {
|
|
22532
|
+
class: (0, vue.normalizeClass)(["border-icon border-icon-right", {
|
|
22533
|
+
active: direction.value === "Right",
|
|
22534
|
+
configured: isConfigured("Right")
|
|
22535
|
+
}]),
|
|
22423
22536
|
onClick: _cache[3] || (_cache[3] = ($event) => selectDirection("Right"))
|
|
22424
22537
|
}, null, 2)
|
|
22425
22538
|
]),
|
|
22426
22539
|
(0, vue.createElementVNode)("div", _hoisted_5, [(0, vue.createElementVNode)("div", {
|
|
22427
|
-
class: (0, vue.normalizeClass)(["border-icon border-icon-bottom", {
|
|
22540
|
+
class: (0, vue.normalizeClass)(["border-icon border-icon-bottom", {
|
|
22541
|
+
active: direction.value === "Bottom",
|
|
22542
|
+
configured: isConfigured("Bottom")
|
|
22543
|
+
}]),
|
|
22428
22544
|
onClick: _cache[4] || (_cache[4] = ($event) => selectDirection("Bottom"))
|
|
22429
22545
|
}, null, 2)])
|
|
22430
22546
|
]), (0, vue.createElementVNode)("div", _hoisted_6, [(0, vue.createVNode)((0, vue.unref)(_tmagic_form.MContainer), {
|
|
@@ -23138,6 +23254,7 @@
|
|
|
23138
23254
|
exports.getFormValue = getFormValue;
|
|
23139
23255
|
exports.getGuideLineFromCache = getGuideLineFromCache;
|
|
23140
23256
|
exports.getInitPositionStyle = getInitPositionStyle;
|
|
23257
|
+
exports.getLastPushedHistoryIds = getLastPushedHistoryIds;
|
|
23141
23258
|
exports.getNodeIndex = getNodeIndex;
|
|
23142
23259
|
exports.getOrCreateStack = getOrCreateStack;
|
|
23143
23260
|
exports.getPageFragmentList = getPageFragmentList;
|