@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.mjs
CHANGED
|
@@ -6043,7 +6043,75 @@ import {
|
|
|
6043
6043
|
useImperativeHandle,
|
|
6044
6044
|
memo as memo31
|
|
6045
6045
|
} from "react";
|
|
6046
|
+
import {
|
|
6047
|
+
Blocks,
|
|
6048
|
+
Database as Database5,
|
|
6049
|
+
Layers as Layers3,
|
|
6050
|
+
ListTree,
|
|
6051
|
+
MessageSquare as MessageSquare2,
|
|
6052
|
+
Search as SearchIcon,
|
|
6053
|
+
Server as Server2,
|
|
6054
|
+
User as User3,
|
|
6055
|
+
Workflow as Workflow2,
|
|
6056
|
+
Zap as Zap4
|
|
6057
|
+
} from "lucide-react";
|
|
6046
6058
|
import { jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6059
|
+
var formatVersionedName = (name, version) => {
|
|
6060
|
+
if (version) {
|
|
6061
|
+
const nameWithoutVersion = name.replace(
|
|
6062
|
+
new RegExp(`-v?${version.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`),
|
|
6063
|
+
""
|
|
6064
|
+
);
|
|
6065
|
+
return `${nameWithoutVersion} (v${version})`;
|
|
6066
|
+
}
|
|
6067
|
+
const versionMatch = name.match(
|
|
6068
|
+
/^(.+)-v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/
|
|
6069
|
+
);
|
|
6070
|
+
if (!versionMatch) return name;
|
|
6071
|
+
return `${versionMatch[1]} (v${versionMatch[2]})`;
|
|
6072
|
+
};
|
|
6073
|
+
var normalizeCollectionType = (type) => {
|
|
6074
|
+
const aliases = {
|
|
6075
|
+
event: "events",
|
|
6076
|
+
command: "commands",
|
|
6077
|
+
query: "queries",
|
|
6078
|
+
service: "services",
|
|
6079
|
+
domain: "domains",
|
|
6080
|
+
channel: "channels",
|
|
6081
|
+
entity: "entities"
|
|
6082
|
+
};
|
|
6083
|
+
return aliases[type] || type;
|
|
6084
|
+
};
|
|
6085
|
+
var splitVersionedName = (name, version) => {
|
|
6086
|
+
if (version) {
|
|
6087
|
+
return {
|
|
6088
|
+
id: name.replace(
|
|
6089
|
+
new RegExp(`-v?${version.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`),
|
|
6090
|
+
""
|
|
6091
|
+
),
|
|
6092
|
+
version
|
|
6093
|
+
};
|
|
6094
|
+
}
|
|
6095
|
+
const versionMatch = name.match(
|
|
6096
|
+
/^(.+)-v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/
|
|
6097
|
+
);
|
|
6098
|
+
if (!versionMatch) return { id: name, version: void 0 };
|
|
6099
|
+
return { id: versionMatch[1], version: versionMatch[2] };
|
|
6100
|
+
};
|
|
6101
|
+
var getResourceKey = ({
|
|
6102
|
+
type,
|
|
6103
|
+
id,
|
|
6104
|
+
name,
|
|
6105
|
+
version
|
|
6106
|
+
}) => {
|
|
6107
|
+
const parsed = splitVersionedName(id || name, version);
|
|
6108
|
+
return `${normalizeCollectionType(type)}:${parsed.id}:${parsed.version || ""}`.toLowerCase();
|
|
6109
|
+
};
|
|
6110
|
+
var getNodeResourceData = (data, key) => {
|
|
6111
|
+
const resource = data?.[key];
|
|
6112
|
+
if (!resource || typeof resource !== "object") return void 0;
|
|
6113
|
+
return "data" in resource && resource.data ? resource.data : resource;
|
|
6114
|
+
};
|
|
6047
6115
|
var VisualiserSearch = memo31(
|
|
6048
6116
|
forwardRef(
|
|
6049
6117
|
({ nodes, onNodeSelect, onClear, onPaneClick: _onPaneClick }, ref) => {
|
|
@@ -6053,6 +6121,8 @@ var VisualiserSearch = memo31(
|
|
|
6053
6121
|
const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState5(-1);
|
|
6054
6122
|
const searchInputRef = useRef2(null);
|
|
6055
6123
|
const containerRef = useRef2(null);
|
|
6124
|
+
const suggestionsListRef = useRef2(null);
|
|
6125
|
+
const suggestionItemRefs = useRef2([]);
|
|
6056
6126
|
const hideSuggestions = useCallback4(() => {
|
|
6057
6127
|
setShowSuggestions(false);
|
|
6058
6128
|
setSelectedSuggestionIndex(-1);
|
|
@@ -6071,84 +6141,277 @@ var VisualiserSearch = memo31(
|
|
|
6071
6141
|
if (node.type === "messageGroupExpanded") {
|
|
6072
6142
|
return node.data?.groupName || node.id;
|
|
6073
6143
|
}
|
|
6074
|
-
const
|
|
6075
|
-
const
|
|
6076
|
-
|
|
6144
|
+
const message = getNodeResourceData(node.data, "message");
|
|
6145
|
+
const service = getNodeResourceData(node.data, "service");
|
|
6146
|
+
const domain = getNodeResourceData(node.data, "domain");
|
|
6147
|
+
const entity = getNodeResourceData(node.data, "entity");
|
|
6148
|
+
const channel = getNodeResourceData(node.data, "channel");
|
|
6149
|
+
const dataProduct = getNodeResourceData(node.data, "dataProduct");
|
|
6150
|
+
const data = getNodeResourceData(node.data, "data");
|
|
6151
|
+
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;
|
|
6152
|
+
const version = message?.version || service?.version || domain?.version || entity?.version || channel?.version || dataProduct?.version || data?.version || node.data?.version;
|
|
6153
|
+
return formatVersionedName(name, version);
|
|
6077
6154
|
}, []);
|
|
6078
|
-
const
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6155
|
+
const getNodeResourceKey = useCallback4(
|
|
6156
|
+
(node, label) => {
|
|
6157
|
+
if (node.type === "messageGroup" || node.type === "messageGroupExpanded") {
|
|
6158
|
+
return `${node.type}:${node.id}`.toLowerCase();
|
|
6159
|
+
}
|
|
6160
|
+
const data = node.data;
|
|
6161
|
+
const resource = getNodeResourceData(data, "message") || getNodeResourceData(data, "service") || getNodeResourceData(data, "domain") || getNodeResourceData(data, "entity") || getNodeResourceData(data, "channel") || getNodeResourceData(data, "dataProduct") || data?.data || data;
|
|
6162
|
+
return getResourceKey({
|
|
6163
|
+
type: node.type || "unknown",
|
|
6164
|
+
id: resource?.id,
|
|
6165
|
+
name: resource?.name || resource?.id || label || node.id,
|
|
6166
|
+
version: resource?.version || data?.version
|
|
6167
|
+
});
|
|
6168
|
+
},
|
|
6169
|
+
[]
|
|
6170
|
+
);
|
|
6171
|
+
const dedupeSearchSuggestions = useCallback4(
|
|
6172
|
+
(suggestions) => {
|
|
6173
|
+
const uniqueSuggestions = [];
|
|
6174
|
+
const indexByResourceKey = /* @__PURE__ */ new Map();
|
|
6175
|
+
suggestions.forEach((suggestion) => {
|
|
6176
|
+
const existingIndex = indexByResourceKey.get(
|
|
6177
|
+
suggestion.resourceKey
|
|
6178
|
+
);
|
|
6179
|
+
if (existingIndex === void 0) {
|
|
6180
|
+
indexByResourceKey.set(
|
|
6181
|
+
suggestion.resourceKey,
|
|
6182
|
+
uniqueSuggestions.length
|
|
6183
|
+
);
|
|
6184
|
+
uniqueSuggestions.push(suggestion);
|
|
6185
|
+
return;
|
|
6186
|
+
}
|
|
6187
|
+
if (suggestion.isGroupedMessage && !uniqueSuggestions[existingIndex].isGroupedMessage) {
|
|
6188
|
+
uniqueSuggestions[existingIndex] = suggestion;
|
|
6189
|
+
}
|
|
6190
|
+
});
|
|
6191
|
+
return uniqueSuggestions;
|
|
6192
|
+
},
|
|
6193
|
+
[]
|
|
6194
|
+
);
|
|
6195
|
+
const getSearchSuggestions = useCallback4(
|
|
6196
|
+
(nodesToIndex) => {
|
|
6197
|
+
const suggestions = nodesToIndex.flatMap((node) => {
|
|
6198
|
+
const nodeName = getNodeDisplayName(node);
|
|
6199
|
+
const suggestions2 = [
|
|
6200
|
+
{
|
|
6201
|
+
key: node.id,
|
|
6202
|
+
node,
|
|
6203
|
+
label: nodeName,
|
|
6204
|
+
searchText: nodeName,
|
|
6205
|
+
type: node.type || "unknown",
|
|
6206
|
+
resourceKey: getNodeResourceKey(node, nodeName)
|
|
6207
|
+
}
|
|
6208
|
+
];
|
|
6209
|
+
if (node.type !== "messageGroup") return suggestions2;
|
|
6210
|
+
const groupName = node.data?.groupName || nodeName;
|
|
6211
|
+
const groupedMessages = node.data?.messages || [];
|
|
6212
|
+
groupedMessages.forEach((item, index) => {
|
|
6213
|
+
const message = item.message;
|
|
6214
|
+
const messageName = message?.data?.name || message?.data?.id;
|
|
6215
|
+
if (!messageName) return;
|
|
6216
|
+
const version = message?.data?.version;
|
|
6217
|
+
const label = formatVersionedName(messageName, version);
|
|
6218
|
+
suggestions2.push({
|
|
6219
|
+
key: `${node.id}:${message?.data?.id || messageName}:${version || index}`,
|
|
6220
|
+
node,
|
|
6221
|
+
label,
|
|
6222
|
+
searchText: `${label} ${groupName}`,
|
|
6223
|
+
type: message?.collection || "message",
|
|
6224
|
+
resourceKey: getResourceKey({
|
|
6225
|
+
type: message?.collection || "message",
|
|
6226
|
+
id: message?.data?.id,
|
|
6227
|
+
name: messageName,
|
|
6228
|
+
version
|
|
6229
|
+
}),
|
|
6230
|
+
groupName,
|
|
6231
|
+
isGroupedMessage: true
|
|
6232
|
+
});
|
|
6233
|
+
});
|
|
6234
|
+
return suggestions2;
|
|
6235
|
+
});
|
|
6236
|
+
return dedupeSearchSuggestions(suggestions);
|
|
6237
|
+
},
|
|
6238
|
+
[dedupeSearchSuggestions, getNodeDisplayName, getNodeResourceKey]
|
|
6239
|
+
);
|
|
6240
|
+
const getNodeTypeMeta = useCallback4((nodeType) => {
|
|
6241
|
+
const meta = {
|
|
6242
|
+
events: {
|
|
6243
|
+
label: "Event",
|
|
6244
|
+
Icon: Zap4,
|
|
6245
|
+
iconClass: "border-orange-500/25 bg-orange-500/10 text-orange-500",
|
|
6246
|
+
badgeClass: "border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300"
|
|
6247
|
+
},
|
|
6248
|
+
event: {
|
|
6249
|
+
label: "Event",
|
|
6250
|
+
Icon: Zap4,
|
|
6251
|
+
iconClass: "border-orange-500/25 bg-orange-500/10 text-orange-500",
|
|
6252
|
+
badgeClass: "border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300"
|
|
6253
|
+
},
|
|
6254
|
+
commands: {
|
|
6255
|
+
label: "Command",
|
|
6256
|
+
Icon: MessageSquare2,
|
|
6257
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6258
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6259
|
+
},
|
|
6260
|
+
command: {
|
|
6261
|
+
label: "Command",
|
|
6262
|
+
Icon: MessageSquare2,
|
|
6263
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6264
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6265
|
+
},
|
|
6266
|
+
queries: {
|
|
6267
|
+
label: "Query",
|
|
6268
|
+
Icon: SearchIcon,
|
|
6269
|
+
iconClass: "border-green-500/25 bg-green-500/10 text-green-500",
|
|
6270
|
+
badgeClass: "border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300"
|
|
6271
|
+
},
|
|
6272
|
+
query: {
|
|
6273
|
+
label: "Query",
|
|
6274
|
+
Icon: SearchIcon,
|
|
6275
|
+
iconClass: "border-green-500/25 bg-green-500/10 text-green-500",
|
|
6276
|
+
badgeClass: "border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300"
|
|
6277
|
+
},
|
|
6278
|
+
services: {
|
|
6279
|
+
label: "Service",
|
|
6280
|
+
Icon: Server2,
|
|
6281
|
+
iconClass: "border-pink-500/25 bg-pink-500/10 text-pink-500",
|
|
6282
|
+
badgeClass: "border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300"
|
|
6283
|
+
},
|
|
6284
|
+
domains: {
|
|
6285
|
+
label: "Domain",
|
|
6286
|
+
Icon: Blocks,
|
|
6287
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6288
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6289
|
+
},
|
|
6290
|
+
flows: {
|
|
6291
|
+
label: "Flow",
|
|
6292
|
+
Icon: Workflow2,
|
|
6293
|
+
iconClass: "border-teal-500/25 bg-teal-500/10 text-teal-500",
|
|
6294
|
+
badgeClass: "border-teal-500/25 bg-teal-500/10 text-teal-700 dark:text-teal-300"
|
|
6295
|
+
},
|
|
6296
|
+
channels: {
|
|
6297
|
+
label: "Channel",
|
|
6298
|
+
Icon: ListTree,
|
|
6299
|
+
iconClass: "border-gray-500/25 bg-gray-500/10 text-gray-500",
|
|
6300
|
+
badgeClass: "border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300"
|
|
6301
|
+
},
|
|
6302
|
+
data: {
|
|
6303
|
+
label: "Data",
|
|
6304
|
+
Icon: Database5,
|
|
6305
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6306
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6307
|
+
},
|
|
6308
|
+
entities: {
|
|
6309
|
+
label: "Entity",
|
|
6310
|
+
Icon: Database5,
|
|
6311
|
+
iconClass: "border-blue-500/25 bg-blue-500/10 text-blue-500",
|
|
6312
|
+
badgeClass: "border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300"
|
|
6313
|
+
},
|
|
6314
|
+
externalSystem: {
|
|
6315
|
+
label: "External",
|
|
6316
|
+
Icon: Server2,
|
|
6317
|
+
iconClass: "border-pink-500/25 bg-pink-500/10 text-pink-500",
|
|
6318
|
+
badgeClass: "border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300"
|
|
6319
|
+
},
|
|
6320
|
+
actor: {
|
|
6321
|
+
label: "Actor",
|
|
6322
|
+
Icon: User3,
|
|
6323
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6324
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6325
|
+
},
|
|
6326
|
+
user: {
|
|
6327
|
+
label: "User",
|
|
6328
|
+
Icon: User3,
|
|
6329
|
+
iconClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
6330
|
+
badgeClass: "border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300"
|
|
6331
|
+
},
|
|
6332
|
+
messageGroup: {
|
|
6333
|
+
label: "Group",
|
|
6334
|
+
Icon: Layers3,
|
|
6335
|
+
iconClass: "border-violet-500/25 bg-violet-500/10 text-violet-500",
|
|
6336
|
+
badgeClass: "border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300"
|
|
6337
|
+
},
|
|
6338
|
+
messageGroupExpanded: {
|
|
6339
|
+
label: "Group",
|
|
6340
|
+
Icon: Layers3,
|
|
6341
|
+
iconClass: "border-violet-500/25 bg-violet-500/10 text-violet-500",
|
|
6342
|
+
badgeClass: "border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300"
|
|
6343
|
+
}
|
|
6344
|
+
};
|
|
6345
|
+
return meta[nodeType] || {
|
|
6346
|
+
label: nodeType,
|
|
6347
|
+
Icon: Layers3,
|
|
6348
|
+
iconClass: "border-gray-500/25 bg-gray-500/10 text-gray-500",
|
|
6349
|
+
badgeClass: "border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300"
|
|
6095
6350
|
};
|
|
6096
|
-
return colorClasses[nodeType] || "bg-gray-100 text-gray-700";
|
|
6097
6351
|
}, []);
|
|
6098
6352
|
const handleSearchChange = useCallback4(
|
|
6099
6353
|
(event) => {
|
|
6100
6354
|
const query = event.target.value;
|
|
6101
6355
|
setSearchQuery(query);
|
|
6102
6356
|
if (query.length > 0) {
|
|
6103
|
-
const
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6357
|
+
const search = query.toLowerCase();
|
|
6358
|
+
const filtered = getSearchSuggestions(nodes).filter(
|
|
6359
|
+
(suggestion) => suggestion.searchText.toLowerCase().includes(search)
|
|
6360
|
+
);
|
|
6107
6361
|
setFilteredSuggestions(filtered);
|
|
6108
6362
|
setShowSuggestions(true);
|
|
6109
6363
|
setSelectedSuggestionIndex(-1);
|
|
6110
6364
|
} else {
|
|
6111
|
-
setFilteredSuggestions(nodes);
|
|
6365
|
+
setFilteredSuggestions(getSearchSuggestions(nodes));
|
|
6112
6366
|
setShowSuggestions(true);
|
|
6113
6367
|
setSelectedSuggestionIndex(-1);
|
|
6114
6368
|
}
|
|
6115
6369
|
},
|
|
6116
|
-
[nodes,
|
|
6370
|
+
[nodes, getSearchSuggestions]
|
|
6117
6371
|
);
|
|
6118
6372
|
const handleSearchFocus = useCallback4(() => {
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6373
|
+
const suggestions = getSearchSuggestions(nodes);
|
|
6374
|
+
const search = searchQuery.toLowerCase();
|
|
6375
|
+
setFilteredSuggestions(
|
|
6376
|
+
searchQuery.length === 0 ? suggestions : suggestions.filter(
|
|
6377
|
+
(suggestion) => suggestion.searchText.toLowerCase().includes(search)
|
|
6378
|
+
)
|
|
6379
|
+
);
|
|
6122
6380
|
setShowSuggestions(true);
|
|
6123
6381
|
setSelectedSuggestionIndex(-1);
|
|
6124
|
-
}, [nodes, searchQuery]);
|
|
6382
|
+
}, [nodes, searchQuery, getSearchSuggestions]);
|
|
6125
6383
|
const handleSuggestionClick = useCallback4(
|
|
6126
|
-
(
|
|
6127
|
-
setSearchQuery(
|
|
6384
|
+
(suggestion) => {
|
|
6385
|
+
setSearchQuery("");
|
|
6386
|
+
setFilteredSuggestions([]);
|
|
6128
6387
|
setShowSuggestions(false);
|
|
6129
|
-
|
|
6388
|
+
setSelectedSuggestionIndex(-1);
|
|
6389
|
+
onNodeSelect(suggestion.node);
|
|
6130
6390
|
},
|
|
6131
|
-
[onNodeSelect
|
|
6391
|
+
[onNodeSelect]
|
|
6132
6392
|
);
|
|
6133
6393
|
const handleSearchKeyDown = useCallback4(
|
|
6134
6394
|
(event) => {
|
|
6135
|
-
if (!showSuggestions || filteredSuggestions.length === 0) return;
|
|
6136
6395
|
switch (event.key) {
|
|
6137
6396
|
case "ArrowDown":
|
|
6138
6397
|
event.preventDefault();
|
|
6398
|
+
if (filteredSuggestions.length === 0) return;
|
|
6399
|
+
setShowSuggestions(true);
|
|
6139
6400
|
setSelectedSuggestionIndex(
|
|
6140
6401
|
(prev) => prev < filteredSuggestions.length - 1 ? prev + 1 : 0
|
|
6141
6402
|
);
|
|
6142
6403
|
break;
|
|
6143
6404
|
case "ArrowUp":
|
|
6144
6405
|
event.preventDefault();
|
|
6406
|
+
if (filteredSuggestions.length === 0) return;
|
|
6407
|
+
setShowSuggestions(true);
|
|
6145
6408
|
setSelectedSuggestionIndex(
|
|
6146
6409
|
(prev) => prev > 0 ? prev - 1 : filteredSuggestions.length - 1
|
|
6147
6410
|
);
|
|
6148
6411
|
break;
|
|
6149
6412
|
case "Enter":
|
|
6150
6413
|
event.preventDefault();
|
|
6151
|
-
if (selectedSuggestionIndex >= 0) {
|
|
6414
|
+
if (showSuggestions && selectedSuggestionIndex >= 0 && selectedSuggestionIndex < filteredSuggestions.length) {
|
|
6152
6415
|
handleSuggestionClick(
|
|
6153
6416
|
filteredSuggestions[selectedSuggestionIndex]
|
|
6154
6417
|
);
|
|
@@ -6177,6 +6440,31 @@ var VisualiserSearch = memo31(
|
|
|
6177
6440
|
searchInputRef.current.focus();
|
|
6178
6441
|
}
|
|
6179
6442
|
}, [onClear]);
|
|
6443
|
+
useEffect2(() => {
|
|
6444
|
+
suggestionItemRefs.current = suggestionItemRefs.current.slice(
|
|
6445
|
+
0,
|
|
6446
|
+
filteredSuggestions.length
|
|
6447
|
+
);
|
|
6448
|
+
}, [filteredSuggestions.length]);
|
|
6449
|
+
useEffect2(() => {
|
|
6450
|
+
if (!showSuggestions || selectedSuggestionIndex < 0) return;
|
|
6451
|
+
const list = suggestionsListRef.current;
|
|
6452
|
+
const item = suggestionItemRefs.current[selectedSuggestionIndex];
|
|
6453
|
+
if (!list || !item) return;
|
|
6454
|
+
const itemTop = item.offsetTop;
|
|
6455
|
+
const itemBottom = itemTop + item.offsetHeight;
|
|
6456
|
+
const visibleTop = list.scrollTop;
|
|
6457
|
+
const visibleBottom = visibleTop + list.clientHeight;
|
|
6458
|
+
if (itemTop < visibleTop) {
|
|
6459
|
+
list.scrollTop = itemTop;
|
|
6460
|
+
} else if (itemBottom > visibleBottom) {
|
|
6461
|
+
list.scrollTop = itemBottom - list.clientHeight;
|
|
6462
|
+
}
|
|
6463
|
+
}, [
|
|
6464
|
+
showSuggestions,
|
|
6465
|
+
selectedSuggestionIndex,
|
|
6466
|
+
filteredSuggestions.length
|
|
6467
|
+
]);
|
|
6180
6468
|
useEffect2(() => {
|
|
6181
6469
|
const handleClickOutside = (event) => {
|
|
6182
6470
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
@@ -6231,28 +6519,53 @@ var VisualiserSearch = memo31(
|
|
|
6231
6519
|
}
|
|
6232
6520
|
)
|
|
6233
6521
|
] }),
|
|
6234
|
-
showSuggestions && filteredSuggestions.length > 0 && /* @__PURE__ */ jsx32(
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
"
|
|
6239
|
-
{
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
{
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6522
|
+
showSuggestions && filteredSuggestions.length > 0 && /* @__PURE__ */ jsx32(
|
|
6523
|
+
"div",
|
|
6524
|
+
{
|
|
6525
|
+
ref: suggestionsListRef,
|
|
6526
|
+
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",
|
|
6527
|
+
children: filteredSuggestions.map((suggestion, index) => {
|
|
6528
|
+
const nodeTypeMeta = getNodeTypeMeta(suggestion.type);
|
|
6529
|
+
const Icon = nodeTypeMeta.Icon;
|
|
6530
|
+
const isSelected = index === selectedSuggestionIndex;
|
|
6531
|
+
return /* @__PURE__ */ jsxs30(
|
|
6532
|
+
"div",
|
|
6533
|
+
{
|
|
6534
|
+
ref: (element) => {
|
|
6535
|
+
suggestionItemRefs.current[index] = element;
|
|
6536
|
+
},
|
|
6537
|
+
onClick: () => handleSuggestionClick(suggestion),
|
|
6538
|
+
onMouseEnter: () => setSelectedSuggestionIndex(index),
|
|
6539
|
+
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)]"}`,
|
|
6540
|
+
children: [
|
|
6541
|
+
/* @__PURE__ */ jsx32(
|
|
6542
|
+
"span",
|
|
6543
|
+
{
|
|
6544
|
+
className: `mt-0.5 flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-md border ${nodeTypeMeta.iconClass}`,
|
|
6545
|
+
children: /* @__PURE__ */ jsx32(Icon, { className: "h-3.5 w-3.5" })
|
|
6546
|
+
}
|
|
6547
|
+
),
|
|
6548
|
+
/* @__PURE__ */ jsxs30("span", { className: "min-w-0 flex-1", children: [
|
|
6549
|
+
/* @__PURE__ */ jsx32("span", { className: "block truncate text-sm font-medium text-[rgb(var(--ec-page-text))]", children: suggestion.label }),
|
|
6550
|
+
suggestion.isGroupedMessage && suggestion.groupName && /* @__PURE__ */ jsxs30("span", { className: "mt-0.5 block truncate text-xs text-[rgb(var(--ec-page-text-muted))]", children: [
|
|
6551
|
+
"in ",
|
|
6552
|
+
suggestion.groupName
|
|
6553
|
+
] })
|
|
6554
|
+
] }),
|
|
6555
|
+
/* @__PURE__ */ jsx32(
|
|
6556
|
+
"span",
|
|
6557
|
+
{
|
|
6558
|
+
className: `mt-0.5 flex-shrink-0 rounded border px-2 py-0.5 text-xs font-medium ${nodeTypeMeta.badgeClass}`,
|
|
6559
|
+
children: nodeTypeMeta.label
|
|
6560
|
+
}
|
|
6561
|
+
)
|
|
6562
|
+
]
|
|
6563
|
+
},
|
|
6564
|
+
`${suggestion.key}:${index}`
|
|
6565
|
+
);
|
|
6566
|
+
})
|
|
6567
|
+
}
|
|
6568
|
+
)
|
|
6256
6569
|
] });
|
|
6257
6570
|
}
|
|
6258
6571
|
)
|
|
@@ -8083,7 +8396,7 @@ import {
|
|
|
8083
8396
|
Maximize2 as Maximize23,
|
|
8084
8397
|
Map as Map2,
|
|
8085
8398
|
Sparkles,
|
|
8086
|
-
Zap as
|
|
8399
|
+
Zap as Zap5,
|
|
8087
8400
|
EyeOff,
|
|
8088
8401
|
ExternalLink,
|
|
8089
8402
|
Save,
|
|
@@ -8208,7 +8521,7 @@ var VisualizerDropdownContent = memo33(
|
|
|
8208
8521
|
onCheckedChange: toggleAnimateMessages,
|
|
8209
8522
|
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",
|
|
8210
8523
|
children: [
|
|
8211
|
-
/* @__PURE__ */ jsx40(
|
|
8524
|
+
/* @__PURE__ */ jsx40(Zap5, { className: "w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0" }),
|
|
8212
8525
|
/* @__PURE__ */ jsx40("span", { className: "flex-1 font-normal", children: "Simulate Messages" }),
|
|
8213
8526
|
/* @__PURE__ */ jsx40(
|
|
8214
8527
|
"div",
|
|
@@ -8992,6 +9305,120 @@ function flatLayout(nodes, edges, graphOpts, nodeSize, style) {
|
|
|
8992
9305
|
return { nodes: layoutNodes, edges: layoutEdges };
|
|
8993
9306
|
}
|
|
8994
9307
|
|
|
9308
|
+
// src/utils/local-packing.ts
|
|
9309
|
+
var toNumber = (value) => {
|
|
9310
|
+
if (typeof value === "number") return value;
|
|
9311
|
+
if (typeof value === "string") {
|
|
9312
|
+
const parsed = Number.parseFloat(value);
|
|
9313
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
9314
|
+
}
|
|
9315
|
+
return void 0;
|
|
9316
|
+
};
|
|
9317
|
+
var getPackableNodeSize = (node) => ({
|
|
9318
|
+
width: toNumber(node.measured?.width) ?? toNumber(node.width) ?? toNumber(node.style?.width) ?? 260,
|
|
9319
|
+
height: toNumber(node.measured?.height) ?? toNumber(node.height) ?? toNumber(node.style?.height) ?? 140
|
|
9320
|
+
});
|
|
9321
|
+
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;
|
|
9322
|
+
var toRect = (node, y = node.position.y) => {
|
|
9323
|
+
const size = getPackableNodeSize(node);
|
|
9324
|
+
return {
|
|
9325
|
+
x: node.position.x,
|
|
9326
|
+
y,
|
|
9327
|
+
width: size.width,
|
|
9328
|
+
height: size.height
|
|
9329
|
+
};
|
|
9330
|
+
};
|
|
9331
|
+
var packNodesAroundBounds = ({
|
|
9332
|
+
nodes,
|
|
9333
|
+
movableNodeIds,
|
|
9334
|
+
protectedBounds,
|
|
9335
|
+
groupNodeId,
|
|
9336
|
+
gap = 40
|
|
9337
|
+
}) => {
|
|
9338
|
+
const movableNodes = nodes.filter((node) => movableNodeIds.has(node.id)).sort((a, b) => a.position.y - b.position.y);
|
|
9339
|
+
const movableIds = new Set(movableNodes.map((node) => node.id));
|
|
9340
|
+
const occupiedRects = [
|
|
9341
|
+
protectedBounds,
|
|
9342
|
+
...nodes.filter(
|
|
9343
|
+
(node) => !node.parentId && node.id !== groupNodeId && !movableIds.has(node.id)
|
|
9344
|
+
).map((node) => toRect(node))
|
|
9345
|
+
];
|
|
9346
|
+
const plannedPositions = /* @__PURE__ */ new Map();
|
|
9347
|
+
const groupCenterY = protectedBounds.y + protectedBounds.height / 2;
|
|
9348
|
+
const placeNode = (node) => {
|
|
9349
|
+
const size = getPackableNodeSize(node);
|
|
9350
|
+
const nodeCenterY = node.position.y + size.height / 2;
|
|
9351
|
+
const moveDirection = nodeCenterY >= groupCenterY ? 1 : -1;
|
|
9352
|
+
let y = moveDirection > 0 ? Math.max(
|
|
9353
|
+
node.position.y,
|
|
9354
|
+
protectedBounds.y + protectedBounds.height + gap
|
|
9355
|
+
) : Math.min(node.position.y, protectedBounds.y - size.height - gap);
|
|
9356
|
+
let attempts = 0;
|
|
9357
|
+
while (attempts < occupiedRects.length + 8) {
|
|
9358
|
+
const rect = {
|
|
9359
|
+
x: node.position.x,
|
|
9360
|
+
y,
|
|
9361
|
+
width: size.width,
|
|
9362
|
+
height: size.height
|
|
9363
|
+
};
|
|
9364
|
+
const collision = occupiedRects.find(
|
|
9365
|
+
(occupied) => rectsIntersect(rect, occupied, gap)
|
|
9366
|
+
);
|
|
9367
|
+
if (!collision) {
|
|
9368
|
+
occupiedRects.push(rect);
|
|
9369
|
+
plannedPositions.set(node.id, { ...node.position, y });
|
|
9370
|
+
return;
|
|
9371
|
+
}
|
|
9372
|
+
y = moveDirection > 0 ? collision.y + collision.height + gap : collision.y - size.height - gap;
|
|
9373
|
+
attempts += 1;
|
|
9374
|
+
}
|
|
9375
|
+
occupiedRects.push({
|
|
9376
|
+
x: node.position.x,
|
|
9377
|
+
y,
|
|
9378
|
+
width: size.width,
|
|
9379
|
+
height: size.height
|
|
9380
|
+
});
|
|
9381
|
+
plannedPositions.set(node.id, { ...node.position, y });
|
|
9382
|
+
};
|
|
9383
|
+
const below = movableNodes.filter((node) => {
|
|
9384
|
+
const size = getPackableNodeSize(node);
|
|
9385
|
+
return node.position.y + size.height / 2 >= groupCenterY;
|
|
9386
|
+
});
|
|
9387
|
+
const belowIds = new Set(below.map((node) => node.id));
|
|
9388
|
+
const above = movableNodes.filter((node) => !belowIds.has(node.id)).reverse();
|
|
9389
|
+
below.forEach(placeNode);
|
|
9390
|
+
above.forEach(placeNode);
|
|
9391
|
+
return plannedPositions;
|
|
9392
|
+
};
|
|
9393
|
+
|
|
9394
|
+
// src/utils/message-group-expansion.ts
|
|
9395
|
+
var getExpandedMessageGroupNode = (nodes, groupNodeId) => nodes.find(
|
|
9396
|
+
(node) => node.id === groupNodeId && node.type === "messageGroupExpanded"
|
|
9397
|
+
);
|
|
9398
|
+
var buildMessageGroupExpansionNodes = ({
|
|
9399
|
+
currentNodes,
|
|
9400
|
+
groupNodeId,
|
|
9401
|
+
expandedContainerNode,
|
|
9402
|
+
childNodes,
|
|
9403
|
+
downstreamNodes,
|
|
9404
|
+
getDownstreamPosition
|
|
9405
|
+
}) => {
|
|
9406
|
+
const withoutExistingGroup = currentNodes.filter(
|
|
9407
|
+
(node) => node.id !== groupNodeId && node.parentId !== groupNodeId
|
|
9408
|
+
);
|
|
9409
|
+
const existingIds = new Set(withoutExistingGroup.map((node) => node.id));
|
|
9410
|
+
const newDownstream = downstreamNodes.filter((node) => !existingIds.has(node.id)).map((node, index) => ({
|
|
9411
|
+
...node,
|
|
9412
|
+
position: getDownstreamPosition(node, index)
|
|
9413
|
+
}));
|
|
9414
|
+
return [
|
|
9415
|
+
...withoutExistingGroup,
|
|
9416
|
+
expandedContainerNode,
|
|
9417
|
+
...childNodes,
|
|
9418
|
+
...newDownstream
|
|
9419
|
+
];
|
|
9420
|
+
};
|
|
9421
|
+
|
|
8995
9422
|
// src/components/NotesToolbarButton.tsx
|
|
8996
9423
|
import { useState as useState13, useCallback as useCallback11 } from "react";
|
|
8997
9424
|
import {
|
|
@@ -9001,14 +9428,14 @@ import {
|
|
|
9001
9428
|
Locate,
|
|
9002
9429
|
ChevronRight,
|
|
9003
9430
|
ServerIcon as ServerIcon2,
|
|
9004
|
-
Zap as
|
|
9005
|
-
MessageSquare as
|
|
9431
|
+
Zap as Zap6,
|
|
9432
|
+
MessageSquare as MessageSquare3,
|
|
9006
9433
|
Search as Search3,
|
|
9007
9434
|
ArrowRightLeft as ArrowRightLeft3,
|
|
9008
|
-
Database as
|
|
9435
|
+
Database as Database6,
|
|
9009
9436
|
Package as Package2,
|
|
9010
9437
|
Globe as Globe5,
|
|
9011
|
-
User as
|
|
9438
|
+
User as User4,
|
|
9012
9439
|
MonitorIcon as MonitorIcon2,
|
|
9013
9440
|
BoxesIcon as BoxesIcon2
|
|
9014
9441
|
} from "lucide-react";
|
|
@@ -9018,18 +9445,18 @@ import { Fragment as Fragment11, jsx as jsx42, jsxs as jsxs40 } from "react/jsx-
|
|
|
9018
9445
|
var NODE_TYPE_META = {
|
|
9019
9446
|
service: { icon: ServerIcon2, color: "#ec4899", label: "Service" },
|
|
9020
9447
|
services: { icon: ServerIcon2, color: "#ec4899", label: "Service" },
|
|
9021
|
-
event: { icon:
|
|
9022
|
-
events: { icon:
|
|
9023
|
-
command: { icon:
|
|
9024
|
-
commands: { icon:
|
|
9448
|
+
event: { icon: Zap6, color: "#f97316", label: "Event" },
|
|
9449
|
+
events: { icon: Zap6, color: "#f97316", label: "Event" },
|
|
9450
|
+
command: { icon: MessageSquare3, color: "#3b82f6", label: "Command" },
|
|
9451
|
+
commands: { icon: MessageSquare3, color: "#3b82f6", label: "Command" },
|
|
9025
9452
|
query: { icon: Search3, color: "#22c55e", label: "Query" },
|
|
9026
9453
|
queries: { icon: Search3, color: "#22c55e", label: "Query" },
|
|
9027
9454
|
channel: { icon: ArrowRightLeft3, color: "#6b7280", label: "Channel" },
|
|
9028
9455
|
channels: { icon: ArrowRightLeft3, color: "#6b7280", label: "Channel" },
|
|
9029
|
-
data: { icon:
|
|
9456
|
+
data: { icon: Database6, color: "#3b82f6", label: "Data" },
|
|
9030
9457
|
"data-products": { icon: Package2, color: "#6366f1", label: "Data Product" },
|
|
9031
9458
|
externalSystem: { icon: Globe5, color: "#ec4899", label: "External System" },
|
|
9032
|
-
actor: { icon:
|
|
9459
|
+
actor: { icon: User4, color: "#eab308", label: "Actor" },
|
|
9033
9460
|
view: { icon: MonitorIcon2, color: "#8b5cf6", label: "View" },
|
|
9034
9461
|
domain: { icon: BoxesIcon2, color: "#14b8a6", label: "Domain" },
|
|
9035
9462
|
domains: { icon: BoxesIcon2, color: "#14b8a6", label: "Domain" }
|
|
@@ -9931,7 +10358,7 @@ var NodeGraphBuilder = ({
|
|
|
9931
10358
|
);
|
|
9932
10359
|
const [nodes, setNodes, onNodesChange] = useNodesState2(initialNodes);
|
|
9933
10360
|
const [edges, setEdges, onEdgesChange] = useEdgesState2(initialEdges);
|
|
9934
|
-
const { fitView, getNodes } = useReactFlow5();
|
|
10361
|
+
const { fitView, getNodes, getIntersectingNodes, getZoom, setCenter } = useReactFlow5();
|
|
9935
10362
|
useEffect8(() => {
|
|
9936
10363
|
setNodes(initialNodes);
|
|
9937
10364
|
setEdges(initialEdges);
|
|
@@ -10071,57 +10498,107 @@ var NodeGraphBuilder = ({
|
|
|
10071
10498
|
wrapper.classList.add("ec-animating-layout");
|
|
10072
10499
|
setTimeout(() => wrapper.classList.remove("ec-animating-layout"), 400);
|
|
10073
10500
|
}, []);
|
|
10074
|
-
const relayoutGraph = useCallback12(
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
g.
|
|
10097
|
-
|
|
10098
|
-
});
|
|
10099
|
-
dagre3.layout(g);
|
|
10100
|
-
const positioned = nextNodes.map((node) => {
|
|
10101
|
-
if (node.parentId) {
|
|
10102
|
-
const parent = nextNodes.find((n) => n.id === node.parentId);
|
|
10103
|
-
if (parent?.type === "flowExpanded") {
|
|
10104
|
-
return node;
|
|
10501
|
+
const relayoutGraph = useCallback12(
|
|
10502
|
+
(nextNodes, nextEdges, anchor) => {
|
|
10503
|
+
const g = new dagre3.graphlib.Graph({ compound: true });
|
|
10504
|
+
g.setGraph({ rankdir: "LR", ranksep: 300, nodesep: 50 });
|
|
10505
|
+
g.setDefaultEdgeLabel(() => ({}));
|
|
10506
|
+
nextNodes.forEach((node) => {
|
|
10507
|
+
if (node.parentId) return;
|
|
10508
|
+
const w = node.style?.width || (node.type === "messageGroupExpanded" ? 380 : 150);
|
|
10509
|
+
const h = node.style?.height || (node.type === "messageGroupExpanded" ? 0 : 120);
|
|
10510
|
+
if (node.type === "messageGroupExpanded") {
|
|
10511
|
+
const children = nextNodes.filter((n) => n.parentId === node.id);
|
|
10512
|
+
const childHeight = children.length * 190 + 100;
|
|
10513
|
+
g.setNode(node.id, { width: w, height: childHeight });
|
|
10514
|
+
} else {
|
|
10515
|
+
g.setNode(node.id, { width: w, height: h });
|
|
10516
|
+
}
|
|
10517
|
+
});
|
|
10518
|
+
nextEdges.forEach((edge) => {
|
|
10519
|
+
const sourceNode = nextNodes.find((n) => n.id === edge.source);
|
|
10520
|
+
const targetNode = nextNodes.find((n) => n.id === edge.target);
|
|
10521
|
+
const sourceTop = sourceNode?.parentId || edge.source;
|
|
10522
|
+
const targetTop = targetNode?.parentId || edge.target;
|
|
10523
|
+
if (g.hasNode(sourceTop) && g.hasNode(targetTop) && sourceTop !== targetTop) {
|
|
10524
|
+
g.setEdge(sourceTop, targetTop);
|
|
10105
10525
|
}
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10526
|
+
});
|
|
10527
|
+
dagre3.layout(g);
|
|
10528
|
+
const positioned = nextNodes.map((node) => {
|
|
10529
|
+
if (node.parentId) {
|
|
10530
|
+
const parent = nextNodes.find((n) => n.id === node.parentId);
|
|
10531
|
+
if (parent?.type === "flowExpanded") {
|
|
10532
|
+
return node;
|
|
10533
|
+
}
|
|
10534
|
+
const parentWidth = parent?.style?.width || 380;
|
|
10535
|
+
const childWidth = 240;
|
|
10536
|
+
const xOffset = Math.max(20, (parentWidth - childWidth) / 2);
|
|
10537
|
+
const siblings = nextNodes.filter(
|
|
10538
|
+
(n) => n.parentId === node.parentId
|
|
10539
|
+
);
|
|
10540
|
+
const index = siblings.indexOf(node);
|
|
10541
|
+
return {
|
|
10542
|
+
...node,
|
|
10543
|
+
position: { x: xOffset, y: 70 + index * 190 }
|
|
10544
|
+
};
|
|
10545
|
+
}
|
|
10546
|
+
const pos = g.node(node.id);
|
|
10547
|
+
if (!pos) return node;
|
|
10111
10548
|
return {
|
|
10112
10549
|
...node,
|
|
10113
|
-
position: { x:
|
|
10550
|
+
position: { x: pos.x - pos.width / 2, y: pos.y - pos.height / 2 }
|
|
10114
10551
|
};
|
|
10115
|
-
}
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
return
|
|
10119
|
-
|
|
10120
|
-
|
|
10552
|
+
});
|
|
10553
|
+
if (!anchor) return positioned;
|
|
10554
|
+
const positionedAnchor = positioned.find((node) => node.id === anchor.id);
|
|
10555
|
+
if (!positionedAnchor) return positioned;
|
|
10556
|
+
const offset = {
|
|
10557
|
+
x: anchor.position.x - positionedAnchor.position.x,
|
|
10558
|
+
y: anchor.position.y - positionedAnchor.position.y
|
|
10121
10559
|
};
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10560
|
+
return positioned.map((node) => {
|
|
10561
|
+
if (node.parentId) return node;
|
|
10562
|
+
return {
|
|
10563
|
+
...node,
|
|
10564
|
+
position: {
|
|
10565
|
+
x: node.position.x + offset.x,
|
|
10566
|
+
y: node.position.y + offset.y
|
|
10567
|
+
}
|
|
10568
|
+
};
|
|
10569
|
+
});
|
|
10570
|
+
},
|
|
10571
|
+
[]
|
|
10572
|
+
);
|
|
10573
|
+
const makeRoomForRenderedExpandedGroup = useCallback12(
|
|
10574
|
+
(groupNodeId, groupBounds) => {
|
|
10575
|
+
const padding = 80;
|
|
10576
|
+
const protectedBounds = {
|
|
10577
|
+
x: groupBounds.x - padding,
|
|
10578
|
+
y: groupBounds.y - padding,
|
|
10579
|
+
width: groupBounds.width + padding * 2,
|
|
10580
|
+
height: groupBounds.height + padding * 2
|
|
10581
|
+
};
|
|
10582
|
+
const intersectingIds = new Set(
|
|
10583
|
+
getIntersectingNodes(protectedBounds, true).filter((node) => node.id !== groupNodeId && !node.parentId).map((node) => node.id)
|
|
10584
|
+
);
|
|
10585
|
+
if (intersectingIds.size === 0) return;
|
|
10586
|
+
setNodes((currentNodes) => {
|
|
10587
|
+
const plannedPositions = packNodesAroundBounds({
|
|
10588
|
+
nodes: currentNodes,
|
|
10589
|
+
movableNodeIds: intersectingIds,
|
|
10590
|
+
protectedBounds,
|
|
10591
|
+
groupNodeId
|
|
10592
|
+
});
|
|
10593
|
+
return currentNodes.map((node) => {
|
|
10594
|
+
const plannedPosition = plannedPositions.get(node.id);
|
|
10595
|
+
if (!plannedPosition) return node;
|
|
10596
|
+
return { ...node, position: plannedPosition };
|
|
10597
|
+
});
|
|
10598
|
+
});
|
|
10599
|
+
},
|
|
10600
|
+
[getIntersectingNodes, setNodes]
|
|
10601
|
+
);
|
|
10125
10602
|
const layoutSubFlowChildren = useCallback12(
|
|
10126
10603
|
(children, edges2, sizeOf, opts) => {
|
|
10127
10604
|
const { padding, headerH, fallbackW = 240, fallbackH = 120 } = opts;
|
|
@@ -10219,9 +10696,19 @@ var NodeGraphBuilder = ({
|
|
|
10219
10696
|
}
|
|
10220
10697
|
const without = prev.filter(
|
|
10221
10698
|
(n) => n.id !== groupNodeId && !childNodeIds.has(n.id) && !(downstreamNodeIds.has(n.id) && !referencedByEdges.has(n.id))
|
|
10222
|
-
)
|
|
10223
|
-
|
|
10224
|
-
|
|
10699
|
+
).map((n) => {
|
|
10700
|
+
const stashedPosition = stashed?.nodePositions?.[n.id];
|
|
10701
|
+
if (!stashedPosition || n.parentId) return n;
|
|
10702
|
+
return { ...n, position: stashedPosition };
|
|
10703
|
+
});
|
|
10704
|
+
const next = [
|
|
10705
|
+
...without,
|
|
10706
|
+
{
|
|
10707
|
+
...originalNode,
|
|
10708
|
+
position: stashed?.nodePositions?.[groupNodeId] ?? expandedNode.position
|
|
10709
|
+
}
|
|
10710
|
+
];
|
|
10711
|
+
return next;
|
|
10225
10712
|
});
|
|
10226
10713
|
setEdges((prev) => {
|
|
10227
10714
|
const without = prev.filter(
|
|
@@ -10229,9 +10716,6 @@ var NodeGraphBuilder = ({
|
|
|
10229
10716
|
);
|
|
10230
10717
|
return [...without, ...originalEdges];
|
|
10231
10718
|
});
|
|
10232
|
-
requestAnimationFrame(() => {
|
|
10233
|
-
fitView({ duration: 400, padding: 0.2 });
|
|
10234
|
-
});
|
|
10235
10719
|
},
|
|
10236
10720
|
[
|
|
10237
10721
|
initialNodes,
|
|
@@ -10239,8 +10723,7 @@ var NodeGraphBuilder = ({
|
|
|
10239
10723
|
setNodes,
|
|
10240
10724
|
setEdges,
|
|
10241
10725
|
relayoutGraph,
|
|
10242
|
-
animateLayout
|
|
10243
|
-
fitView
|
|
10726
|
+
animateLayout
|
|
10244
10727
|
]
|
|
10245
10728
|
);
|
|
10246
10729
|
useEffect8(() => {
|
|
@@ -10323,9 +10806,6 @@ var NodeGraphBuilder = ({
|
|
|
10323
10806
|
onNodeClick(node);
|
|
10324
10807
|
return;
|
|
10325
10808
|
}
|
|
10326
|
-
if (linksToVisualiser && onNavigate) {
|
|
10327
|
-
return;
|
|
10328
|
-
}
|
|
10329
10809
|
const isFlow = edgesRef.current.some(
|
|
10330
10810
|
(edge) => edge.type === "flow-edge"
|
|
10331
10811
|
);
|
|
@@ -10339,6 +10819,24 @@ var NodeGraphBuilder = ({
|
|
|
10339
10819
|
if (node.type === "messageGroup") {
|
|
10340
10820
|
const groupData = node.data;
|
|
10341
10821
|
const groupNodeId = node.id;
|
|
10822
|
+
const currentGroupNode = getExpandedMessageGroupNode(
|
|
10823
|
+
nodesRef.current,
|
|
10824
|
+
groupNodeId
|
|
10825
|
+
);
|
|
10826
|
+
if (currentGroupNode?.type === "messageGroupExpanded") {
|
|
10827
|
+
const measured = currentGroupNode?.measured;
|
|
10828
|
+
const width = measured?.width ?? currentGroupNode.style?.width ?? 380;
|
|
10829
|
+
const height = measured?.height ?? currentGroupNode.style?.height ?? 300;
|
|
10830
|
+
setCenter(
|
|
10831
|
+
currentGroupNode.position.x + width / 2,
|
|
10832
|
+
currentGroupNode.position.y + height / 2,
|
|
10833
|
+
{
|
|
10834
|
+
duration: 300,
|
|
10835
|
+
zoom: Math.min(Math.max(getZoom(), 0.55), 1)
|
|
10836
|
+
}
|
|
10837
|
+
);
|
|
10838
|
+
return;
|
|
10839
|
+
}
|
|
10342
10840
|
const serviceNodeId = `${groupData.service.id}-${groupData.service.version}`;
|
|
10343
10841
|
const childCount = groupData.messages?.length || 0;
|
|
10344
10842
|
const containerWidth = 380;
|
|
@@ -10347,6 +10845,9 @@ var NodeGraphBuilder = ({
|
|
|
10347
10845
|
(e) => e.source === groupNodeId || e.target === groupNodeId
|
|
10348
10846
|
);
|
|
10349
10847
|
const preExpansionNodeIds = nodesRef.current.map((n) => n.id);
|
|
10848
|
+
const preExpansionNodePositions = Object.fromEntries(
|
|
10849
|
+
nodesRef.current.map((n) => [n.id, { ...n.position }])
|
|
10850
|
+
);
|
|
10350
10851
|
const expandedContainerNode = {
|
|
10351
10852
|
id: groupNodeId,
|
|
10352
10853
|
type: "messageGroupExpanded",
|
|
@@ -10359,7 +10860,8 @@ var NodeGraphBuilder = ({
|
|
|
10359
10860
|
__preExpansion: {
|
|
10360
10861
|
node,
|
|
10361
10862
|
edges: preExpansionEdges,
|
|
10362
|
-
nodeIds: preExpansionNodeIds
|
|
10863
|
+
nodeIds: preExpansionNodeIds,
|
|
10864
|
+
nodePositions: preExpansionNodePositions
|
|
10363
10865
|
}
|
|
10364
10866
|
},
|
|
10365
10867
|
style: {
|
|
@@ -10420,24 +10922,19 @@ var NodeGraphBuilder = ({
|
|
|
10420
10922
|
});
|
|
10421
10923
|
animateLayout();
|
|
10422
10924
|
setNodes((prev) => {
|
|
10423
|
-
const
|
|
10424
|
-
const
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
const next = [
|
|
10429
|
-
...without,
|
|
10925
|
+
const downstreamX = groupData.direction === "sends" ? node.position.x + containerWidth + 260 : node.position.x - 420;
|
|
10926
|
+
const downstreamY = node.position.y + 40;
|
|
10927
|
+
return buildMessageGroupExpansionNodes({
|
|
10928
|
+
currentNodes: prev,
|
|
10929
|
+
groupNodeId,
|
|
10430
10930
|
expandedContainerNode,
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
...childEdges,
|
|
10439
|
-
...downstreamEdges
|
|
10440
|
-
]);
|
|
10931
|
+
childNodes,
|
|
10932
|
+
downstreamNodes,
|
|
10933
|
+
getDownstreamPosition: (_downstreamNode, index) => ({
|
|
10934
|
+
x: downstreamX,
|
|
10935
|
+
y: downstreamY + index * 190
|
|
10936
|
+
})
|
|
10937
|
+
});
|
|
10441
10938
|
});
|
|
10442
10939
|
setEdges((prev) => {
|
|
10443
10940
|
const without = prev.filter(
|
|
@@ -10446,6 +10943,12 @@ var NodeGraphBuilder = ({
|
|
|
10446
10943
|
return [...without, ...childEdges, ...downstreamEdges];
|
|
10447
10944
|
});
|
|
10448
10945
|
requestAnimationFrame(() => {
|
|
10946
|
+
let actualContainerBounds = {
|
|
10947
|
+
x: node.position.x,
|
|
10948
|
+
y: node.position.y,
|
|
10949
|
+
width: containerWidth,
|
|
10950
|
+
height: containerHeight
|
|
10951
|
+
};
|
|
10449
10952
|
setNodes((prev) => {
|
|
10450
10953
|
const children = prev.filter((n) => n.parentId === groupNodeId);
|
|
10451
10954
|
if (children.length === 0) return prev;
|
|
@@ -10465,8 +10968,20 @@ var NodeGraphBuilder = ({
|
|
|
10465
10968
|
const totalChildH = measurements.reduce((sum, m) => sum + m.h, 0) + gap * (measurements.length - 1);
|
|
10466
10969
|
const actualContainerH = headerH + totalChildH + padding * 2;
|
|
10467
10970
|
let currentY = headerH + padding;
|
|
10971
|
+
actualContainerBounds = {
|
|
10972
|
+
x: node.position.x,
|
|
10973
|
+
y: node.position.y,
|
|
10974
|
+
width: containerWidth,
|
|
10975
|
+
height: actualContainerH
|
|
10976
|
+
};
|
|
10468
10977
|
return prev.map((n) => {
|
|
10469
10978
|
if (n.id === groupNodeId) {
|
|
10979
|
+
actualContainerBounds = {
|
|
10980
|
+
x: n.position.x,
|
|
10981
|
+
y: n.position.y,
|
|
10982
|
+
width: containerWidth,
|
|
10983
|
+
height: actualContainerH
|
|
10984
|
+
};
|
|
10470
10985
|
return {
|
|
10471
10986
|
...n,
|
|
10472
10987
|
style: {
|
|
@@ -10484,9 +10999,23 @@ var NodeGraphBuilder = ({
|
|
|
10484
10999
|
return { ...n, position: { x, y } };
|
|
10485
11000
|
});
|
|
10486
11001
|
});
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
11002
|
+
requestAnimationFrame(() => {
|
|
11003
|
+
const groupNode = getNodes().find((n) => n.id === groupNodeId);
|
|
11004
|
+
const measured = groupNode?.measured;
|
|
11005
|
+
const width = measured?.width ?? groupNode?.style?.width ?? containerWidth;
|
|
11006
|
+
const height = measured?.height ?? groupNode?.style?.height ?? actualContainerBounds.height;
|
|
11007
|
+
const bounds = {
|
|
11008
|
+
x: groupNode?.position.x ?? actualContainerBounds.x,
|
|
11009
|
+
y: groupNode?.position.y ?? actualContainerBounds.y,
|
|
11010
|
+
width,
|
|
11011
|
+
height
|
|
11012
|
+
};
|
|
11013
|
+
makeRoomForRenderedExpandedGroup(groupNodeId, bounds);
|
|
11014
|
+
setCenter(bounds.x + width / 2, bounds.y + height / 2, {
|
|
11015
|
+
duration: 450,
|
|
11016
|
+
zoom: Math.min(Math.max(getZoom(), 0.55), 1)
|
|
11017
|
+
});
|
|
11018
|
+
});
|
|
10490
11019
|
});
|
|
10491
11020
|
return;
|
|
10492
11021
|
}
|
|
@@ -10651,10 +11180,21 @@ var NodeGraphBuilder = ({
|
|
|
10651
11180
|
});
|
|
10652
11181
|
return;
|
|
10653
11182
|
}
|
|
11183
|
+
if (linksToVisualiser && onNavigate) {
|
|
11184
|
+
return;
|
|
11185
|
+
}
|
|
10654
11186
|
setFocusedNodeId(node.id);
|
|
10655
11187
|
setFocusModeOpen(true);
|
|
10656
11188
|
},
|
|
10657
|
-
[
|
|
11189
|
+
[
|
|
11190
|
+
onNodeClick,
|
|
11191
|
+
linksToVisualiser,
|
|
11192
|
+
onNavigate,
|
|
11193
|
+
makeRoomForRenderedExpandedGroup,
|
|
11194
|
+
getNodes,
|
|
11195
|
+
getZoom,
|
|
11196
|
+
setCenter
|
|
11197
|
+
]
|
|
10658
11198
|
);
|
|
10659
11199
|
const toggleAnimateMessages = useCallback12(() => {
|
|
10660
11200
|
setAnimateMessages((prev) => {
|
|
@@ -10884,13 +11424,15 @@ var NodeGraphBuilder = ({
|
|
|
10884
11424
|
}, [getNodes, downloadImage, title]);
|
|
10885
11425
|
const handleLegendClick = useCallback12(
|
|
10886
11426
|
(collectionType, groupId) => {
|
|
11427
|
+
const isLegendTarget = (node) => {
|
|
11428
|
+
if (groupId) {
|
|
11429
|
+
return node.data.group && node.data.group?.id === groupId;
|
|
11430
|
+
}
|
|
11431
|
+
return node.type === collectionType;
|
|
11432
|
+
};
|
|
10887
11433
|
const updatedNodes = nodes.map((node) => {
|
|
10888
|
-
if (
|
|
11434
|
+
if (isLegendTarget(node)) {
|
|
10889
11435
|
return { ...node, style: { ...node.style, opacity: 1 } };
|
|
10890
|
-
} else {
|
|
10891
|
-
if (node.type === collectionType) {
|
|
10892
|
-
return { ...node, style: { ...node.style, opacity: 1 } };
|
|
10893
|
-
}
|
|
10894
11436
|
}
|
|
10895
11437
|
return { ...node, style: { ...node.style, opacity: 0.1 } };
|
|
10896
11438
|
});
|
|
@@ -10905,10 +11447,12 @@ var NodeGraphBuilder = ({
|
|
|
10905
11447
|
});
|
|
10906
11448
|
setNodes(updatedNodes);
|
|
10907
11449
|
setEdges(updatedEdges);
|
|
11450
|
+
const targetNodes = updatedNodes.filter(isLegendTarget);
|
|
11451
|
+
if (targetNodes.length === 0) return;
|
|
10908
11452
|
fitView({
|
|
10909
11453
|
padding: 0.2,
|
|
10910
11454
|
duration: 800,
|
|
10911
|
-
nodes:
|
|
11455
|
+
nodes: targetNodes
|
|
10912
11456
|
});
|
|
10913
11457
|
},
|
|
10914
11458
|
[nodes, edges, setNodes, setEdges, fitView]
|