@eventcatalog/visualiser 3.19.0 → 3.20.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/dist/index.d.mts +31 -22
- package/dist/index.d.ts +31 -22
- package/dist/index.js +738 -205
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +701 -157
- package/dist/index.mjs.map +1 -1
- package/dist/styles-core.css +192 -3
- package/dist/styles.css +192 -3
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -104,7 +104,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
104
104
|
var import_react79 = require("react");
|
|
105
105
|
var import_react_dom = require("react-dom");
|
|
106
106
|
var import_react80 = require("@xyflow/react");
|
|
107
|
-
var
|
|
107
|
+
var import_lucide_react32 = require("lucide-react");
|
|
108
108
|
var DropdownMenu2 = __toESM(require("@radix-ui/react-dropdown-menu"));
|
|
109
109
|
var import_html_to_image = require("html-to-image");
|
|
110
110
|
|
|
@@ -6101,7 +6101,64 @@ var FlowEdge_default = (0, import_react59.memo)(function CustomEdge({
|
|
|
6101
6101
|
|
|
6102
6102
|
// src/components/VisualiserSearch.tsx
|
|
6103
6103
|
var import_react61 = require("react");
|
|
6104
|
+
var import_lucide_react25 = require("lucide-react");
|
|
6104
6105
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
6106
|
+
var formatVersionedName = (name, version) => {
|
|
6107
|
+
if (version) {
|
|
6108
|
+
const nameWithoutVersion = name.replace(
|
|
6109
|
+
new RegExp(`-v?${version.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`),
|
|
6110
|
+
""
|
|
6111
|
+
);
|
|
6112
|
+
return `${nameWithoutVersion} (v${version})`;
|
|
6113
|
+
}
|
|
6114
|
+
const versionMatch = name.match(
|
|
6115
|
+
/^(.+)-v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/
|
|
6116
|
+
);
|
|
6117
|
+
if (!versionMatch) return name;
|
|
6118
|
+
return `${versionMatch[1]} (v${versionMatch[2]})`;
|
|
6119
|
+
};
|
|
6120
|
+
var normalizeCollectionType = (type) => {
|
|
6121
|
+
const aliases = {
|
|
6122
|
+
event: "events",
|
|
6123
|
+
command: "commands",
|
|
6124
|
+
query: "queries",
|
|
6125
|
+
service: "services",
|
|
6126
|
+
domain: "domains",
|
|
6127
|
+
channel: "channels",
|
|
6128
|
+
entity: "entities"
|
|
6129
|
+
};
|
|
6130
|
+
return aliases[type] || type;
|
|
6131
|
+
};
|
|
6132
|
+
var splitVersionedName = (name, version) => {
|
|
6133
|
+
if (version) {
|
|
6134
|
+
return {
|
|
6135
|
+
id: name.replace(
|
|
6136
|
+
new RegExp(`-v?${version.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`),
|
|
6137
|
+
""
|
|
6138
|
+
),
|
|
6139
|
+
version
|
|
6140
|
+
};
|
|
6141
|
+
}
|
|
6142
|
+
const versionMatch = name.match(
|
|
6143
|
+
/^(.+)-v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/
|
|
6144
|
+
);
|
|
6145
|
+
if (!versionMatch) return { id: name, version: void 0 };
|
|
6146
|
+
return { id: versionMatch[1], version: versionMatch[2] };
|
|
6147
|
+
};
|
|
6148
|
+
var getResourceKey = ({
|
|
6149
|
+
type,
|
|
6150
|
+
id,
|
|
6151
|
+
name,
|
|
6152
|
+
version
|
|
6153
|
+
}) => {
|
|
6154
|
+
const parsed = splitVersionedName(id || name, version);
|
|
6155
|
+
return `${normalizeCollectionType(type)}:${parsed.id}:${parsed.version || ""}`.toLowerCase();
|
|
6156
|
+
};
|
|
6157
|
+
var getNodeResourceData = (data, key) => {
|
|
6158
|
+
const resource = data?.[key];
|
|
6159
|
+
if (!resource || typeof resource !== "object") return void 0;
|
|
6160
|
+
return "data" in resource && resource.data ? resource.data : resource;
|
|
6161
|
+
};
|
|
6105
6162
|
var VisualiserSearch = (0, import_react61.memo)(
|
|
6106
6163
|
(0, import_react61.forwardRef)(
|
|
6107
6164
|
({ nodes, onNodeSelect, onClear, onPaneClick: _onPaneClick }, ref) => {
|
|
@@ -6111,6 +6168,8 @@ var VisualiserSearch = (0, import_react61.memo)(
|
|
|
6111
6168
|
const [selectedSuggestionIndex, setSelectedSuggestionIndex] = (0, import_react61.useState)(-1);
|
|
6112
6169
|
const searchInputRef = (0, import_react61.useRef)(null);
|
|
6113
6170
|
const containerRef = (0, import_react61.useRef)(null);
|
|
6171
|
+
const suggestionsListRef = (0, import_react61.useRef)(null);
|
|
6172
|
+
const suggestionItemRefs = (0, import_react61.useRef)([]);
|
|
6114
6173
|
const hideSuggestions = (0, import_react61.useCallback)(() => {
|
|
6115
6174
|
setShowSuggestions(false);
|
|
6116
6175
|
setSelectedSuggestionIndex(-1);
|
|
@@ -6129,84 +6188,277 @@ var VisualiserSearch = (0, import_react61.memo)(
|
|
|
6129
6188
|
if (node.type === "messageGroupExpanded") {
|
|
6130
6189
|
return node.data?.groupName || node.id;
|
|
6131
6190
|
}
|
|
6132
|
-
const
|
|
6133
|
-
const
|
|
6134
|
-
|
|
6191
|
+
const message = getNodeResourceData(node.data, "message");
|
|
6192
|
+
const service = getNodeResourceData(node.data, "service");
|
|
6193
|
+
const domain = getNodeResourceData(node.data, "domain");
|
|
6194
|
+
const entity = getNodeResourceData(node.data, "entity");
|
|
6195
|
+
const channel = getNodeResourceData(node.data, "channel");
|
|
6196
|
+
const dataProduct = getNodeResourceData(node.data, "dataProduct");
|
|
6197
|
+
const data = getNodeResourceData(node.data, "data");
|
|
6198
|
+
const name = message?.name || message?.id || service?.name || service?.id || domain?.name || domain?.id || entity?.name || entity?.id || channel?.name || channel?.id || dataProduct?.name || dataProduct?.id || data?.name || data?.id || node.data?.name || node.id;
|
|
6199
|
+
const version = message?.version || service?.version || domain?.version || entity?.version || channel?.version || dataProduct?.version || data?.version || node.data?.version;
|
|
6200
|
+
return formatVersionedName(name, version);
|
|
6135
6201
|
}, []);
|
|
6136
|
-
const
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6202
|
+
const getNodeResourceKey = (0, import_react61.useCallback)(
|
|
6203
|
+
(node, label) => {
|
|
6204
|
+
if (node.type === "messageGroup" || node.type === "messageGroupExpanded") {
|
|
6205
|
+
return `${node.type}:${node.id}`.toLowerCase();
|
|
6206
|
+
}
|
|
6207
|
+
const data = node.data;
|
|
6208
|
+
const resource = getNodeResourceData(data, "message") || getNodeResourceData(data, "service") || getNodeResourceData(data, "domain") || getNodeResourceData(data, "entity") || getNodeResourceData(data, "channel") || getNodeResourceData(data, "dataProduct") || data?.data || data;
|
|
6209
|
+
return getResourceKey({
|
|
6210
|
+
type: node.type || "unknown",
|
|
6211
|
+
id: resource?.id,
|
|
6212
|
+
name: resource?.name || resource?.id || label || node.id,
|
|
6213
|
+
version: resource?.version || data?.version
|
|
6214
|
+
});
|
|
6215
|
+
},
|
|
6216
|
+
[]
|
|
6217
|
+
);
|
|
6218
|
+
const dedupeSearchSuggestions = (0, import_react61.useCallback)(
|
|
6219
|
+
(suggestions) => {
|
|
6220
|
+
const uniqueSuggestions = [];
|
|
6221
|
+
const indexByResourceKey = /* @__PURE__ */ new Map();
|
|
6222
|
+
suggestions.forEach((suggestion) => {
|
|
6223
|
+
const existingIndex = indexByResourceKey.get(
|
|
6224
|
+
suggestion.resourceKey
|
|
6225
|
+
);
|
|
6226
|
+
if (existingIndex === void 0) {
|
|
6227
|
+
indexByResourceKey.set(
|
|
6228
|
+
suggestion.resourceKey,
|
|
6229
|
+
uniqueSuggestions.length
|
|
6230
|
+
);
|
|
6231
|
+
uniqueSuggestions.push(suggestion);
|
|
6232
|
+
return;
|
|
6233
|
+
}
|
|
6234
|
+
if (suggestion.isGroupedMessage && !uniqueSuggestions[existingIndex].isGroupedMessage) {
|
|
6235
|
+
uniqueSuggestions[existingIndex] = suggestion;
|
|
6236
|
+
}
|
|
6237
|
+
});
|
|
6238
|
+
return uniqueSuggestions;
|
|
6239
|
+
},
|
|
6240
|
+
[]
|
|
6241
|
+
);
|
|
6242
|
+
const getSearchSuggestions = (0, import_react61.useCallback)(
|
|
6243
|
+
(nodesToIndex) => {
|
|
6244
|
+
const suggestions = nodesToIndex.flatMap((node) => {
|
|
6245
|
+
const nodeName = getNodeDisplayName(node);
|
|
6246
|
+
const suggestions2 = [
|
|
6247
|
+
{
|
|
6248
|
+
key: node.id,
|
|
6249
|
+
node,
|
|
6250
|
+
label: nodeName,
|
|
6251
|
+
searchText: nodeName,
|
|
6252
|
+
type: node.type || "unknown",
|
|
6253
|
+
resourceKey: getNodeResourceKey(node, nodeName)
|
|
6254
|
+
}
|
|
6255
|
+
];
|
|
6256
|
+
if (node.type !== "messageGroup") return suggestions2;
|
|
6257
|
+
const groupName = node.data?.groupName || nodeName;
|
|
6258
|
+
const groupedMessages = node.data?.messages || [];
|
|
6259
|
+
groupedMessages.forEach((item, index) => {
|
|
6260
|
+
const message = item.message;
|
|
6261
|
+
const messageName = message?.data?.name || message?.data?.id;
|
|
6262
|
+
if (!messageName) return;
|
|
6263
|
+
const version = message?.data?.version;
|
|
6264
|
+
const label = formatVersionedName(messageName, version);
|
|
6265
|
+
suggestions2.push({
|
|
6266
|
+
key: `${node.id}:${message?.data?.id || messageName}:${version || index}`,
|
|
6267
|
+
node,
|
|
6268
|
+
label,
|
|
6269
|
+
searchText: `${label} ${groupName}`,
|
|
6270
|
+
type: message?.collection || "message",
|
|
6271
|
+
resourceKey: getResourceKey({
|
|
6272
|
+
type: message?.collection || "message",
|
|
6273
|
+
id: message?.data?.id,
|
|
6274
|
+
name: messageName,
|
|
6275
|
+
version
|
|
6276
|
+
}),
|
|
6277
|
+
groupName,
|
|
6278
|
+
isGroupedMessage: true
|
|
6279
|
+
});
|
|
6280
|
+
});
|
|
6281
|
+
return suggestions2;
|
|
6282
|
+
});
|
|
6283
|
+
return dedupeSearchSuggestions(suggestions);
|
|
6284
|
+
},
|
|
6285
|
+
[dedupeSearchSuggestions, getNodeDisplayName, getNodeResourceKey]
|
|
6286
|
+
);
|
|
6287
|
+
const getNodeTypeMeta = (0, import_react61.useCallback)((nodeType) => {
|
|
6288
|
+
const meta = {
|
|
6289
|
+
events: {
|
|
6290
|
+
label: "Event",
|
|
6291
|
+
Icon: import_lucide_react25.Zap,
|
|
6292
|
+
iconClass: "border-orange-500/25 bg-orange-500/10 text-orange-500",
|
|
6293
|
+
badgeClass: "border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300"
|
|
6294
|
+
},
|
|
6295
|
+
event: {
|
|
6296
|
+
label: "Event",
|
|
6297
|
+
Icon: import_lucide_react25.Zap,
|
|
6298
|
+
iconClass: "border-orange-500/25 bg-orange-500/10 text-orange-500",
|
|
6299
|
+
badgeClass: "border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300"
|
|
6300
|
+
},
|
|
6301
|
+
commands: {
|
|
6302
|
+
label: "Command",
|
|
6303
|
+
Icon: import_lucide_react25.MessageSquare,
|
|
6304
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6305
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6306
|
+
},
|
|
6307
|
+
command: {
|
|
6308
|
+
label: "Command",
|
|
6309
|
+
Icon: import_lucide_react25.MessageSquare,
|
|
6310
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6311
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6312
|
+
},
|
|
6313
|
+
queries: {
|
|
6314
|
+
label: "Query",
|
|
6315
|
+
Icon: import_lucide_react25.Search,
|
|
6316
|
+
iconClass: "border-green-500/25 bg-green-500/10 text-green-500",
|
|
6317
|
+
badgeClass: "border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300"
|
|
6318
|
+
},
|
|
6319
|
+
query: {
|
|
6320
|
+
label: "Query",
|
|
6321
|
+
Icon: import_lucide_react25.Search,
|
|
6322
|
+
iconClass: "border-green-500/25 bg-green-500/10 text-green-500",
|
|
6323
|
+
badgeClass: "border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300"
|
|
6324
|
+
},
|
|
6325
|
+
services: {
|
|
6326
|
+
label: "Service",
|
|
6327
|
+
Icon: import_lucide_react25.Server,
|
|
6328
|
+
iconClass: "border-pink-500/25 bg-pink-500/10 text-pink-500",
|
|
6329
|
+
badgeClass: "border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300"
|
|
6330
|
+
},
|
|
6331
|
+
domains: {
|
|
6332
|
+
label: "Domain",
|
|
6333
|
+
Icon: import_lucide_react25.Blocks,
|
|
6334
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6335
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6336
|
+
},
|
|
6337
|
+
flows: {
|
|
6338
|
+
label: "Flow",
|
|
6339
|
+
Icon: import_lucide_react25.Workflow,
|
|
6340
|
+
iconClass: "border-teal-500/25 bg-teal-500/10 text-teal-500",
|
|
6341
|
+
badgeClass: "border-teal-500/25 bg-teal-500/10 text-teal-700 dark:text-teal-300"
|
|
6342
|
+
},
|
|
6343
|
+
channels: {
|
|
6344
|
+
label: "Channel",
|
|
6345
|
+
Icon: import_lucide_react25.ListTree,
|
|
6346
|
+
iconClass: "border-gray-500/25 bg-gray-500/10 text-gray-500",
|
|
6347
|
+
badgeClass: "border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300"
|
|
6348
|
+
},
|
|
6349
|
+
data: {
|
|
6350
|
+
label: "Data",
|
|
6351
|
+
Icon: import_lucide_react25.Database,
|
|
6352
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6353
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6354
|
+
},
|
|
6355
|
+
entities: {
|
|
6356
|
+
label: "Entity",
|
|
6357
|
+
Icon: import_lucide_react25.Database,
|
|
6358
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6359
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6360
|
+
},
|
|
6361
|
+
externalSystem: {
|
|
6362
|
+
label: "External",
|
|
6363
|
+
Icon: import_lucide_react25.Server,
|
|
6364
|
+
iconClass: "border-pink-500/25 bg-pink-500/10 text-pink-500",
|
|
6365
|
+
badgeClass: "border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300"
|
|
6366
|
+
},
|
|
6367
|
+
actor: {
|
|
6368
|
+
label: "Actor",
|
|
6369
|
+
Icon: import_lucide_react25.User,
|
|
6370
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6371
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6372
|
+
},
|
|
6373
|
+
user: {
|
|
6374
|
+
label: "User",
|
|
6375
|
+
Icon: import_lucide_react25.User,
|
|
6376
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6377
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6378
|
+
},
|
|
6379
|
+
messageGroup: {
|
|
6380
|
+
label: "Group",
|
|
6381
|
+
Icon: import_lucide_react25.Layers,
|
|
6382
|
+
iconClass: "border-violet-500/25 bg-violet-500/10 text-violet-500",
|
|
6383
|
+
badgeClass: "border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300"
|
|
6384
|
+
},
|
|
6385
|
+
messageGroupExpanded: {
|
|
6386
|
+
label: "Group",
|
|
6387
|
+
Icon: import_lucide_react25.Layers,
|
|
6388
|
+
iconClass: "border-violet-500/25 bg-violet-500/10 text-violet-500",
|
|
6389
|
+
badgeClass: "border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300"
|
|
6390
|
+
}
|
|
6391
|
+
};
|
|
6392
|
+
return meta[nodeType] || {
|
|
6393
|
+
label: nodeType,
|
|
6394
|
+
Icon: import_lucide_react25.Layers,
|
|
6395
|
+
iconClass: "border-gray-500/25 bg-gray-500/10 text-gray-500",
|
|
6396
|
+
badgeClass: "border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300"
|
|
6153
6397
|
};
|
|
6154
|
-
return colorClasses[nodeType] || "bg-gray-100 text-gray-700";
|
|
6155
6398
|
}, []);
|
|
6156
6399
|
const handleSearchChange = (0, import_react61.useCallback)(
|
|
6157
6400
|
(event) => {
|
|
6158
6401
|
const query = event.target.value;
|
|
6159
6402
|
setSearchQuery(query);
|
|
6160
6403
|
if (query.length > 0) {
|
|
6161
|
-
const
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6404
|
+
const search = query.toLowerCase();
|
|
6405
|
+
const filtered = getSearchSuggestions(nodes).filter(
|
|
6406
|
+
(suggestion) => suggestion.searchText.toLowerCase().includes(search)
|
|
6407
|
+
);
|
|
6165
6408
|
setFilteredSuggestions(filtered);
|
|
6166
6409
|
setShowSuggestions(true);
|
|
6167
6410
|
setSelectedSuggestionIndex(-1);
|
|
6168
6411
|
} else {
|
|
6169
|
-
setFilteredSuggestions(nodes);
|
|
6412
|
+
setFilteredSuggestions(getSearchSuggestions(nodes));
|
|
6170
6413
|
setShowSuggestions(true);
|
|
6171
6414
|
setSelectedSuggestionIndex(-1);
|
|
6172
6415
|
}
|
|
6173
6416
|
},
|
|
6174
|
-
[nodes,
|
|
6417
|
+
[nodes, getSearchSuggestions]
|
|
6175
6418
|
);
|
|
6176
6419
|
const handleSearchFocus = (0, import_react61.useCallback)(() => {
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6420
|
+
const suggestions = getSearchSuggestions(nodes);
|
|
6421
|
+
const search = searchQuery.toLowerCase();
|
|
6422
|
+
setFilteredSuggestions(
|
|
6423
|
+
searchQuery.length === 0 ? suggestions : suggestions.filter(
|
|
6424
|
+
(suggestion) => suggestion.searchText.toLowerCase().includes(search)
|
|
6425
|
+
)
|
|
6426
|
+
);
|
|
6180
6427
|
setShowSuggestions(true);
|
|
6181
6428
|
setSelectedSuggestionIndex(-1);
|
|
6182
|
-
}, [nodes, searchQuery]);
|
|
6429
|
+
}, [nodes, searchQuery, getSearchSuggestions]);
|
|
6183
6430
|
const handleSuggestionClick = (0, import_react61.useCallback)(
|
|
6184
|
-
(
|
|
6185
|
-
setSearchQuery(
|
|
6431
|
+
(suggestion) => {
|
|
6432
|
+
setSearchQuery("");
|
|
6433
|
+
setFilteredSuggestions([]);
|
|
6186
6434
|
setShowSuggestions(false);
|
|
6187
|
-
|
|
6435
|
+
setSelectedSuggestionIndex(-1);
|
|
6436
|
+
onNodeSelect(suggestion.node);
|
|
6188
6437
|
},
|
|
6189
|
-
[onNodeSelect
|
|
6438
|
+
[onNodeSelect]
|
|
6190
6439
|
);
|
|
6191
6440
|
const handleSearchKeyDown = (0, import_react61.useCallback)(
|
|
6192
6441
|
(event) => {
|
|
6193
|
-
if (!showSuggestions || filteredSuggestions.length === 0) return;
|
|
6194
6442
|
switch (event.key) {
|
|
6195
6443
|
case "ArrowDown":
|
|
6196
6444
|
event.preventDefault();
|
|
6445
|
+
if (filteredSuggestions.length === 0) return;
|
|
6446
|
+
setShowSuggestions(true);
|
|
6197
6447
|
setSelectedSuggestionIndex(
|
|
6198
6448
|
(prev) => prev < filteredSuggestions.length - 1 ? prev + 1 : 0
|
|
6199
6449
|
);
|
|
6200
6450
|
break;
|
|
6201
6451
|
case "ArrowUp":
|
|
6202
6452
|
event.preventDefault();
|
|
6453
|
+
if (filteredSuggestions.length === 0) return;
|
|
6454
|
+
setShowSuggestions(true);
|
|
6203
6455
|
setSelectedSuggestionIndex(
|
|
6204
6456
|
(prev) => prev > 0 ? prev - 1 : filteredSuggestions.length - 1
|
|
6205
6457
|
);
|
|
6206
6458
|
break;
|
|
6207
6459
|
case "Enter":
|
|
6208
6460
|
event.preventDefault();
|
|
6209
|
-
if (selectedSuggestionIndex >= 0) {
|
|
6461
|
+
if (showSuggestions && selectedSuggestionIndex >= 0 && selectedSuggestionIndex < filteredSuggestions.length) {
|
|
6210
6462
|
handleSuggestionClick(
|
|
6211
6463
|
filteredSuggestions[selectedSuggestionIndex]
|
|
6212
6464
|
);
|
|
@@ -6235,6 +6487,31 @@ var VisualiserSearch = (0, import_react61.memo)(
|
|
|
6235
6487
|
searchInputRef.current.focus();
|
|
6236
6488
|
}
|
|
6237
6489
|
}, [onClear]);
|
|
6490
|
+
(0, import_react61.useEffect)(() => {
|
|
6491
|
+
suggestionItemRefs.current = suggestionItemRefs.current.slice(
|
|
6492
|
+
0,
|
|
6493
|
+
filteredSuggestions.length
|
|
6494
|
+
);
|
|
6495
|
+
}, [filteredSuggestions.length]);
|
|
6496
|
+
(0, import_react61.useEffect)(() => {
|
|
6497
|
+
if (!showSuggestions || selectedSuggestionIndex < 0) return;
|
|
6498
|
+
const list = suggestionsListRef.current;
|
|
6499
|
+
const item = suggestionItemRefs.current[selectedSuggestionIndex];
|
|
6500
|
+
if (!list || !item) return;
|
|
6501
|
+
const itemTop = item.offsetTop;
|
|
6502
|
+
const itemBottom = itemTop + item.offsetHeight;
|
|
6503
|
+
const visibleTop = list.scrollTop;
|
|
6504
|
+
const visibleBottom = visibleTop + list.clientHeight;
|
|
6505
|
+
if (itemTop < visibleTop) {
|
|
6506
|
+
list.scrollTop = itemTop;
|
|
6507
|
+
} else if (itemBottom > visibleBottom) {
|
|
6508
|
+
list.scrollTop = itemBottom - list.clientHeight;
|
|
6509
|
+
}
|
|
6510
|
+
}, [
|
|
6511
|
+
showSuggestions,
|
|
6512
|
+
selectedSuggestionIndex,
|
|
6513
|
+
filteredSuggestions.length
|
|
6514
|
+
]);
|
|
6238
6515
|
(0, import_react61.useEffect)(() => {
|
|
6239
6516
|
const handleClickOutside = (event) => {
|
|
6240
6517
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
@@ -6289,28 +6566,53 @@ var VisualiserSearch = (0, import_react61.memo)(
|
|
|
6289
6566
|
}
|
|
6290
6567
|
)
|
|
6291
6568
|
] }),
|
|
6292
|
-
showSuggestions && filteredSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
"
|
|
6297
|
-
{
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
{
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6569
|
+
showSuggestions && filteredSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6570
|
+
"div",
|
|
6571
|
+
{
|
|
6572
|
+
ref: suggestionsListRef,
|
|
6573
|
+
className: "absolute top-full left-0 right-0 mt-1 bg-[rgb(var(--ec-card-bg))] border border-[rgb(var(--ec-page-border))] rounded-md shadow-lg z-50 max-h-60 overflow-y-auto",
|
|
6574
|
+
children: filteredSuggestions.map((suggestion, index) => {
|
|
6575
|
+
const nodeTypeMeta = getNodeTypeMeta(suggestion.type);
|
|
6576
|
+
const Icon = nodeTypeMeta.Icon;
|
|
6577
|
+
const isSelected = index === selectedSuggestionIndex;
|
|
6578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6579
|
+
"div",
|
|
6580
|
+
{
|
|
6581
|
+
ref: (element) => {
|
|
6582
|
+
suggestionItemRefs.current[index] = element;
|
|
6583
|
+
},
|
|
6584
|
+
onClick: () => handleSuggestionClick(suggestion),
|
|
6585
|
+
onMouseEnter: () => setSelectedSuggestionIndex(index),
|
|
6586
|
+
className: `px-3 py-2 cursor-pointer flex items-start gap-3 ${isSelected ? "bg-[rgb(var(--ec-accent-subtle))] outline outline-1 -outline-offset-1 outline-[rgb(var(--ec-accent))]" : "hover:bg-[rgb(var(--ec-page-border)/0.5)]"}`,
|
|
6587
|
+
children: [
|
|
6588
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6589
|
+
"span",
|
|
6590
|
+
{
|
|
6591
|
+
className: `mt-0.5 flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-md border ${nodeTypeMeta.iconClass}`,
|
|
6592
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { className: "h-3.5 w-3.5" })
|
|
6593
|
+
}
|
|
6594
|
+
),
|
|
6595
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "block truncate text-sm font-medium text-[rgb(var(--ec-page-text))]", children: suggestion.label }),
|
|
6597
|
+
suggestion.isGroupedMessage && suggestion.groupName && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "mt-0.5 block truncate text-xs text-[rgb(var(--ec-page-text-muted))]", children: [
|
|
6598
|
+
"in ",
|
|
6599
|
+
suggestion.groupName
|
|
6600
|
+
] })
|
|
6601
|
+
] }),
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6603
|
+
"span",
|
|
6604
|
+
{
|
|
6605
|
+
className: `mt-0.5 flex-shrink-0 rounded border px-2 py-0.5 text-xs font-medium ${nodeTypeMeta.badgeClass}`,
|
|
6606
|
+
children: nodeTypeMeta.label
|
|
6607
|
+
}
|
|
6608
|
+
)
|
|
6609
|
+
]
|
|
6610
|
+
},
|
|
6611
|
+
`${suggestion.key}:${index}`
|
|
6612
|
+
);
|
|
6613
|
+
})
|
|
6614
|
+
}
|
|
6615
|
+
)
|
|
6314
6616
|
] });
|
|
6315
6617
|
}
|
|
6316
6618
|
)
|
|
@@ -6565,7 +6867,7 @@ var StepWalkthrough_default = (0, import_react62.memo)(function StepWalkthrough(
|
|
|
6565
6867
|
// src/components/StudioModal.tsx
|
|
6566
6868
|
var import_react63 = require("react");
|
|
6567
6869
|
var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
|
|
6568
|
-
var
|
|
6870
|
+
var import_lucide_react26 = require("lucide-react");
|
|
6569
6871
|
var import_react64 = require("@xyflow/react");
|
|
6570
6872
|
|
|
6571
6873
|
// src/utils/export-node-graph.ts
|
|
@@ -6690,10 +6992,10 @@ var StudioModal = ({ isOpen, onClose }) => {
|
|
|
6690
6992
|
onClick: handleCopyToClipboard,
|
|
6691
6993
|
className: `w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md border transition-colors ${copySuccess ? "bg-green-50 border-green-200 text-green-700" : "bg-white border-gray-300 text-gray-700 hover:bg-gray-50"}`,
|
|
6692
6994
|
children: copySuccess ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
6693
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6995
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react26.CheckIcon, { className: "w-4 h-4" }),
|
|
6694
6996
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Copied!" })
|
|
6695
6997
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
6696
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6998
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react26.ClipboardIcon, { className: "w-4 h-4" }),
|
|
6697
6999
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Copy diagram to clipboard" })
|
|
6698
7000
|
] })
|
|
6699
7001
|
}
|
|
@@ -6708,7 +7010,7 @@ var StudioModal = ({ isOpen, onClose }) => {
|
|
|
6708
7010
|
onClick: handleOpenStudio,
|
|
6709
7011
|
className: "w-full flex items-center justify-center space-x-2 px-4 py-2 bg-[rgb(var(--ec-accent))] text-white text-sm font-medium rounded-md hover:bg-[rgb(var(--ec-accent-hover))] transition-colors",
|
|
6710
7012
|
children: [
|
|
6711
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7013
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react26.ExternalLinkIcon, { className: "w-4 h-4" }),
|
|
6712
7014
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Open EventCatalog Studio" })
|
|
6713
7015
|
]
|
|
6714
7016
|
}
|
|
@@ -6733,7 +7035,7 @@ var StudioModal_default = StudioModal;
|
|
|
6733
7035
|
// src/components/FocusModeModal.tsx
|
|
6734
7036
|
var import_react69 = require("react");
|
|
6735
7037
|
var Dialog3 = __toESM(require("@radix-ui/react-dialog"));
|
|
6736
|
-
var
|
|
7038
|
+
var import_lucide_react28 = require("lucide-react");
|
|
6737
7039
|
var import_react70 = require("@xyflow/react");
|
|
6738
7040
|
|
|
6739
7041
|
// src/components/FocusMode/FocusModeContent.tsx
|
|
@@ -6847,7 +7149,7 @@ function getNodeDocUrl(node) {
|
|
|
6847
7149
|
|
|
6848
7150
|
// src/components/FocusMode/FocusModeNodeActions.tsx
|
|
6849
7151
|
var import_react65 = require("@xyflow/react");
|
|
6850
|
-
var
|
|
7152
|
+
var import_lucide_react27 = require("lucide-react");
|
|
6851
7153
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
6852
7154
|
var FocusModeNodeActions = ({
|
|
6853
7155
|
node,
|
|
@@ -6894,7 +7196,7 @@ var FocusModeNodeActions = ({
|
|
|
6894
7196
|
className: "flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors",
|
|
6895
7197
|
style: { width: buttonSize, height: buttonSize },
|
|
6896
7198
|
title: "View documentation",
|
|
6897
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7199
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react27.FileText, { style: { width: iconSize, height: iconSize } })
|
|
6898
7200
|
}
|
|
6899
7201
|
)
|
|
6900
7202
|
}
|
|
@@ -6922,7 +7224,7 @@ var FocusModeNodeActions = ({
|
|
|
6922
7224
|
className: "flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors",
|
|
6923
7225
|
style: { width: buttonSize, height: buttonSize },
|
|
6924
7226
|
title: "View documentation",
|
|
6925
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7227
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react27.FileText, { style: { width: iconSize, height: iconSize } })
|
|
6926
7228
|
}
|
|
6927
7229
|
),
|
|
6928
7230
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
@@ -6932,7 +7234,7 @@ var FocusModeNodeActions = ({
|
|
|
6932
7234
|
className: "flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors",
|
|
6933
7235
|
style: { width: buttonSize, height: buttonSize },
|
|
6934
7236
|
title: "Focus on this node",
|
|
6935
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7237
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react27.ArrowRightLeft, { style: { width: iconSize, height: iconSize } })
|
|
6936
7238
|
}
|
|
6937
7239
|
)
|
|
6938
7240
|
]
|
|
@@ -7331,7 +7633,7 @@ var FocusModeModal = ({
|
|
|
7331
7633
|
background: isDark ? "rgba(59, 130, 246, 0.18)" : "rgba(59, 130, 246, 0.12)"
|
|
7332
7634
|
},
|
|
7333
7635
|
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7334
|
-
|
|
7636
|
+
import_lucide_react28.FocusIcon,
|
|
7335
7637
|
{
|
|
7336
7638
|
style: {
|
|
7337
7639
|
width: 20,
|
|
@@ -7383,7 +7685,7 @@ var FocusModeModal = ({
|
|
|
7383
7685
|
color: isDark ? "#94a3b8" : "#64748b"
|
|
7384
7686
|
},
|
|
7385
7687
|
"aria-label": "Close",
|
|
7386
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7688
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react28.XIcon, { style: { width: 20, height: 20 } })
|
|
7387
7689
|
}
|
|
7388
7690
|
) })
|
|
7389
7691
|
]
|
|
@@ -7411,7 +7713,7 @@ var FocusModeModal_default = FocusModeModal;
|
|
|
7411
7713
|
|
|
7412
7714
|
// src/components/MermaidView.tsx
|
|
7413
7715
|
var import_react71 = require("react");
|
|
7414
|
-
var
|
|
7716
|
+
var import_lucide_react29 = require("lucide-react");
|
|
7415
7717
|
|
|
7416
7718
|
// src/utils/export-mermaid.ts
|
|
7417
7719
|
var NODE_SHAPE_MAP = {
|
|
@@ -7805,7 +8107,7 @@ var MermaidView = ({
|
|
|
7805
8107
|
onClick: handleCopyToClipboard,
|
|
7806
8108
|
className: `p-2.5 rounded-md shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[rgb(var(--ec-accent))] transition-all duration-150 ${copySuccess ? "bg-green-500 text-white scale-110" : "bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-page-border))/0.5] text-[rgb(var(--ec-icon-color))] hover:scale-105"}`,
|
|
7807
8109
|
"aria-label": copySuccess ? "Copied!" : "Copy Mermaid code",
|
|
7808
|
-
children: copySuccess ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8110
|
+
children: copySuccess ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react29.CheckIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react29.ClipboardIcon, { className: "h-5 w-5" })
|
|
7809
8111
|
}
|
|
7810
8112
|
),
|
|
7811
8113
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "absolute top-full right-0 mt-2 px-2 py-1 bg-[rgb(var(--ec-page-text))] text-[rgb(var(--ec-page-bg))] text-xs rounded shadow-lg opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50", children: copySuccess ? "Copied!" : "Copy Mermaid code" })
|
|
@@ -8111,7 +8413,7 @@ var useChannelVisibility = ({
|
|
|
8111
8413
|
// src/components/VisualizerDropdownContent.tsx
|
|
8112
8414
|
var import_react74 = require("react");
|
|
8113
8415
|
var DropdownMenu = __toESM(require("@radix-ui/react-dropdown-menu"));
|
|
8114
|
-
var
|
|
8416
|
+
var import_lucide_react30 = require("lucide-react");
|
|
8115
8417
|
var import_outline2 = require("@heroicons/react/24/outline");
|
|
8116
8418
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8117
8419
|
var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
@@ -8166,7 +8468,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8166
8468
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
8167
8469
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(DropdownMenu.Sub, { children: [
|
|
8168
8470
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(DropdownMenu.SubTrigger, { className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2 outline-none", children: [
|
|
8169
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8471
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Grid3x3, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8170
8472
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Canvas" }),
|
|
8171
8473
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8172
8474
|
"svg",
|
|
@@ -8201,7 +8503,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8201
8503
|
onCheckedChange: setIsMermaidView,
|
|
8202
8504
|
className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2",
|
|
8203
8505
|
children: [
|
|
8204
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8506
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Code, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8205
8507
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Render as mermaid" }),
|
|
8206
8508
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8207
8509
|
"div",
|
|
@@ -8226,7 +8528,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8226
8528
|
onCheckedChange: toggleAnimateMessages,
|
|
8227
8529
|
className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2",
|
|
8228
8530
|
children: [
|
|
8229
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8531
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Zap, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8230
8532
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Simulate Messages" }),
|
|
8231
8533
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8232
8534
|
"div",
|
|
@@ -8250,7 +8552,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8250
8552
|
onCheckedChange: toggleChannelsVisibility,
|
|
8251
8553
|
className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2",
|
|
8252
8554
|
children: [
|
|
8253
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8555
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.EyeOff, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8254
8556
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Hide channels" }),
|
|
8255
8557
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8256
8558
|
"div",
|
|
@@ -8274,7 +8576,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8274
8576
|
onCheckedChange: setShowMinimap,
|
|
8275
8577
|
className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2",
|
|
8276
8578
|
children: [
|
|
8277
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8579
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Map, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8278
8580
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Show minimap" }),
|
|
8279
8581
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8280
8582
|
"div",
|
|
@@ -8298,7 +8600,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8298
8600
|
onClick: handleFitView,
|
|
8299
8601
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8300
8602
|
children: [
|
|
8301
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8603
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Maximize2, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8302
8604
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Fit to view" })
|
|
8303
8605
|
]
|
|
8304
8606
|
}
|
|
@@ -8317,7 +8619,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8317
8619
|
},
|
|
8318
8620
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8319
8621
|
children: [
|
|
8320
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8622
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Search, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8321
8623
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Find on canvas" })
|
|
8322
8624
|
]
|
|
8323
8625
|
}
|
|
@@ -8332,7 +8634,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8332
8634
|
onClick: onOpenNotes,
|
|
8333
8635
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8334
8636
|
children: [
|
|
8335
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8637
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.MessageCircle, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8336
8638
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "flex-1 font-normal", children: [
|
|
8337
8639
|
"View notes (",
|
|
8338
8640
|
notesCount,
|
|
@@ -8343,7 +8645,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8343
8645
|
),
|
|
8344
8646
|
isDevMode && onSaveLayout && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(DropdownMenu.Sub, { children: [
|
|
8345
8647
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(DropdownMenu.SubTrigger, { className: "flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2 outline-none", children: [
|
|
8346
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8648
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Save, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8347
8649
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Layout" }),
|
|
8348
8650
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[10px] text-amber-600 font-medium", children: "DEV" }),
|
|
8349
8651
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
@@ -8379,7 +8681,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8379
8681
|
disabled: layoutStatus !== "idle",
|
|
8380
8682
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
8381
8683
|
children: [
|
|
8382
|
-
layoutStatus === "saving" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8684
|
+
layoutStatus === "saving" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Loader2, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Save, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8383
8685
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: layoutStatus === "saving" ? "Saving..." : "Save Layout" })
|
|
8384
8686
|
]
|
|
8385
8687
|
}
|
|
@@ -8391,7 +8693,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8391
8693
|
disabled: layoutStatus !== "idle",
|
|
8392
8694
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
8393
8695
|
children: [
|
|
8394
|
-
layoutStatus === "resetting" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8696
|
+
layoutStatus === "resetting" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Loader2, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.RotateCcw, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8395
8697
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: layoutStatus === "resetting" ? "Resetting..." : "Reset Layout" })
|
|
8396
8698
|
]
|
|
8397
8699
|
}
|
|
@@ -8408,7 +8710,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8408
8710
|
onClick: openChat,
|
|
8409
8711
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8410
8712
|
children: [
|
|
8411
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8713
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Sparkles, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8412
8714
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Ask a question" })
|
|
8413
8715
|
]
|
|
8414
8716
|
}
|
|
@@ -8421,7 +8723,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8421
8723
|
onClick: handleCopyArchitectureCode,
|
|
8422
8724
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8423
8725
|
children: [
|
|
8424
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8726
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Code, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8425
8727
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Copy as mermaid" })
|
|
8426
8728
|
]
|
|
8427
8729
|
}
|
|
@@ -8443,7 +8745,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8443
8745
|
onClick: () => setIsShareModalOpen(true),
|
|
8444
8746
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8445
8747
|
children: [
|
|
8446
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8748
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.Share2, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8447
8749
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Share Link" })
|
|
8448
8750
|
]
|
|
8449
8751
|
}
|
|
@@ -8467,7 +8769,7 @@ var VisualizerDropdownContent = (0, import_react74.memo)(
|
|
|
8467
8769
|
onClick: openStudioModal,
|
|
8468
8770
|
className: "px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors",
|
|
8469
8771
|
children: [
|
|
8470
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8772
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react30.ExternalLink, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8471
8773
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex-1 font-normal", children: "Open in EventCatalog Studio" })
|
|
8472
8774
|
]
|
|
8473
8775
|
}
|
|
@@ -9010,30 +9312,144 @@ function flatLayout(nodes, edges, graphOpts, nodeSize, style) {
|
|
|
9010
9312
|
return { nodes: layoutNodes, edges: layoutEdges };
|
|
9011
9313
|
}
|
|
9012
9314
|
|
|
9315
|
+
// src/utils/local-packing.ts
|
|
9316
|
+
var toNumber = (value) => {
|
|
9317
|
+
if (typeof value === "number") return value;
|
|
9318
|
+
if (typeof value === "string") {
|
|
9319
|
+
const parsed = Number.parseFloat(value);
|
|
9320
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
9321
|
+
}
|
|
9322
|
+
return void 0;
|
|
9323
|
+
};
|
|
9324
|
+
var getPackableNodeSize = (node) => ({
|
|
9325
|
+
width: toNumber(node.measured?.width) ?? toNumber(node.width) ?? toNumber(node.style?.width) ?? 260,
|
|
9326
|
+
height: toNumber(node.measured?.height) ?? toNumber(node.height) ?? toNumber(node.style?.height) ?? 140
|
|
9327
|
+
});
|
|
9328
|
+
var rectsIntersect = (a, b, gap = 0) => a.x < b.x + b.width + gap && a.x + a.width + gap > b.x && a.y < b.y + b.height + gap && a.y + a.height + gap > b.y;
|
|
9329
|
+
var toRect = (node, y = node.position.y) => {
|
|
9330
|
+
const size = getPackableNodeSize(node);
|
|
9331
|
+
return {
|
|
9332
|
+
x: node.position.x,
|
|
9333
|
+
y,
|
|
9334
|
+
width: size.width,
|
|
9335
|
+
height: size.height
|
|
9336
|
+
};
|
|
9337
|
+
};
|
|
9338
|
+
var packNodesAroundBounds = ({
|
|
9339
|
+
nodes,
|
|
9340
|
+
movableNodeIds,
|
|
9341
|
+
protectedBounds,
|
|
9342
|
+
groupNodeId,
|
|
9343
|
+
gap = 40
|
|
9344
|
+
}) => {
|
|
9345
|
+
const movableNodes = nodes.filter((node) => movableNodeIds.has(node.id)).sort((a, b) => a.position.y - b.position.y);
|
|
9346
|
+
const movableIds = new Set(movableNodes.map((node) => node.id));
|
|
9347
|
+
const occupiedRects = [
|
|
9348
|
+
protectedBounds,
|
|
9349
|
+
...nodes.filter(
|
|
9350
|
+
(node) => !node.parentId && node.id !== groupNodeId && !movableIds.has(node.id)
|
|
9351
|
+
).map((node) => toRect(node))
|
|
9352
|
+
];
|
|
9353
|
+
const plannedPositions = /* @__PURE__ */ new Map();
|
|
9354
|
+
const groupCenterY = protectedBounds.y + protectedBounds.height / 2;
|
|
9355
|
+
const placeNode = (node) => {
|
|
9356
|
+
const size = getPackableNodeSize(node);
|
|
9357
|
+
const nodeCenterY = node.position.y + size.height / 2;
|
|
9358
|
+
const moveDirection = nodeCenterY >= groupCenterY ? 1 : -1;
|
|
9359
|
+
let y = moveDirection > 0 ? Math.max(
|
|
9360
|
+
node.position.y,
|
|
9361
|
+
protectedBounds.y + protectedBounds.height + gap
|
|
9362
|
+
) : Math.min(node.position.y, protectedBounds.y - size.height - gap);
|
|
9363
|
+
let attempts = 0;
|
|
9364
|
+
while (attempts < occupiedRects.length + 8) {
|
|
9365
|
+
const rect = {
|
|
9366
|
+
x: node.position.x,
|
|
9367
|
+
y,
|
|
9368
|
+
width: size.width,
|
|
9369
|
+
height: size.height
|
|
9370
|
+
};
|
|
9371
|
+
const collision = occupiedRects.find(
|
|
9372
|
+
(occupied) => rectsIntersect(rect, occupied, gap)
|
|
9373
|
+
);
|
|
9374
|
+
if (!collision) {
|
|
9375
|
+
occupiedRects.push(rect);
|
|
9376
|
+
plannedPositions.set(node.id, { ...node.position, y });
|
|
9377
|
+
return;
|
|
9378
|
+
}
|
|
9379
|
+
y = moveDirection > 0 ? collision.y + collision.height + gap : collision.y - size.height - gap;
|
|
9380
|
+
attempts += 1;
|
|
9381
|
+
}
|
|
9382
|
+
occupiedRects.push({
|
|
9383
|
+
x: node.position.x,
|
|
9384
|
+
y,
|
|
9385
|
+
width: size.width,
|
|
9386
|
+
height: size.height
|
|
9387
|
+
});
|
|
9388
|
+
plannedPositions.set(node.id, { ...node.position, y });
|
|
9389
|
+
};
|
|
9390
|
+
const below = movableNodes.filter((node) => {
|
|
9391
|
+
const size = getPackableNodeSize(node);
|
|
9392
|
+
return node.position.y + size.height / 2 >= groupCenterY;
|
|
9393
|
+
});
|
|
9394
|
+
const belowIds = new Set(below.map((node) => node.id));
|
|
9395
|
+
const above = movableNodes.filter((node) => !belowIds.has(node.id)).reverse();
|
|
9396
|
+
below.forEach(placeNode);
|
|
9397
|
+
above.forEach(placeNode);
|
|
9398
|
+
return plannedPositions;
|
|
9399
|
+
};
|
|
9400
|
+
|
|
9401
|
+
// src/utils/message-group-expansion.ts
|
|
9402
|
+
var getExpandedMessageGroupNode = (nodes, groupNodeId) => nodes.find(
|
|
9403
|
+
(node) => node.id === groupNodeId && node.type === "messageGroupExpanded"
|
|
9404
|
+
);
|
|
9405
|
+
var buildMessageGroupExpansionNodes = ({
|
|
9406
|
+
currentNodes,
|
|
9407
|
+
groupNodeId,
|
|
9408
|
+
expandedContainerNode,
|
|
9409
|
+
childNodes,
|
|
9410
|
+
downstreamNodes,
|
|
9411
|
+
getDownstreamPosition
|
|
9412
|
+
}) => {
|
|
9413
|
+
const withoutExistingGroup = currentNodes.filter(
|
|
9414
|
+
(node) => node.id !== groupNodeId && node.parentId !== groupNodeId
|
|
9415
|
+
);
|
|
9416
|
+
const existingIds = new Set(withoutExistingGroup.map((node) => node.id));
|
|
9417
|
+
const newDownstream = downstreamNodes.filter((node) => !existingIds.has(node.id)).map((node, index) => ({
|
|
9418
|
+
...node,
|
|
9419
|
+
position: getDownstreamPosition(node, index)
|
|
9420
|
+
}));
|
|
9421
|
+
return [
|
|
9422
|
+
...withoutExistingGroup,
|
|
9423
|
+
expandedContainerNode,
|
|
9424
|
+
...childNodes,
|
|
9425
|
+
...newDownstream
|
|
9426
|
+
];
|
|
9427
|
+
};
|
|
9428
|
+
|
|
9013
9429
|
// src/components/NotesToolbarButton.tsx
|
|
9014
9430
|
var import_react77 = require("react");
|
|
9015
|
-
var
|
|
9431
|
+
var import_lucide_react31 = require("lucide-react");
|
|
9016
9432
|
var import_react78 = require("@xyflow/react");
|
|
9017
9433
|
var Dialog4 = __toESM(require("@radix-ui/react-dialog"));
|
|
9018
9434
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
9019
9435
|
var NODE_TYPE_META = {
|
|
9020
|
-
service: { icon:
|
|
9021
|
-
services: { icon:
|
|
9022
|
-
event: { icon:
|
|
9023
|
-
events: { icon:
|
|
9024
|
-
command: { icon:
|
|
9025
|
-
commands: { icon:
|
|
9026
|
-
query: { icon:
|
|
9027
|
-
queries: { icon:
|
|
9028
|
-
channel: { icon:
|
|
9029
|
-
channels: { icon:
|
|
9030
|
-
data: { icon:
|
|
9031
|
-
"data-products": { icon:
|
|
9032
|
-
externalSystem: { icon:
|
|
9033
|
-
actor: { icon:
|
|
9034
|
-
view: { icon:
|
|
9035
|
-
domain: { icon:
|
|
9036
|
-
domains: { icon:
|
|
9436
|
+
service: { icon: import_lucide_react31.ServerIcon, color: "#ec4899", label: "Service" },
|
|
9437
|
+
services: { icon: import_lucide_react31.ServerIcon, color: "#ec4899", label: "Service" },
|
|
9438
|
+
event: { icon: import_lucide_react31.Zap, color: "#f97316", label: "Event" },
|
|
9439
|
+
events: { icon: import_lucide_react31.Zap, color: "#f97316", label: "Event" },
|
|
9440
|
+
command: { icon: import_lucide_react31.MessageSquare, color: "#3b82f6", label: "Command" },
|
|
9441
|
+
commands: { icon: import_lucide_react31.MessageSquare, color: "#3b82f6", label: "Command" },
|
|
9442
|
+
query: { icon: import_lucide_react31.Search, color: "#22c55e", label: "Query" },
|
|
9443
|
+
queries: { icon: import_lucide_react31.Search, color: "#22c55e", label: "Query" },
|
|
9444
|
+
channel: { icon: import_lucide_react31.ArrowRightLeft, color: "#6b7280", label: "Channel" },
|
|
9445
|
+
channels: { icon: import_lucide_react31.ArrowRightLeft, color: "#6b7280", label: "Channel" },
|
|
9446
|
+
data: { icon: import_lucide_react31.Database, color: "#3b82f6", label: "Data" },
|
|
9447
|
+
"data-products": { icon: import_lucide_react31.Package, color: "#6366f1", label: "Data Product" },
|
|
9448
|
+
externalSystem: { icon: import_lucide_react31.Globe, color: "#ec4899", label: "External System" },
|
|
9449
|
+
actor: { icon: import_lucide_react31.User, color: "#eab308", label: "Actor" },
|
|
9450
|
+
view: { icon: import_lucide_react31.MonitorIcon, color: "#8b5cf6", label: "View" },
|
|
9451
|
+
domain: { icon: import_lucide_react31.BoxesIcon, color: "#14b8a6", label: "Domain" },
|
|
9452
|
+
domains: { icon: import_lucide_react31.BoxesIcon, color: "#14b8a6", label: "Domain" }
|
|
9037
9453
|
};
|
|
9038
9454
|
function getNodeMeta(nodeType) {
|
|
9039
9455
|
if (!nodeType) return null;
|
|
@@ -9172,7 +9588,7 @@ function PriorityBadge({ priority }) {
|
|
|
9172
9588
|
lineHeight: 1.4
|
|
9173
9589
|
},
|
|
9174
9590
|
children: [
|
|
9175
|
-
isUrgent && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9591
|
+
isUrgent && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react31.AlertTriangle, { style: { width: 9, height: 9 }, strokeWidth: 2.5 }),
|
|
9176
9592
|
p.label
|
|
9177
9593
|
]
|
|
9178
9594
|
}
|
|
@@ -9367,7 +9783,7 @@ function AllNotesModal({
|
|
|
9367
9783
|
flexShrink: 0
|
|
9368
9784
|
},
|
|
9369
9785
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9370
|
-
|
|
9786
|
+
import_lucide_react31.MessageCircle,
|
|
9371
9787
|
{
|
|
9372
9788
|
style: { width: 16, height: 16, color: "#64748b" },
|
|
9373
9789
|
strokeWidth: 2.5
|
|
@@ -9428,7 +9844,7 @@ function AllNotesModal({
|
|
|
9428
9844
|
flexShrink: 0
|
|
9429
9845
|
},
|
|
9430
9846
|
"aria-label": "Close",
|
|
9431
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9847
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react31.X, { style: { width: 15, height: 15 } })
|
|
9432
9848
|
}
|
|
9433
9849
|
) })
|
|
9434
9850
|
]
|
|
@@ -9448,7 +9864,7 @@ function AllNotesModal({
|
|
|
9448
9864
|
children: noteGroups.map((group, i) => {
|
|
9449
9865
|
const isActive = i === selectedIdx;
|
|
9450
9866
|
const meta = getNodeMeta(group.nodeType);
|
|
9451
|
-
const IconComp = meta?.icon ||
|
|
9867
|
+
const IconComp = meta?.icon || import_lucide_react31.MessageCircle;
|
|
9452
9868
|
const iconColor = meta?.color || "#64748b";
|
|
9453
9869
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
9454
9870
|
"button",
|
|
@@ -9537,7 +9953,7 @@ function AllNotesModal({
|
|
|
9537
9953
|
)
|
|
9538
9954
|
] }),
|
|
9539
9955
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9540
|
-
|
|
9956
|
+
import_lucide_react31.ChevronRight,
|
|
9541
9957
|
{
|
|
9542
9958
|
style: {
|
|
9543
9959
|
width: 14,
|
|
@@ -9589,7 +10005,7 @@ function AllNotesModal({
|
|
|
9589
10005
|
children: [
|
|
9590
10006
|
(() => {
|
|
9591
10007
|
const meta = getNodeMeta(selected.nodeType);
|
|
9592
|
-
const Icon = meta?.icon ||
|
|
10008
|
+
const Icon = meta?.icon || import_lucide_react31.MessageCircle;
|
|
9593
10009
|
const color = meta?.color || "#64748b";
|
|
9594
10010
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9595
10011
|
"div",
|
|
@@ -9680,7 +10096,7 @@ function AllNotesModal({
|
|
|
9680
10096
|
e.currentTarget.style.color = "#475569";
|
|
9681
10097
|
},
|
|
9682
10098
|
children: [
|
|
9683
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
10099
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react31.Locate, { style: { width: 12, height: 12 } }),
|
|
9684
10100
|
"Find on canvas"
|
|
9685
10101
|
]
|
|
9686
10102
|
}
|
|
@@ -9932,7 +10348,7 @@ var NodeGraphBuilder = ({
|
|
|
9932
10348
|
);
|
|
9933
10349
|
const [nodes, setNodes, onNodesChange] = (0, import_react80.useNodesState)(initialNodes);
|
|
9934
10350
|
const [edges, setEdges, onEdgesChange] = (0, import_react80.useEdgesState)(initialEdges);
|
|
9935
|
-
const { fitView, getNodes } = (0, import_react80.useReactFlow)();
|
|
10351
|
+
const { fitView, getNodes, getIntersectingNodes, getZoom, setCenter } = (0, import_react80.useReactFlow)();
|
|
9936
10352
|
(0, import_react79.useEffect)(() => {
|
|
9937
10353
|
setNodes(initialNodes);
|
|
9938
10354
|
setEdges(initialEdges);
|
|
@@ -10072,57 +10488,107 @@ var NodeGraphBuilder = ({
|
|
|
10072
10488
|
wrapper.classList.add("ec-animating-layout");
|
|
10073
10489
|
setTimeout(() => wrapper.classList.remove("ec-animating-layout"), 400);
|
|
10074
10490
|
}, []);
|
|
10075
|
-
const relayoutGraph = (0, import_react79.useCallback)(
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
g.
|
|
10098
|
-
|
|
10099
|
-
});
|
|
10100
|
-
import_dagre3.default.layout(g);
|
|
10101
|
-
const positioned = nextNodes.map((node) => {
|
|
10102
|
-
if (node.parentId) {
|
|
10103
|
-
const parent = nextNodes.find((n) => n.id === node.parentId);
|
|
10104
|
-
if (parent?.type === "flowExpanded") {
|
|
10105
|
-
return node;
|
|
10491
|
+
const relayoutGraph = (0, import_react79.useCallback)(
|
|
10492
|
+
(nextNodes, nextEdges, anchor) => {
|
|
10493
|
+
const g = new import_dagre3.default.graphlib.Graph({ compound: true });
|
|
10494
|
+
g.setGraph({ rankdir: "LR", ranksep: 300, nodesep: 50 });
|
|
10495
|
+
g.setDefaultEdgeLabel(() => ({}));
|
|
10496
|
+
nextNodes.forEach((node) => {
|
|
10497
|
+
if (node.parentId) return;
|
|
10498
|
+
const w = node.style?.width || (node.type === "messageGroupExpanded" ? 380 : 150);
|
|
10499
|
+
const h = node.style?.height || (node.type === "messageGroupExpanded" ? 0 : 120);
|
|
10500
|
+
if (node.type === "messageGroupExpanded") {
|
|
10501
|
+
const children = nextNodes.filter((n) => n.parentId === node.id);
|
|
10502
|
+
const childHeight = children.length * 190 + 100;
|
|
10503
|
+
g.setNode(node.id, { width: w, height: childHeight });
|
|
10504
|
+
} else {
|
|
10505
|
+
g.setNode(node.id, { width: w, height: h });
|
|
10506
|
+
}
|
|
10507
|
+
});
|
|
10508
|
+
nextEdges.forEach((edge) => {
|
|
10509
|
+
const sourceNode = nextNodes.find((n) => n.id === edge.source);
|
|
10510
|
+
const targetNode = nextNodes.find((n) => n.id === edge.target);
|
|
10511
|
+
const sourceTop = sourceNode?.parentId || edge.source;
|
|
10512
|
+
const targetTop = targetNode?.parentId || edge.target;
|
|
10513
|
+
if (g.hasNode(sourceTop) && g.hasNode(targetTop) && sourceTop !== targetTop) {
|
|
10514
|
+
g.setEdge(sourceTop, targetTop);
|
|
10106
10515
|
}
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10516
|
+
});
|
|
10517
|
+
import_dagre3.default.layout(g);
|
|
10518
|
+
const positioned = nextNodes.map((node) => {
|
|
10519
|
+
if (node.parentId) {
|
|
10520
|
+
const parent = nextNodes.find((n) => n.id === node.parentId);
|
|
10521
|
+
if (parent?.type === "flowExpanded") {
|
|
10522
|
+
return node;
|
|
10523
|
+
}
|
|
10524
|
+
const parentWidth = parent?.style?.width || 380;
|
|
10525
|
+
const childWidth = 240;
|
|
10526
|
+
const xOffset = Math.max(20, (parentWidth - childWidth) / 2);
|
|
10527
|
+
const siblings = nextNodes.filter(
|
|
10528
|
+
(n) => n.parentId === node.parentId
|
|
10529
|
+
);
|
|
10530
|
+
const index = siblings.indexOf(node);
|
|
10531
|
+
return {
|
|
10532
|
+
...node,
|
|
10533
|
+
position: { x: xOffset, y: 70 + index * 190 }
|
|
10534
|
+
};
|
|
10535
|
+
}
|
|
10536
|
+
const pos = g.node(node.id);
|
|
10537
|
+
if (!pos) return node;
|
|
10112
10538
|
return {
|
|
10113
10539
|
...node,
|
|
10114
|
-
position: { x:
|
|
10540
|
+
position: { x: pos.x - pos.width / 2, y: pos.y - pos.height / 2 }
|
|
10115
10541
|
};
|
|
10116
|
-
}
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
return
|
|
10120
|
-
|
|
10121
|
-
|
|
10542
|
+
});
|
|
10543
|
+
if (!anchor) return positioned;
|
|
10544
|
+
const positionedAnchor = positioned.find((node) => node.id === anchor.id);
|
|
10545
|
+
if (!positionedAnchor) return positioned;
|
|
10546
|
+
const offset = {
|
|
10547
|
+
x: anchor.position.x - positionedAnchor.position.x,
|
|
10548
|
+
y: anchor.position.y - positionedAnchor.position.y
|
|
10122
10549
|
};
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10550
|
+
return positioned.map((node) => {
|
|
10551
|
+
if (node.parentId) return node;
|
|
10552
|
+
return {
|
|
10553
|
+
...node,
|
|
10554
|
+
position: {
|
|
10555
|
+
x: node.position.x + offset.x,
|
|
10556
|
+
y: node.position.y + offset.y
|
|
10557
|
+
}
|
|
10558
|
+
};
|
|
10559
|
+
});
|
|
10560
|
+
},
|
|
10561
|
+
[]
|
|
10562
|
+
);
|
|
10563
|
+
const makeRoomForRenderedExpandedGroup = (0, import_react79.useCallback)(
|
|
10564
|
+
(groupNodeId, groupBounds) => {
|
|
10565
|
+
const padding = 80;
|
|
10566
|
+
const protectedBounds = {
|
|
10567
|
+
x: groupBounds.x - padding,
|
|
10568
|
+
y: groupBounds.y - padding,
|
|
10569
|
+
width: groupBounds.width + padding * 2,
|
|
10570
|
+
height: groupBounds.height + padding * 2
|
|
10571
|
+
};
|
|
10572
|
+
const intersectingIds = new Set(
|
|
10573
|
+
getIntersectingNodes(protectedBounds, true).filter((node) => node.id !== groupNodeId && !node.parentId).map((node) => node.id)
|
|
10574
|
+
);
|
|
10575
|
+
if (intersectingIds.size === 0) return;
|
|
10576
|
+
setNodes((currentNodes) => {
|
|
10577
|
+
const plannedPositions = packNodesAroundBounds({
|
|
10578
|
+
nodes: currentNodes,
|
|
10579
|
+
movableNodeIds: intersectingIds,
|
|
10580
|
+
protectedBounds,
|
|
10581
|
+
groupNodeId
|
|
10582
|
+
});
|
|
10583
|
+
return currentNodes.map((node) => {
|
|
10584
|
+
const plannedPosition = plannedPositions.get(node.id);
|
|
10585
|
+
if (!plannedPosition) return node;
|
|
10586
|
+
return { ...node, position: plannedPosition };
|
|
10587
|
+
});
|
|
10588
|
+
});
|
|
10589
|
+
},
|
|
10590
|
+
[getIntersectingNodes, setNodes]
|
|
10591
|
+
);
|
|
10126
10592
|
const layoutSubFlowChildren = (0, import_react79.useCallback)(
|
|
10127
10593
|
(children, edges2, sizeOf, opts) => {
|
|
10128
10594
|
const { padding, headerH, fallbackW = 240, fallbackH = 120 } = opts;
|
|
@@ -10220,9 +10686,19 @@ var NodeGraphBuilder = ({
|
|
|
10220
10686
|
}
|
|
10221
10687
|
const without = prev.filter(
|
|
10222
10688
|
(n) => n.id !== groupNodeId && !childNodeIds.has(n.id) && !(downstreamNodeIds.has(n.id) && !referencedByEdges.has(n.id))
|
|
10223
|
-
)
|
|
10224
|
-
|
|
10225
|
-
|
|
10689
|
+
).map((n) => {
|
|
10690
|
+
const stashedPosition = stashed?.nodePositions?.[n.id];
|
|
10691
|
+
if (!stashedPosition || n.parentId) return n;
|
|
10692
|
+
return { ...n, position: stashedPosition };
|
|
10693
|
+
});
|
|
10694
|
+
const next = [
|
|
10695
|
+
...without,
|
|
10696
|
+
{
|
|
10697
|
+
...originalNode,
|
|
10698
|
+
position: stashed?.nodePositions?.[groupNodeId] ?? expandedNode.position
|
|
10699
|
+
}
|
|
10700
|
+
];
|
|
10701
|
+
return next;
|
|
10226
10702
|
});
|
|
10227
10703
|
setEdges((prev) => {
|
|
10228
10704
|
const without = prev.filter(
|
|
@@ -10230,9 +10706,6 @@ var NodeGraphBuilder = ({
|
|
|
10230
10706
|
);
|
|
10231
10707
|
return [...without, ...originalEdges];
|
|
10232
10708
|
});
|
|
10233
|
-
requestAnimationFrame(() => {
|
|
10234
|
-
fitView({ duration: 400, padding: 0.2 });
|
|
10235
|
-
});
|
|
10236
10709
|
},
|
|
10237
10710
|
[
|
|
10238
10711
|
initialNodes,
|
|
@@ -10240,8 +10713,7 @@ var NodeGraphBuilder = ({
|
|
|
10240
10713
|
setNodes,
|
|
10241
10714
|
setEdges,
|
|
10242
10715
|
relayoutGraph,
|
|
10243
|
-
animateLayout
|
|
10244
|
-
fitView
|
|
10716
|
+
animateLayout
|
|
10245
10717
|
]
|
|
10246
10718
|
);
|
|
10247
10719
|
(0, import_react79.useEffect)(() => {
|
|
@@ -10324,9 +10796,6 @@ var NodeGraphBuilder = ({
|
|
|
10324
10796
|
onNodeClick(node);
|
|
10325
10797
|
return;
|
|
10326
10798
|
}
|
|
10327
|
-
if (linksToVisualiser && onNavigate) {
|
|
10328
|
-
return;
|
|
10329
|
-
}
|
|
10330
10799
|
const isFlow = edgesRef.current.some(
|
|
10331
10800
|
(edge) => edge.type === "flow-edge"
|
|
10332
10801
|
);
|
|
@@ -10340,6 +10809,24 @@ var NodeGraphBuilder = ({
|
|
|
10340
10809
|
if (node.type === "messageGroup") {
|
|
10341
10810
|
const groupData = node.data;
|
|
10342
10811
|
const groupNodeId = node.id;
|
|
10812
|
+
const currentGroupNode = getExpandedMessageGroupNode(
|
|
10813
|
+
nodesRef.current,
|
|
10814
|
+
groupNodeId
|
|
10815
|
+
);
|
|
10816
|
+
if (currentGroupNode?.type === "messageGroupExpanded") {
|
|
10817
|
+
const measured = currentGroupNode?.measured;
|
|
10818
|
+
const width = measured?.width ?? currentGroupNode.style?.width ?? 380;
|
|
10819
|
+
const height = measured?.height ?? currentGroupNode.style?.height ?? 300;
|
|
10820
|
+
setCenter(
|
|
10821
|
+
currentGroupNode.position.x + width / 2,
|
|
10822
|
+
currentGroupNode.position.y + height / 2,
|
|
10823
|
+
{
|
|
10824
|
+
duration: 300,
|
|
10825
|
+
zoom: Math.min(Math.max(getZoom(), 0.55), 1)
|
|
10826
|
+
}
|
|
10827
|
+
);
|
|
10828
|
+
return;
|
|
10829
|
+
}
|
|
10343
10830
|
const serviceNodeId = `${groupData.service.id}-${groupData.service.version}`;
|
|
10344
10831
|
const childCount = groupData.messages?.length || 0;
|
|
10345
10832
|
const containerWidth = 380;
|
|
@@ -10348,6 +10835,9 @@ var NodeGraphBuilder = ({
|
|
|
10348
10835
|
(e) => e.source === groupNodeId || e.target === groupNodeId
|
|
10349
10836
|
);
|
|
10350
10837
|
const preExpansionNodeIds = nodesRef.current.map((n) => n.id);
|
|
10838
|
+
const preExpansionNodePositions = Object.fromEntries(
|
|
10839
|
+
nodesRef.current.map((n) => [n.id, { ...n.position }])
|
|
10840
|
+
);
|
|
10351
10841
|
const expandedContainerNode = {
|
|
10352
10842
|
id: groupNodeId,
|
|
10353
10843
|
type: "messageGroupExpanded",
|
|
@@ -10360,7 +10850,8 @@ var NodeGraphBuilder = ({
|
|
|
10360
10850
|
__preExpansion: {
|
|
10361
10851
|
node,
|
|
10362
10852
|
edges: preExpansionEdges,
|
|
10363
|
-
nodeIds: preExpansionNodeIds
|
|
10853
|
+
nodeIds: preExpansionNodeIds,
|
|
10854
|
+
nodePositions: preExpansionNodePositions
|
|
10364
10855
|
}
|
|
10365
10856
|
},
|
|
10366
10857
|
style: {
|
|
@@ -10421,24 +10912,19 @@ var NodeGraphBuilder = ({
|
|
|
10421
10912
|
});
|
|
10422
10913
|
animateLayout();
|
|
10423
10914
|
setNodes((prev) => {
|
|
10424
|
-
const
|
|
10425
|
-
const
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
const next = [
|
|
10430
|
-
...without,
|
|
10915
|
+
const downstreamX = groupData.direction === "sends" ? node.position.x + containerWidth + 260 : node.position.x - 420;
|
|
10916
|
+
const downstreamY = node.position.y + 40;
|
|
10917
|
+
return buildMessageGroupExpansionNodes({
|
|
10918
|
+
currentNodes: prev,
|
|
10919
|
+
groupNodeId,
|
|
10431
10920
|
expandedContainerNode,
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
...childEdges,
|
|
10440
|
-
...downstreamEdges
|
|
10441
|
-
]);
|
|
10921
|
+
childNodes,
|
|
10922
|
+
downstreamNodes,
|
|
10923
|
+
getDownstreamPosition: (_downstreamNode, index) => ({
|
|
10924
|
+
x: downstreamX,
|
|
10925
|
+
y: downstreamY + index * 190
|
|
10926
|
+
})
|
|
10927
|
+
});
|
|
10442
10928
|
});
|
|
10443
10929
|
setEdges((prev) => {
|
|
10444
10930
|
const without = prev.filter(
|
|
@@ -10447,6 +10933,12 @@ var NodeGraphBuilder = ({
|
|
|
10447
10933
|
return [...without, ...childEdges, ...downstreamEdges];
|
|
10448
10934
|
});
|
|
10449
10935
|
requestAnimationFrame(() => {
|
|
10936
|
+
let actualContainerBounds = {
|
|
10937
|
+
x: node.position.x,
|
|
10938
|
+
y: node.position.y,
|
|
10939
|
+
width: containerWidth,
|
|
10940
|
+
height: containerHeight
|
|
10941
|
+
};
|
|
10450
10942
|
setNodes((prev) => {
|
|
10451
10943
|
const children = prev.filter((n) => n.parentId === groupNodeId);
|
|
10452
10944
|
if (children.length === 0) return prev;
|
|
@@ -10466,8 +10958,20 @@ var NodeGraphBuilder = ({
|
|
|
10466
10958
|
const totalChildH = measurements.reduce((sum, m) => sum + m.h, 0) + gap * (measurements.length - 1);
|
|
10467
10959
|
const actualContainerH = headerH + totalChildH + padding * 2;
|
|
10468
10960
|
let currentY = headerH + padding;
|
|
10961
|
+
actualContainerBounds = {
|
|
10962
|
+
x: node.position.x,
|
|
10963
|
+
y: node.position.y,
|
|
10964
|
+
width: containerWidth,
|
|
10965
|
+
height: actualContainerH
|
|
10966
|
+
};
|
|
10469
10967
|
return prev.map((n) => {
|
|
10470
10968
|
if (n.id === groupNodeId) {
|
|
10969
|
+
actualContainerBounds = {
|
|
10970
|
+
x: n.position.x,
|
|
10971
|
+
y: n.position.y,
|
|
10972
|
+
width: containerWidth,
|
|
10973
|
+
height: actualContainerH
|
|
10974
|
+
};
|
|
10471
10975
|
return {
|
|
10472
10976
|
...n,
|
|
10473
10977
|
style: {
|
|
@@ -10485,9 +10989,23 @@ var NodeGraphBuilder = ({
|
|
|
10485
10989
|
return { ...n, position: { x, y } };
|
|
10486
10990
|
});
|
|
10487
10991
|
});
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10992
|
+
requestAnimationFrame(() => {
|
|
10993
|
+
const groupNode = getNodes().find((n) => n.id === groupNodeId);
|
|
10994
|
+
const measured = groupNode?.measured;
|
|
10995
|
+
const width = measured?.width ?? groupNode?.style?.width ?? containerWidth;
|
|
10996
|
+
const height = measured?.height ?? groupNode?.style?.height ?? actualContainerBounds.height;
|
|
10997
|
+
const bounds = {
|
|
10998
|
+
x: groupNode?.position.x ?? actualContainerBounds.x,
|
|
10999
|
+
y: groupNode?.position.y ?? actualContainerBounds.y,
|
|
11000
|
+
width,
|
|
11001
|
+
height
|
|
11002
|
+
};
|
|
11003
|
+
makeRoomForRenderedExpandedGroup(groupNodeId, bounds);
|
|
11004
|
+
setCenter(bounds.x + width / 2, bounds.y + height / 2, {
|
|
11005
|
+
duration: 450,
|
|
11006
|
+
zoom: Math.min(Math.max(getZoom(), 0.55), 1)
|
|
11007
|
+
});
|
|
11008
|
+
});
|
|
10491
11009
|
});
|
|
10492
11010
|
return;
|
|
10493
11011
|
}
|
|
@@ -10652,10 +11170,21 @@ var NodeGraphBuilder = ({
|
|
|
10652
11170
|
});
|
|
10653
11171
|
return;
|
|
10654
11172
|
}
|
|
11173
|
+
if (linksToVisualiser && onNavigate) {
|
|
11174
|
+
return;
|
|
11175
|
+
}
|
|
10655
11176
|
setFocusedNodeId(node.id);
|
|
10656
11177
|
setFocusModeOpen(true);
|
|
10657
11178
|
},
|
|
10658
|
-
[
|
|
11179
|
+
[
|
|
11180
|
+
onNodeClick,
|
|
11181
|
+
linksToVisualiser,
|
|
11182
|
+
onNavigate,
|
|
11183
|
+
makeRoomForRenderedExpandedGroup,
|
|
11184
|
+
getNodes,
|
|
11185
|
+
getZoom,
|
|
11186
|
+
setCenter
|
|
11187
|
+
]
|
|
10659
11188
|
);
|
|
10660
11189
|
const toggleAnimateMessages = (0, import_react79.useCallback)(() => {
|
|
10661
11190
|
setAnimateMessages((prev) => {
|
|
@@ -10885,13 +11414,15 @@ var NodeGraphBuilder = ({
|
|
|
10885
11414
|
}, [getNodes, downloadImage, title]);
|
|
10886
11415
|
const handleLegendClick = (0, import_react79.useCallback)(
|
|
10887
11416
|
(collectionType, groupId) => {
|
|
11417
|
+
const isLegendTarget = (node) => {
|
|
11418
|
+
if (groupId) {
|
|
11419
|
+
return node.data.group && node.data.group?.id === groupId;
|
|
11420
|
+
}
|
|
11421
|
+
return node.type === collectionType;
|
|
11422
|
+
};
|
|
10888
11423
|
const updatedNodes = nodes.map((node) => {
|
|
10889
|
-
if (
|
|
11424
|
+
if (isLegendTarget(node)) {
|
|
10890
11425
|
return { ...node, style: { ...node.style, opacity: 1 } };
|
|
10891
|
-
} else {
|
|
10892
|
-
if (node.type === collectionType) {
|
|
10893
|
-
return { ...node, style: { ...node.style, opacity: 1 } };
|
|
10894
|
-
}
|
|
10895
11426
|
}
|
|
10896
11427
|
return { ...node, style: { ...node.style, opacity: 0.1 } };
|
|
10897
11428
|
});
|
|
@@ -10906,10 +11437,12 @@ var NodeGraphBuilder = ({
|
|
|
10906
11437
|
});
|
|
10907
11438
|
setNodes(updatedNodes);
|
|
10908
11439
|
setEdges(updatedEdges);
|
|
11440
|
+
const targetNodes = updatedNodes.filter(isLegendTarget);
|
|
11441
|
+
if (targetNodes.length === 0) return;
|
|
10909
11442
|
fitView({
|
|
10910
11443
|
padding: 0.2,
|
|
10911
11444
|
duration: 800,
|
|
10912
|
-
nodes:
|
|
11445
|
+
nodes: targetNodes
|
|
10913
11446
|
});
|
|
10914
11447
|
},
|
|
10915
11448
|
[nodes, edges, setNodes, setEdges, fitView]
|
|
@@ -11106,7 +11639,7 @@ var NodeGraphBuilder = ({
|
|
|
11106
11639
|
"aria-label": "Open menu",
|
|
11107
11640
|
children: [
|
|
11108
11641
|
title && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-base font-medium text-[rgb(var(--ec-page-text))] leading-tight", children: title }),
|
|
11109
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11642
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.MoreVertical, { className: "h-5 w-5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 group-hover:text-[rgb(var(--ec-accent))] transition-colors duration-150" })
|
|
11110
11643
|
]
|
|
11111
11644
|
}
|
|
11112
11645
|
) }),
|
|
@@ -11208,7 +11741,7 @@ var NodeGraphBuilder = ({
|
|
|
11208
11741
|
"aria-label": "Open menu",
|
|
11209
11742
|
children: [
|
|
11210
11743
|
title && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-base font-medium text-[rgb(var(--ec-page-text))] leading-tight", children: title }),
|
|
11211
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11744
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.MoreVertical, { className: "h-5 w-5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 group-hover:text-[rgb(var(--ec-accent))] transition-colors duration-150" })
|
|
11212
11745
|
]
|
|
11213
11746
|
}
|
|
11214
11747
|
) }),
|
|
@@ -11270,7 +11803,7 @@ var NodeGraphBuilder = ({
|
|
|
11270
11803
|
) }) })
|
|
11271
11804
|
] }),
|
|
11272
11805
|
links.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex justify-end mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "relative flex items-center -mt-1", children: [
|
|
11273
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "absolute left-2 pointer-events-none flex items-center h-full", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11806
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "absolute left-2 pointer-events-none flex items-center h-full", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.HistoryIcon, { className: "h-4 w-4 text-[rgb(var(--ec-page-text-muted))]" }) }),
|
|
11274
11807
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11275
11808
|
"select",
|
|
11276
11809
|
{
|
|
@@ -11425,7 +11958,7 @@ var NodeGraphBuilder = ({
|
|
|
11425
11958
|
onClick: () => setIsShareModalOpen(false),
|
|
11426
11959
|
className: "text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] transition-colors",
|
|
11427
11960
|
"aria-label": "Close modal",
|
|
11428
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11961
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.ExternalLink, { className: "w-5 h-5 rotate-180" })
|
|
11429
11962
|
}
|
|
11430
11963
|
)
|
|
11431
11964
|
] }),
|
|
@@ -11447,7 +11980,7 @@ var NodeGraphBuilder = ({
|
|
|
11447
11980
|
className: `px-4 py-2.5 rounded-md font-medium transition-all duration-200 flex items-center gap-2 ${shareUrlCopySuccess ? "bg-green-500 text-white" : "bg-[rgb(var(--ec-accent))] text-white hover:opacity-90"}`,
|
|
11448
11981
|
"aria-label": shareUrlCopySuccess ? "Copied!" : "Copy link",
|
|
11449
11982
|
children: [
|
|
11450
|
-
shareUrlCopySuccess ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
11983
|
+
shareUrlCopySuccess ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.CheckIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react32.ClipboardIcon, { className: "w-4 h-4" }),
|
|
11451
11984
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: shareUrlCopySuccess ? "Copied!" : "Copy" })
|
|
11452
11985
|
]
|
|
11453
11986
|
}
|