@oml/markdown 0.12.0 → 0.14.0
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/out/index.d.ts +1 -0
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/md/md-execution.d.ts +3 -3
- package/out/md/md-execution.js +1 -1
- package/out/md/md-execution.js.map +1 -1
- package/out/md/md-executor.js +6 -8
- package/out/md/md-executor.js.map +1 -1
- package/out/md/md-frontmatter.d.ts +1 -1
- package/out/md/md-frontmatter.js +15 -10
- package/out/md/md-frontmatter.js.map +1 -1
- package/out/md/md-runtime.js +1 -1
- package/out/md/md-runtime.js.map +1 -1
- package/out/md/md-types.d.ts +2 -2
- package/out/renderers/diagram-renderer.js +231 -12
- package/out/renderers/diagram-renderer.js.map +1 -1
- package/out/renderers/graph-renderer.js +2 -2
- package/out/renderers/graph-renderer.js.map +1 -1
- package/out/renderers/table-renderer.js +25 -10
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +489 -25
- package/out/static/browser-runtime.bundle.js.map +3 -3
- package/out/static/browser-runtime.js +258 -0
- package/out/static/browser-runtime.js.map +1 -1
- package/out/static/runtime-assets.d.ts +1 -1
- package/out/static/runtime-assets.js +1 -0
- package/out/static/runtime-assets.js.map +1 -1
- package/out/template/binder.d.ts +2 -0
- package/out/template/binder.js +56 -0
- package/out/template/binder.js.map +1 -0
- package/out/template/catalog.d.ts +8 -0
- package/out/template/catalog.js +26 -0
- package/out/template/catalog.js.map +1 -0
- package/out/template/compose.d.ts +7 -0
- package/out/template/compose.js +93 -0
- package/out/template/compose.js.map +1 -0
- package/out/template/definition.d.ts +3 -0
- package/out/template/definition.js +204 -0
- package/out/template/definition.js.map +1 -0
- package/out/template/engine.d.ts +8 -0
- package/out/template/engine.js +30 -0
- package/out/template/engine.js.map +1 -0
- package/out/template/index.d.ts +7 -0
- package/out/template/index.js +9 -0
- package/out/template/index.js.map +1 -0
- package/out/template/resolver.d.ts +4 -0
- package/out/template/resolver.js +58 -0
- package/out/template/resolver.js.map +1 -0
- package/out/template/types.d.ts +82 -0
- package/out/template/types.js +3 -0
- package/out/template/types.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/md/md-execution.ts +3 -3
- package/src/md/md-executor.ts +6 -9
- package/src/md/md-frontmatter.ts +15 -10
- package/src/md/md-runtime.ts +1 -1
- package/src/md/md-types.ts +2 -2
- package/src/renderers/diagram-renderer.ts +229 -12
- package/src/renderers/graph-renderer.ts +2 -2
- package/src/renderers/table-renderer.ts +26 -10
- package/src/static/browser-runtime.ts +305 -0
- package/src/static/markdown-webview.css +13 -0
- package/src/static/runtime-assets.ts +1 -0
- package/src/template/binder.ts +70 -0
- package/src/template/catalog.ts +35 -0
- package/src/template/compose.ts +107 -0
- package/src/template/definition.ts +222 -0
- package/src/template/engine.ts +45 -0
- package/src/template/index.ts +9 -0
- package/src/template/resolver.ts +75 -0
- package/src/template/types.ts +111 -0
|
@@ -236,6 +236,12 @@ async function renderWithX6(
|
|
|
236
236
|
container: liveCanvas,
|
|
237
237
|
autoResize: false,
|
|
238
238
|
grid: false,
|
|
239
|
+
selecting: {
|
|
240
|
+
enabled: true,
|
|
241
|
+
multiple: true,
|
|
242
|
+
// X6 native additive selection modifiers.
|
|
243
|
+
multipleSelectionModifiers: ['meta', 'ctrl'],
|
|
244
|
+
},
|
|
239
245
|
panning: true,
|
|
240
246
|
mousewheel: {
|
|
241
247
|
enabled: true,
|
|
@@ -315,7 +321,7 @@ async function renderWithX6(
|
|
|
315
321
|
bubbles: true,
|
|
316
322
|
detail: {
|
|
317
323
|
iri,
|
|
318
|
-
previewEnabled:
|
|
324
|
+
previewEnabled: event.altKey,
|
|
319
325
|
anchorRect: {
|
|
320
326
|
left: rect.left,
|
|
321
327
|
right: rect.right,
|
|
@@ -1079,26 +1085,200 @@ async function renderWithX6(
|
|
|
1079
1085
|
}
|
|
1080
1086
|
|
|
1081
1087
|
// Compartments are structural containers: do not drag them; select parent instead.
|
|
1082
|
-
const
|
|
1088
|
+
const selectionTargetForNode = (node: any): any => {
|
|
1083
1089
|
if (!isCompartmentNode(node)) {
|
|
1084
|
-
return;
|
|
1090
|
+
return node;
|
|
1085
1091
|
}
|
|
1086
1092
|
const parent = typeof node.getParent === 'function' ? node.getParent() : undefined;
|
|
1087
|
-
|
|
1093
|
+
return parent ?? node;
|
|
1094
|
+
};
|
|
1095
|
+
const multiSelectedNodeIds = new Set<string>();
|
|
1096
|
+
let primarySelectedNodeId: string | undefined;
|
|
1097
|
+
const cssEscape = (value: string): string => value.replace(/["\\]/g, '\\$&');
|
|
1098
|
+
const createSvgElement = (name: string): SVGElement =>
|
|
1099
|
+
document.createElementNS('http://www.w3.org/2000/svg', name);
|
|
1100
|
+
const clearSecondaryDecoration = (container: Element): void => {
|
|
1101
|
+
for (const node of Array.from(container.querySelectorAll('g.oml-secondary-selection'))) {
|
|
1102
|
+
node.remove();
|
|
1103
|
+
}
|
|
1104
|
+
for (const node of Array.from(container.querySelectorAll('[data-oml-multi-selected-style="1"]'))) {
|
|
1105
|
+
if (!(node instanceof SVGElement)) {
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
node.style.removeProperty('stroke');
|
|
1109
|
+
node.style.removeProperty('stroke-width');
|
|
1110
|
+
node.removeAttribute('data-oml-multi-selected-style');
|
|
1111
|
+
}
|
|
1112
|
+
};
|
|
1113
|
+
const renderSecondaryDecoration = (container: Element): void => {
|
|
1114
|
+
clearSecondaryDecoration(container);
|
|
1115
|
+
const graphics = container as unknown as SVGGraphicsElement;
|
|
1116
|
+
if (typeof graphics.getBBox !== 'function') {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
let bbox: DOMRect | undefined;
|
|
1120
|
+
try {
|
|
1121
|
+
bbox = graphics.getBBox();
|
|
1122
|
+
} catch {
|
|
1088
1123
|
return;
|
|
1089
1124
|
}
|
|
1090
|
-
if (
|
|
1091
|
-
|
|
1125
|
+
if (!bbox || bbox.width <= 0 || bbox.height <= 0) {
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
const widgetMargin = 3;
|
|
1129
|
+
const handleSize = 6;
|
|
1130
|
+
const handleHalf = handleSize / 2;
|
|
1131
|
+
const x = bbox.x - widgetMargin;
|
|
1132
|
+
const y = bbox.y - widgetMargin;
|
|
1133
|
+
const width = bbox.width + (widgetMargin * 2);
|
|
1134
|
+
const height = bbox.height + (widgetMargin * 2);
|
|
1135
|
+
|
|
1136
|
+
const group = createSvgElement('g');
|
|
1137
|
+
group.setAttribute('class', 'oml-secondary-selection');
|
|
1138
|
+
group.setAttribute('pointer-events', 'none');
|
|
1139
|
+
|
|
1140
|
+
const box = createSvgElement('rect');
|
|
1141
|
+
box.setAttribute('x', `${x}`);
|
|
1142
|
+
box.setAttribute('y', `${y}`);
|
|
1143
|
+
box.setAttribute('width', `${width}`);
|
|
1144
|
+
box.setAttribute('height', `${height}`);
|
|
1145
|
+
box.setAttribute('fill', 'none');
|
|
1146
|
+
box.setAttribute('stroke', '#000');
|
|
1147
|
+
box.setAttribute('stroke-width', '1');
|
|
1148
|
+
box.setAttribute('stroke-dasharray', '4 3');
|
|
1149
|
+
group.appendChild(box);
|
|
1150
|
+
|
|
1151
|
+
const points = [
|
|
1152
|
+
[x, y],
|
|
1153
|
+
[x + (width / 2), y],
|
|
1154
|
+
[x + width, y],
|
|
1155
|
+
[x, y + (height / 2)],
|
|
1156
|
+
[x + width, y + (height / 2)],
|
|
1157
|
+
[x, y + height],
|
|
1158
|
+
[x + (width / 2), y + height],
|
|
1159
|
+
[x + width, y + height],
|
|
1160
|
+
];
|
|
1161
|
+
for (const [cx, cy] of points) {
|
|
1162
|
+
const handle = createSvgElement('rect');
|
|
1163
|
+
handle.setAttribute('x', `${cx - handleHalf}`);
|
|
1164
|
+
handle.setAttribute('y', `${cy - handleHalf}`);
|
|
1165
|
+
handle.setAttribute('width', `${handleSize}`);
|
|
1166
|
+
handle.setAttribute('height', `${handleSize}`);
|
|
1167
|
+
handle.setAttribute('rx', '3');
|
|
1168
|
+
handle.setAttribute('ry', '3');
|
|
1169
|
+
handle.setAttribute('fill', '#000');
|
|
1170
|
+
handle.setAttribute('stroke', '#000');
|
|
1171
|
+
handle.setAttribute('stroke-width', '1');
|
|
1172
|
+
group.appendChild(handle);
|
|
1173
|
+
}
|
|
1174
|
+
container.appendChild(group);
|
|
1175
|
+
};
|
|
1176
|
+
const refreshPrimaryWidget = (): void => {
|
|
1177
|
+
if (typeof nodeTransform?.clearWidgets === 'function') {
|
|
1178
|
+
nodeTransform.clearWidgets();
|
|
1179
|
+
}
|
|
1180
|
+
if (!primarySelectedNodeId || typeof nodeTransform?.createWidget !== 'function') {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
const cell = typeof graphView.getCellById === 'function' ? graphView.getCellById(primarySelectedNodeId) : undefined;
|
|
1184
|
+
if (!cell) {
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
nodeTransform.createWidget(cell);
|
|
1188
|
+
};
|
|
1189
|
+
let applySelectionScheduled = false;
|
|
1190
|
+
const applyMultiSelectionClassesNow = (): void => {
|
|
1191
|
+
const selectedIds = new Set(multiSelectedNodeIds);
|
|
1192
|
+
const nodeContainers = Array.from(liveCanvas.querySelectorAll('.x6-cell[data-cell-id], .x6-node[data-cell-id]'));
|
|
1193
|
+
for (const element of nodeContainers) {
|
|
1194
|
+
const container = element as Element;
|
|
1195
|
+
const id = String(container.getAttribute('data-cell-id') ?? '');
|
|
1196
|
+
const selected = selectedIds.has(id);
|
|
1197
|
+
container.classList.toggle('oml-diagram-multi-selected', selected);
|
|
1198
|
+
if (selected && id !== primarySelectedNodeId) {
|
|
1199
|
+
renderSecondaryDecoration(container);
|
|
1200
|
+
} else {
|
|
1201
|
+
clearSecondaryDecoration(container);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
for (const id of selectedIds) {
|
|
1205
|
+
const selector = `.x6-cell[data-cell-id="${cssEscape(id)}"], .x6-node[data-cell-id="${cssEscape(id)}"]`;
|
|
1206
|
+
const domMatches = Array.from(liveCanvas.querySelectorAll(selector));
|
|
1207
|
+
for (const element of domMatches) {
|
|
1208
|
+
if (element instanceof Element) {
|
|
1209
|
+
element.classList.add('oml-diagram-multi-selected');
|
|
1210
|
+
if (id !== primarySelectedNodeId) {
|
|
1211
|
+
renderSecondaryDecoration(element);
|
|
1212
|
+
} else {
|
|
1213
|
+
clearSecondaryDecoration(element);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
const cell = typeof graphView.getCellById === 'function' ? graphView.getCellById(id) : undefined;
|
|
1218
|
+
const view = cell && typeof graphView.findViewByCell === 'function' ? graphView.findViewByCell(cell) : undefined;
|
|
1219
|
+
const container = view?.container as Element | undefined;
|
|
1220
|
+
if (container instanceof Element) {
|
|
1221
|
+
container.classList.add('oml-diagram-multi-selected');
|
|
1222
|
+
if (id !== primarySelectedNodeId) {
|
|
1223
|
+
renderSecondaryDecoration(container);
|
|
1224
|
+
} else {
|
|
1225
|
+
clearSecondaryDecoration(container);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
const applyMultiSelectionClasses = (): void => {
|
|
1231
|
+
if (applySelectionScheduled) {
|
|
1232
|
+
return;
|
|
1092
1233
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1234
|
+
applySelectionScheduled = true;
|
|
1235
|
+
window.requestAnimationFrame(() => {
|
|
1236
|
+
window.requestAnimationFrame(() => {
|
|
1237
|
+
applySelectionScheduled = false;
|
|
1238
|
+
applyMultiSelectionClassesNow();
|
|
1239
|
+
});
|
|
1240
|
+
});
|
|
1241
|
+
};
|
|
1242
|
+
const replaceMultiSelection = (ids: Iterable<string>): void => {
|
|
1243
|
+
multiSelectedNodeIds.clear();
|
|
1244
|
+
for (const id of ids) {
|
|
1245
|
+
if (!id) {
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
multiSelectedNodeIds.add(id);
|
|
1095
1249
|
}
|
|
1250
|
+
applyMultiSelectionClasses();
|
|
1251
|
+
};
|
|
1252
|
+
const clearMultiSelection = (): void => {
|
|
1253
|
+
multiSelectedNodeIds.clear();
|
|
1254
|
+
applyMultiSelectionClasses();
|
|
1096
1255
|
};
|
|
1097
1256
|
graphView.on('node:mousedown', ({ node, e }: { node: any; e: MouseEvent }) => {
|
|
1257
|
+
const targetCell = selectionTargetForNode(node);
|
|
1258
|
+
if (!targetCell) {
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const targetId = String(targetCell?.id ?? '');
|
|
1262
|
+
const additive = !!(e.metaKey || e.ctrlKey || e.shiftKey);
|
|
1263
|
+
if (additive) {
|
|
1264
|
+
if (multiSelectedNodeIds.has(targetId)) {
|
|
1265
|
+
multiSelectedNodeIds.delete(targetId);
|
|
1266
|
+
if (primarySelectedNodeId === targetId) {
|
|
1267
|
+
primarySelectedNodeId = multiSelectedNodeIds.values().next().value;
|
|
1268
|
+
}
|
|
1269
|
+
} else if (targetId) {
|
|
1270
|
+
multiSelectedNodeIds.add(targetId);
|
|
1271
|
+
primarySelectedNodeId = targetId;
|
|
1272
|
+
}
|
|
1273
|
+
} else if (targetId) {
|
|
1274
|
+
replaceMultiSelection([targetId]);
|
|
1275
|
+
primarySelectedNodeId = targetId;
|
|
1276
|
+
}
|
|
1277
|
+
applyMultiSelectionClasses();
|
|
1278
|
+
refreshPrimaryWidget();
|
|
1098
1279
|
if (!isCompartmentNode(node)) {
|
|
1099
1280
|
return;
|
|
1100
1281
|
}
|
|
1101
|
-
selectCompartmentParent(node);
|
|
1102
1282
|
e.preventDefault();
|
|
1103
1283
|
e.stopPropagation();
|
|
1104
1284
|
if (typeof (e as any).stopImmediatePropagation === 'function') {
|
|
@@ -1106,12 +1286,49 @@ async function renderWithX6(
|
|
|
1106
1286
|
}
|
|
1107
1287
|
});
|
|
1108
1288
|
graphView.on('node:click', ({ node, e }: { node: any; e: MouseEvent }) => {
|
|
1109
|
-
if (
|
|
1289
|
+
if (isCompartmentNode(node)) {
|
|
1290
|
+
refreshPrimaryWidget();
|
|
1291
|
+
e.preventDefault();
|
|
1292
|
+
e.stopPropagation();
|
|
1293
|
+
if (typeof (e as any).stopImmediatePropagation === 'function') {
|
|
1294
|
+
(e as any).stopImmediatePropagation();
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
graphView.on('node:contextmenu', ({ node, e }: { node: any; e: MouseEvent }) => {
|
|
1299
|
+
const targetCell = selectionTargetForNode(node);
|
|
1300
|
+
const targetId = String(targetCell?.id ?? '');
|
|
1301
|
+
if (!targetId) {
|
|
1110
1302
|
return;
|
|
1111
1303
|
}
|
|
1112
|
-
|
|
1304
|
+
if (!multiSelectedNodeIds.has(targetId)) {
|
|
1305
|
+
multiSelectedNodeIds.clear();
|
|
1306
|
+
multiSelectedNodeIds.add(targetId);
|
|
1307
|
+
primarySelectedNodeId = targetId;
|
|
1308
|
+
applyMultiSelectionClasses();
|
|
1309
|
+
refreshPrimaryWidget();
|
|
1310
|
+
}
|
|
1311
|
+
const selectedIris = [...multiSelectedNodeIds];
|
|
1312
|
+
liveCanvas.dispatchEvent(new CustomEvent('md-diagram-selection-contextmenu', {
|
|
1313
|
+
bubbles: true,
|
|
1314
|
+
detail: {
|
|
1315
|
+
iri: targetId,
|
|
1316
|
+
name: displayLabelFromIri(targetId),
|
|
1317
|
+
selectedIris,
|
|
1318
|
+
clientX: e.clientX,
|
|
1319
|
+
clientY: e.clientY,
|
|
1320
|
+
},
|
|
1321
|
+
}));
|
|
1113
1322
|
e.preventDefault();
|
|
1114
1323
|
e.stopPropagation();
|
|
1324
|
+
if (typeof (e as any).stopImmediatePropagation === 'function') {
|
|
1325
|
+
(e as any).stopImmediatePropagation();
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
graphView.on('blank:mousedown', () => {
|
|
1329
|
+
clearMultiSelection();
|
|
1330
|
+
primarySelectedNodeId = undefined;
|
|
1331
|
+
refreshPrimaryWidget();
|
|
1115
1332
|
});
|
|
1116
1333
|
|
|
1117
1334
|
const sidePriority = (side: PortSide): number => {
|
|
@@ -1339,7 +1556,7 @@ function installDiagramNodeInteractions(canvas: HTMLElement, graphView: any): vo
|
|
|
1339
1556
|
bubbles: true,
|
|
1340
1557
|
detail: {
|
|
1341
1558
|
iri,
|
|
1342
|
-
previewEnabled: !!e &&
|
|
1559
|
+
previewEnabled: !!e && e.altKey,
|
|
1343
1560
|
anchorRect: {
|
|
1344
1561
|
left: bbox.left,
|
|
1345
1562
|
right: bbox.right,
|
|
@@ -697,7 +697,7 @@ function installGraphNodeInteractions(
|
|
|
697
697
|
bubbles: true,
|
|
698
698
|
detail: {
|
|
699
699
|
iri,
|
|
700
|
-
previewEnabled: !!e &&
|
|
700
|
+
previewEnabled: !!e && e.altKey,
|
|
701
701
|
anchorRect: {
|
|
702
702
|
left: bbox.left,
|
|
703
703
|
right: bbox.right,
|
|
@@ -739,7 +739,7 @@ function installGraphNodeInteractions(
|
|
|
739
739
|
detail: {
|
|
740
740
|
blockId,
|
|
741
741
|
blockSource: source,
|
|
742
|
-
|
|
742
|
+
contextMemberIri: iri.trim(),
|
|
743
743
|
},
|
|
744
744
|
}));
|
|
745
745
|
return;
|
|
@@ -146,9 +146,11 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
146
146
|
cells: visibleColumnIndexes.map((columnIndex) => row.cells[columnIndex] ?? ''),
|
|
147
147
|
typedCells: visibleColumnIndexes.map((columnIndex) => row.typedCells?.[columnIndex]),
|
|
148
148
|
}));
|
|
149
|
+
const dedupeVisibleRows = hiddenColumns.size > 0 && !isTree;
|
|
150
|
+
const visibleRows = dedupeVisibleRows ? dedupeRowsByDisplayedCells(rowsWithIndex) : rowsWithIndex;
|
|
149
151
|
root.__omlAiContext = {
|
|
150
152
|
columns: visibleColumns.slice(),
|
|
151
|
-
rows:
|
|
153
|
+
rows: visibleRows
|
|
152
154
|
.map((row) => ({
|
|
153
155
|
iri: (row.cells[0] ?? '').trim(),
|
|
154
156
|
cells: row.cells.slice(),
|
|
@@ -156,7 +158,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
156
158
|
.filter((row) => row.iri.length > 0),
|
|
157
159
|
blockSource,
|
|
158
160
|
};
|
|
159
|
-
const columnContexts = createColumnContexts(visibleColumns,
|
|
161
|
+
const columnContexts = createColumnContexts(visibleColumns, visibleRows);
|
|
160
162
|
const treeModel = isTree
|
|
161
163
|
? this.createTreeModel(columns, allRowsWithIndex, visibleColumnIndexes, options)
|
|
162
164
|
: undefined;
|
|
@@ -275,7 +277,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
275
277
|
downloadButton.addEventListener('click', () => {
|
|
276
278
|
const sourceRows = isTree && treeModel
|
|
277
279
|
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search, blockSource, options)
|
|
278
|
-
:
|
|
280
|
+
: visibleRows;
|
|
279
281
|
if (isTree && treeModel) {
|
|
280
282
|
this.requestTreeJsonDownload(visibleColumns, treeModel, sourceRows);
|
|
281
283
|
return;
|
|
@@ -286,7 +288,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
286
288
|
});
|
|
287
289
|
controlsRight.appendChild(downloadButton);
|
|
288
290
|
|
|
289
|
-
const uploadButton = this.createUploadCsvButton(visibleColumns,
|
|
291
|
+
const uploadButton = this.createUploadCsvButton(visibleColumns, visibleRows, isTree, blockSource);
|
|
290
292
|
if (uploadButton) {
|
|
291
293
|
controlsRight.appendChild(uploadButton);
|
|
292
294
|
}
|
|
@@ -336,7 +338,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
336
338
|
if (isTree) {
|
|
337
339
|
return;
|
|
338
340
|
}
|
|
339
|
-
const filtered = this.applyFiltersAndSorting(visibleColumns,
|
|
341
|
+
const filtered = this.applyFiltersAndSorting(visibleColumns, visibleRows, state, blockSource, options);
|
|
340
342
|
const totalPages = Math.max(1, Math.ceil(filtered.length / state.pageSize));
|
|
341
343
|
if (state.page < totalPages - 1) {
|
|
342
344
|
state.page += 1;
|
|
@@ -359,7 +361,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
359
361
|
const renderPage = () => {
|
|
360
362
|
const sourceRows = isTree && treeModel
|
|
361
363
|
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search, blockSource, options)
|
|
362
|
-
:
|
|
364
|
+
: visibleRows;
|
|
363
365
|
const filtered = isTree
|
|
364
366
|
? sourceRows.slice()
|
|
365
367
|
: this.applyFiltersAndSorting(visibleColumns, sourceRows, state, blockSource, options);
|
|
@@ -408,7 +410,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
408
410
|
state,
|
|
409
411
|
root,
|
|
410
412
|
columns: visibleColumns,
|
|
411
|
-
rows: fullyExpandedTreeRows ??
|
|
413
|
+
rows: fullyExpandedTreeRows ?? visibleRows,
|
|
412
414
|
referenceCell: label,
|
|
413
415
|
rerender: renderPage,
|
|
414
416
|
});
|
|
@@ -463,7 +465,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
463
465
|
this.onRowDoubleClick({
|
|
464
466
|
root,
|
|
465
467
|
columns: visibleColumns,
|
|
466
|
-
rows:
|
|
468
|
+
rows: visibleRows.map((row) => ({ index: row.index, cells: row.cells.slice() })),
|
|
467
469
|
row: { index: rowEntry.index, cells: rowEntry.cells.slice() },
|
|
468
470
|
blockSource,
|
|
469
471
|
typeOptions: this.extractTypeOptions(blockSource),
|
|
@@ -484,7 +486,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
484
486
|
this.appendCustomLeftControls(controlsLeft, {
|
|
485
487
|
root,
|
|
486
488
|
columns: visibleColumns,
|
|
487
|
-
rows:
|
|
489
|
+
rows: visibleRows.map((row) => ({ index: row.index, cells: row.cells.slice() })),
|
|
488
490
|
blockSource,
|
|
489
491
|
options,
|
|
490
492
|
typeOptions: this.extractTypeOptions(blockSource),
|
|
@@ -494,7 +496,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
494
496
|
this.scheduleInitialAutosize({
|
|
495
497
|
root,
|
|
496
498
|
columns: visibleColumns,
|
|
497
|
-
rows: fullyExpandedTreeRows ??
|
|
499
|
+
rows: fullyExpandedTreeRows ?? visibleRows,
|
|
498
500
|
state,
|
|
499
501
|
rerender: renderPage,
|
|
500
502
|
});
|
|
@@ -1209,6 +1211,20 @@ type TableRowData = {
|
|
|
1209
1211
|
treeHasChildren?: boolean;
|
|
1210
1212
|
};
|
|
1211
1213
|
|
|
1214
|
+
function dedupeRowsByDisplayedCells(rows: ReadonlyArray<TableRowData>): TableRowData[] {
|
|
1215
|
+
const seen = new Set<string>();
|
|
1216
|
+
const deduped: TableRowData[] = [];
|
|
1217
|
+
for (const row of rows) {
|
|
1218
|
+
const key = row.cells.join('\u0000');
|
|
1219
|
+
if (seen.has(key)) {
|
|
1220
|
+
continue;
|
|
1221
|
+
}
|
|
1222
|
+
seen.add(key);
|
|
1223
|
+
deduped.push(row);
|
|
1224
|
+
}
|
|
1225
|
+
return deduped;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1212
1228
|
type TreeModel = {
|
|
1213
1229
|
rowsById: Map<string, TableRowData>;
|
|
1214
1230
|
childrenByParent: Map<string, string[]>;
|