@eventcatalog/core 3.12.7 → 3.12.9-beta.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.
Files changed (64) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-RZOSO7BH.js → chunk-2UUS3AQ2.js} +1 -1
  6. package/dist/{chunk-UFF5Q7GJ.js → chunk-EDX2LGRV.js} +1 -1
  7. package/dist/{chunk-2EFYBMLH.js → chunk-RJOB6XEC.js} +1 -1
  8. package/dist/{chunk-YO6IQXB3.js → chunk-V7YMKA4P.js} +1 -1
  9. package/dist/{chunk-PLQAZDJI.js → chunk-WTCJKTEF.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +5 -5
  14. package/dist/generate.cjs +1 -1
  15. package/dist/generate.js +3 -3
  16. package/dist/utils/cli-logger.cjs +1 -1
  17. package/dist/utils/cli-logger.js +2 -2
  18. package/eventcatalog/src/components/MDX/Design/Design.astro +2 -2
  19. package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -2
  20. package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -2
  21. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +104 -0
  22. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +2 -2
  23. package/eventcatalog/src/components/MDX/NodeGraph/README.md +85 -0
  24. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -2
  25. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +66 -17
  26. package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +14 -5
  27. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +1 -1
  28. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +133 -18
  29. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +36 -14
  30. package/eventcatalog/src/utils/node-graphs/utils/utils.ts +115 -4
  31. package/package.json +4 -4
  32. package/eventcatalog/src/components/MDX/NodeGraph/DownloadButton.tsx +0 -62
  33. package/eventcatalog/src/components/MDX/NodeGraph/Edges/AnimatedMessageEdge.tsx +0 -110
  34. package/eventcatalog/src/components/MDX/NodeGraph/Edges/FlowEdge.tsx +0 -96
  35. package/eventcatalog/src/components/MDX/NodeGraph/Edges/MultilineEdgeLabel.tsx +0 -52
  36. package/eventcatalog/src/components/MDX/NodeGraph/FocusMode/FocusModeContent.tsx +0 -294
  37. package/eventcatalog/src/components/MDX/NodeGraph/FocusMode/FocusModeNodeActions.tsx +0 -92
  38. package/eventcatalog/src/components/MDX/NodeGraph/FocusMode/FocusModePlaceholder.tsx +0 -26
  39. package/eventcatalog/src/components/MDX/NodeGraph/FocusMode/utils.ts +0 -163
  40. package/eventcatalog/src/components/MDX/NodeGraph/FocusModeModal.tsx +0 -99
  41. package/eventcatalog/src/components/MDX/NodeGraph/MermaidView.tsx +0 -242
  42. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +0 -1181
  43. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Actor.tsx +0 -46
  44. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Channel.tsx +0 -55
  45. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Command.tsx +0 -27
  46. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Custom.tsx +0 -159
  47. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Data.tsx +0 -63
  48. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/DataProduct.tsx +0 -132
  49. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Domain.tsx +0 -155
  50. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Entity.tsx +0 -154
  51. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Event.tsx +0 -29
  52. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/ExternalSystem.tsx +0 -79
  53. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/ExternalSystem2.tsx +0 -24
  54. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Flow.tsx +0 -107
  55. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/MessageContextMenu.tsx +0 -63
  56. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Query.tsx +0 -28
  57. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Service.tsx +0 -127
  58. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Step.tsx +0 -64
  59. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/User.tsx +0 -76
  60. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/View.tsx +0 -24
  61. package/eventcatalog/src/components/MDX/NodeGraph/StepWalkthrough.tsx +0 -296
  62. package/eventcatalog/src/components/MDX/NodeGraph/StudioModal.tsx +0 -129
  63. package/eventcatalog/src/components/MDX/NodeGraph/VisualiserSearch.tsx +0 -258
  64. package/eventcatalog/src/components/MDX/NodeGraph/VisualizerDropdownContent.tsx +0 -313
@@ -94,7 +94,7 @@ export const getNodesAndEdgesForDomainContextMap = async ({ defaultFlow = null }
94
94
  data: { label: `Bounded Context: ${domain.data.name}` },
95
95
  position: { x: 0, y: 0 },
96
96
  style: {
97
- height: 40,
97
+ height: 20,
98
98
  backgroundColor: 'transparent',
99
99
  border: 'none',
100
100
  color: 'black',
@@ -23,7 +23,7 @@ import {
23
23
  import type { CollectionMessageTypes } from '@types';
24
24
  import { getCommands } from '@utils/collections/commands';
25
25
  import { getQueries } from '@utils/collections/queries';
26
- import { createNode } from './utils/utils';
26
+ import { createNode, buildContextMenuForMessage, buildContextMenuForService, buildContextMenuForResource } from './utils/utils';
27
27
  import { getConsumersOfMessage, getProducersOfMessage } from '@utils/collections/services';
28
28
  import { getNodesAndEdgesForChannelChain } from './channel-node-graph';
29
29
  import { getChannelChain, isChannelsConnected } from '@utils/collections/channels';
@@ -79,6 +79,13 @@ const getNodesAndEdges = async ({
79
79
  message: {
80
80
  ...message.data,
81
81
  },
82
+ contextMenu: buildContextMenuForMessage({
83
+ id: message.data.id,
84
+ version: message.data.version,
85
+ name: message.data.name,
86
+ collection: message.collection,
87
+ schemaPath: (message.data as any).schemaPath,
88
+ }),
82
89
  },
83
90
  position: { x: 0, y: 0 },
84
91
  type: message.collection,
@@ -96,12 +103,23 @@ const getNodesAndEdges = async ({
96
103
  const isDataProduct = producer.collection === 'data-products';
97
104
 
98
105
  // Create the producer node with appropriate data structure
106
+ const producerContextMenu = isDataProduct
107
+ ? buildContextMenuForResource({ collection: 'data-products', id: producer.data.id, version: producer.data.version })
108
+ : buildContextMenuForService({
109
+ id: producer.data.id,
110
+ version: producer.data.version,
111
+ specifications: (producer.data as any).specifications,
112
+ repository: (producer.data as any).repository,
113
+ });
114
+
99
115
  nodes.push({
100
116
  id: generateIdForNode(producer),
101
117
  type: isDataProduct ? 'data-products' : producer?.collection,
102
118
  sourcePosition: 'right',
103
119
  targetPosition: 'left',
104
- data: isDataProduct ? { mode, dataProduct: { ...producer.data } } : { mode, service: { ...producer.data } },
120
+ data: isDataProduct
121
+ ? { mode, dataProduct: { ...producer.data }, contextMenu: producerContextMenu }
122
+ : { mode, service: { ...producer.data }, contextMenu: producerContextMenu },
105
123
  position: { x: 250, y: 0 },
106
124
  });
107
125
 
@@ -121,8 +139,8 @@ const getNodesAndEdges = async ({
121
139
  animated: false,
122
140
  markerEnd: {
123
141
  type: MarkerType.ArrowClosed,
124
- width: 40,
125
- height: 40,
142
+ width: 20,
143
+ height: 20,
126
144
  },
127
145
  });
128
146
  continue;
@@ -153,8 +171,8 @@ const getNodesAndEdges = async ({
153
171
  animated: false,
154
172
  markerEnd: {
155
173
  type: MarkerType.ArrowClosed,
156
- width: 40,
157
- height: 40,
174
+ width: 20,
175
+ height: 20,
158
176
  },
159
177
  });
160
178
  continue;
@@ -183,7 +201,15 @@ const getNodesAndEdges = async ({
183
201
  createNode({
184
202
  id: generateIdForNode(channel),
185
203
  type: channel.collection,
186
- data: { mode, channel: { ...channel.data } },
204
+ data: {
205
+ mode,
206
+ channel: { ...channel.data },
207
+ contextMenu: buildContextMenuForResource({
208
+ collection: 'channels',
209
+ id: channel.data.id,
210
+ version: channel.data.version,
211
+ }),
212
+ },
187
213
  position: { x: 0, y: 0 },
188
214
  })
189
215
  );
@@ -217,13 +243,22 @@ const getNodesAndEdges = async ({
217
243
  const isDataProduct = consumer.collection === 'data-products';
218
244
 
219
245
  // Render the consumer node with appropriate data structure
246
+ const consumerContextMenu = isDataProduct
247
+ ? buildContextMenuForResource({ collection: 'data-products', id: consumer.data.id, version: consumer.data.version })
248
+ : buildContextMenuForService({
249
+ id: consumer.data.id,
250
+ version: consumer.data.version,
251
+ specifications: (consumer.data as any).specifications,
252
+ repository: (consumer.data as any).repository,
253
+ });
254
+
220
255
  nodes.push({
221
256
  id: generateIdForNode(consumer),
222
257
  sourcePosition: 'right',
223
258
  targetPosition: 'left',
224
259
  data: isDataProduct
225
- ? { title: consumer?.data.id, mode, dataProduct: { ...consumer.data } }
226
- : { title: consumer?.data.id, mode, service: { ...consumer.data } },
260
+ ? { title: consumer?.data.id, mode, dataProduct: { ...consumer.data }, contextMenu: consumerContextMenu }
261
+ : { title: consumer?.data.id, mode, service: { ...consumer.data }, contextMenu: consumerContextMenu },
227
262
  position: { x: 0, y: 0 },
228
263
  type: isDataProduct ? 'data-products' : consumer?.collection,
229
264
  });
@@ -496,7 +531,17 @@ export const getNodesAndEdgesForConsumedMessage = ({
496
531
  createNode({
497
532
  id: messageId,
498
533
  type: message.collection,
499
- data: { mode, message: { ...message.data } },
534
+ data: {
535
+ mode,
536
+ message: { ...message.data },
537
+ contextMenu: buildContextMenuForMessage({
538
+ id: message.data.id,
539
+ version: message.data.version,
540
+ name: message.data.name,
541
+ collection: message.collection,
542
+ schemaPath: (message.data as any).schemaPath,
543
+ }),
544
+ },
500
545
  position: { x: 0, y: 0 },
501
546
  })
502
547
  );
@@ -506,7 +551,16 @@ export const getNodesAndEdgesForConsumedMessage = ({
506
551
  createNode({
507
552
  id: generateIdForNode(target),
508
553
  type: target.collection,
509
- data: { mode, service: { ...target.data } },
554
+ data: {
555
+ mode,
556
+ service: { ...target.data },
557
+ contextMenu: buildContextMenuForService({
558
+ id: target.data.id,
559
+ version: target.data.version,
560
+ specifications: target.data.specifications as { type: string; path: string }[],
561
+ repository: target.data.repository as { url: string },
562
+ }),
563
+ },
510
564
  position: { x: 0, y: 0 },
511
565
  })
512
566
  );
@@ -562,7 +616,15 @@ export const getNodesAndEdgesForConsumedMessage = ({
562
616
  createNode({
563
617
  id: channelId,
564
618
  type: channel.collection,
565
- data: { mode, channel: { ...channel.data, ...channel, id: channel.data.id } },
619
+ data: {
620
+ mode,
621
+ channel: { ...channel.data, ...channel, id: channel.data.id },
622
+ contextMenu: buildContextMenuForResource({
623
+ collection: 'channels',
624
+ id: channel.data.id,
625
+ version: channel.data.version,
626
+ }),
627
+ },
566
628
  position: { x: 0, y: 0 },
567
629
  })
568
630
  );
@@ -602,7 +664,16 @@ export const getNodesAndEdgesForConsumedMessage = ({
602
664
  createNode({
603
665
  id: producerId,
604
666
  type: producer.collection,
605
- data: { mode, service: { ...producer.data } },
667
+ data: {
668
+ mode,
669
+ service: { ...producer.data },
670
+ contextMenu: buildContextMenuForService({
671
+ id: producer.data.id,
672
+ version: producer.data.version,
673
+ specifications: producer.data.specifications as { type: string; path: string }[],
674
+ repository: producer.data.repository as { url: string },
675
+ }),
676
+ },
606
677
  position: { x: 0, y: 0 },
607
678
  })
608
679
  );
@@ -803,7 +874,17 @@ export const getNodesAndEdgesForProducedMessage = ({
803
874
  createNode({
804
875
  id: messageId,
805
876
  type: message.collection,
806
- data: { mode, message: { ...message.data } },
877
+ data: {
878
+ mode,
879
+ message: { ...message.data },
880
+ contextMenu: buildContextMenuForMessage({
881
+ id: message.data.id,
882
+ version: message.data.version,
883
+ name: message.data.name,
884
+ collection: message.collection,
885
+ schemaPath: (message.data as any).schemaPath,
886
+ }),
887
+ },
807
888
  position: { x: 0, y: 0 },
808
889
  })
809
890
  );
@@ -813,7 +894,16 @@ export const getNodesAndEdgesForProducedMessage = ({
813
894
  createNode({
814
895
  id: generateIdForNode(source),
815
896
  type: source.collection,
816
- data: { mode, service: { ...source.data } },
897
+ data: {
898
+ mode,
899
+ service: { ...source.data },
900
+ contextMenu: buildContextMenuForService({
901
+ id: source.data.id,
902
+ version: source.data.version,
903
+ specifications: source.data.specifications as { type: string; path: string }[],
904
+ repository: source.data.repository as { url: string },
905
+ }),
906
+ },
817
907
  position: { x: 0, y: 0 },
818
908
  })
819
909
  );
@@ -862,7 +952,15 @@ export const getNodesAndEdgesForProducedMessage = ({
862
952
  createNode({
863
953
  id: channelId,
864
954
  type: channel.collection,
865
- data: { mode, channel: { ...channel.data, ...channel, mode, id: channel.data.id } },
955
+ data: {
956
+ mode,
957
+ channel: { ...channel.data, ...channel, mode, id: channel.data.id },
958
+ contextMenu: buildContextMenuForResource({
959
+ collection: 'channels',
960
+ id: channel.data.id,
961
+ version: channel.data.version,
962
+ }),
963
+ },
866
964
  position: { x: 0, y: 0 },
867
965
  })
868
966
  );
@@ -897,7 +995,16 @@ export const getNodesAndEdgesForProducedMessage = ({
897
995
  createNode({
898
996
  id: consumerId,
899
997
  type: consumer.collection,
900
- data: { mode, service: { ...consumer.data } },
998
+ data: {
999
+ mode,
1000
+ service: { ...consumer.data },
1001
+ contextMenu: buildContextMenuForService({
1002
+ id: consumer.data.id,
1003
+ version: consumer.data.version,
1004
+ specifications: consumer.data.specifications as { type: string; path: string }[],
1005
+ repository: consumer.data.repository as { url: string },
1006
+ }),
1007
+ },
901
1008
  position: { x: 0, y: 0 },
902
1009
  })
903
1010
  );
@@ -950,7 +1057,15 @@ export const getNodesAndEdgesForProducedMessage = ({
950
1057
  createNode({
951
1058
  id: generateIdForNode(channel),
952
1059
  type: channel.collection,
953
- data: { mode, channel: { ...channel.data, ...channel } },
1060
+ data: {
1061
+ mode,
1062
+ channel: { ...channel.data, ...channel },
1063
+ contextMenu: buildContextMenuForResource({
1064
+ collection: 'channels',
1065
+ id: channel.data.id,
1066
+ version: channel.data.version,
1067
+ }),
1068
+ },
954
1069
  position: { x: 0, y: 0 },
955
1070
  })
956
1071
  );
@@ -6,6 +6,8 @@ import {
6
6
  generatedIdForEdge,
7
7
  calculatedNodes,
8
8
  createEdge,
9
+ buildContextMenuForService,
10
+ buildContextMenuForResource,
9
11
  } from '@utils/node-graphs/utils/utils';
10
12
 
11
13
  import { findMatchingNodes, findInMap, createVersionedMap } from '@utils/collections/util';
@@ -145,8 +147,16 @@ export const getNodesAndEdges = async ({
145
147
  id: generateIdForNode(service),
146
148
  sourcePosition: 'right',
147
149
  targetPosition: 'left',
148
- // data: { mode, service: { ...service, ...service.data } },
149
- data: { mode, service: { ...service.data } },
150
+ data: {
151
+ mode,
152
+ service: { ...service.data },
153
+ contextMenu: buildContextMenuForService({
154
+ id: service.data.id,
155
+ version: service.data.version,
156
+ specifications: service.data.specifications as { type: string; path: string }[],
157
+ repository: service.data.repository as { url: string },
158
+ }),
159
+ },
150
160
  type: service.collection,
151
161
  });
152
162
 
@@ -156,7 +166,11 @@ export const getNodesAndEdges = async ({
156
166
  id: generateIdForNode(writeTo),
157
167
  sourcePosition: 'right',
158
168
  targetPosition: 'left',
159
- data: { mode, data: { ...writeTo.data } },
169
+ data: {
170
+ mode,
171
+ data: { ...writeTo.data },
172
+ contextMenu: buildContextMenuForResource({ collection: 'entities', id: writeTo.data.id, version: writeTo.data.version }),
173
+ },
160
174
  type: 'data',
161
175
  });
162
176
 
@@ -172,8 +186,8 @@ export const getNodesAndEdges = async ({
172
186
  markerEnd: {
173
187
  type: MarkerType.ArrowClosed,
174
188
  color: '#666',
175
- width: 40,
176
- height: 40,
189
+ width: 20,
190
+ height: 20,
177
191
  },
178
192
  })
179
193
  );
@@ -186,7 +200,15 @@ export const getNodesAndEdges = async ({
186
200
  id: generateIdForNode(readFrom),
187
201
  sourcePosition: 'right',
188
202
  targetPosition: 'left',
189
- data: { mode, data: { ...readFrom.data } },
203
+ data: {
204
+ mode,
205
+ data: { ...readFrom.data },
206
+ contextMenu: buildContextMenuForResource({
207
+ collection: 'entities',
208
+ id: readFrom.data.id,
209
+ version: readFrom.data.version,
210
+ }),
211
+ },
190
212
  type: 'data',
191
213
  });
192
214
 
@@ -202,8 +224,8 @@ export const getNodesAndEdges = async ({
202
224
  markerStart: {
203
225
  type: MarkerType.ArrowClosed,
204
226
  color: '#666',
205
- width: 40,
206
- height: 40,
227
+ width: 20,
228
+ height: 20,
207
229
  },
208
230
  markerEnd: undefined,
209
231
  })
@@ -243,8 +265,8 @@ export const getNodesAndEdges = async ({
243
265
  data: { message: { ...message.data } },
244
266
  markerEnd: {
245
267
  type: MarkerType.ArrowClosed,
246
- width: 40,
247
- height: 40,
268
+ width: 20,
269
+ height: 20,
248
270
  },
249
271
  style: {
250
272
  strokeWidth: 1,
@@ -265,14 +287,14 @@ export const getNodesAndEdges = async ({
265
287
  markerStart: {
266
288
  type: MarkerType.ArrowClosed,
267
289
  color: '#666',
268
- width: 40,
269
- height: 40,
290
+ width: 20,
291
+ height: 20,
270
292
  },
271
293
  markerEnd: {
272
294
  type: MarkerType.ArrowClosed,
273
295
  color: '#666',
274
- width: 40,
275
- height: 40,
296
+ width: 20,
297
+ height: 20,
276
298
  },
277
299
  });
278
300
  });
@@ -3,6 +3,7 @@
3
3
  import { MarkerType, Position, type Edge, type Node } from '@xyflow/react';
4
4
  import dagre from 'dagre';
5
5
  import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
6
+ import { buildUrl } from '@utils/url-builder';
6
7
  interface BaseCollectionData {
7
8
  id: string;
8
9
  version: string;
@@ -93,13 +94,13 @@ export const createEdge = (edgeOptions: Edge) => {
93
94
  animated: false,
94
95
  // markerStart: {
95
96
  // type: MarkerType.Arrow,
96
- // width: 40,
97
- // height: 40,
97
+ // width: 20,
98
+ // height: 20,
98
99
  // },
99
100
  markerEnd: {
100
101
  type: MarkerType.ArrowClosed,
101
- width: 40,
102
- height: 40,
102
+ width: 20,
103
+ height: 20,
103
104
  },
104
105
  style: {
105
106
  strokeWidth: 1,
@@ -118,6 +119,116 @@ export const createNode = (values: Node): Node => {
118
119
 
119
120
  type DagreGraph = any;
120
121
 
122
+ type ContextMenuItem = {
123
+ label: string;
124
+ href: string;
125
+ download?: string;
126
+ external?: boolean;
127
+ separator?: boolean;
128
+ };
129
+
130
+ export const buildContextMenuForMessage = ({
131
+ id,
132
+ version,
133
+ name,
134
+ collection,
135
+ schemaPath,
136
+ }: {
137
+ id: string;
138
+ version: string;
139
+ name: string;
140
+ collection: string;
141
+ schemaPath?: string;
142
+ }): ContextMenuItem[] => {
143
+ const items: ContextMenuItem[] = [{ label: 'Read documentation', href: buildUrl(`/docs/${collection}/${id}/${version}`) }];
144
+
145
+ if (schemaPath) {
146
+ items.push({
147
+ label: 'Download schema',
148
+ href: buildUrl(`/generated/${collection}/${id}/${schemaPath}`, true),
149
+ download: `${name}(${version})-${schemaPath}`,
150
+ external: true,
151
+ separator: true,
152
+ });
153
+ }
154
+
155
+ items.push({
156
+ label: 'Read changelog',
157
+ href: buildUrl(`/docs/${collection}/${id}/${version}/changelog`),
158
+ external: true,
159
+ separator: !schemaPath,
160
+ });
161
+
162
+ return items;
163
+ };
164
+
165
+ export const buildContextMenuForService = ({
166
+ id,
167
+ version,
168
+ specifications,
169
+ repository,
170
+ }: {
171
+ id: string;
172
+ version: string;
173
+ specifications?: { type: string; path: string }[];
174
+ repository?: { url: string };
175
+ }): ContextMenuItem[] => {
176
+ const items: ContextMenuItem[] = [{ label: 'Read documentation', href: buildUrl(`/docs/services/${id}/${version}`) }];
177
+
178
+ if (specifications && Array.isArray(specifications)) {
179
+ for (const spec of specifications) {
180
+ const specType = spec.type?.toLowerCase() || '';
181
+ let label = 'View specification';
182
+ if (specType.includes('asyncapi')) label = 'View AsyncAPI spec';
183
+ else if (specType.includes('openapi')) label = 'View OpenAPI spec';
184
+
185
+ items.push({
186
+ label,
187
+ href: buildUrl(`/docs/services/${id}/${version}/spec/${spec.type}`),
188
+ separator: items.length === 1,
189
+ });
190
+ }
191
+ }
192
+
193
+ if (repository?.url) {
194
+ items.push({
195
+ label: 'View code repository',
196
+ href: repository.url,
197
+ external: true,
198
+ separator: true,
199
+ });
200
+ }
201
+
202
+ items.push({
203
+ label: 'Read changelog',
204
+ href: buildUrl(`/docs/services/${id}/${version}/changelog`),
205
+ external: true,
206
+ separator: !repository?.url && (!specifications || specifications.length === 0),
207
+ });
208
+
209
+ return items;
210
+ };
211
+
212
+ export const buildContextMenuForResource = ({
213
+ collection,
214
+ id,
215
+ version,
216
+ }: {
217
+ collection: string;
218
+ id: string;
219
+ version: string;
220
+ }): ContextMenuItem[] => {
221
+ return [
222
+ { label: 'Read documentation', href: buildUrl(`/docs/${collection}/${id}/${version}`) },
223
+ {
224
+ label: 'Read changelog',
225
+ href: buildUrl(`/docs/${collection}/${id}/${version}/changelog`),
226
+ external: true,
227
+ separator: true,
228
+ },
229
+ ];
230
+ };
231
+
121
232
  export const getNodesAndEdgesFromDagre = ({
122
233
  nodes,
123
234
  edges,
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "3.12.7",
9
+ "version": "3.12.9-beta.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -32,7 +32,6 @@
32
32
  "@asyncapi/react-component": "2.4.3",
33
33
  "@auth/core": "^0.37.4",
34
34
  "@eventcatalog/license": "^0.0.7",
35
- "@eventcatalog/visualizer": "^0.0.6",
36
35
  "@fontsource/inter": "^5.2.5",
37
36
  "@headlessui/react": "^2.0.3",
38
37
  "@heroicons/react": "^2.1.3",
@@ -102,8 +101,9 @@
102
101
  "update-notifier": "^7.3.1",
103
102
  "uuid": "^10.0.0",
104
103
  "zod": "^3.25.0",
105
- "@eventcatalog/linter": "1.0.2",
106
- "@eventcatalog/sdk": "2.13.1"
104
+ "@eventcatalog/linter": "1.0.3",
105
+ "@eventcatalog/visualiser": "^0.0.2-beta.0",
106
+ "@eventcatalog/sdk": "2.13.2"
107
107
  },
108
108
  "devDependencies": {
109
109
  "@astrojs/check": "^0.9.6",
@@ -1,62 +0,0 @@
1
- import { Panel, useReactFlow, getNodesBounds, getViewportForBounds } from '@xyflow/react';
2
- import { toPng } from 'html-to-image';
3
- import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
4
-
5
- function downloadImage(dataUrl: string, filename?: string) {
6
- const a = document.createElement('a');
7
-
8
- a.setAttribute('download', `${filename || 'eventcatalog'}.png`);
9
- a.setAttribute('href', dataUrl);
10
- a.click();
11
- }
12
-
13
- const imageWidth = 1024;
14
- const imageHeight = 768;
15
-
16
- function DownloadButton({ filename, addPadding = true }: { filename?: string; addPadding?: boolean }) {
17
- const { getNodes } = useReactFlow();
18
- const onClick = () => {
19
- const nodesBounds = getNodesBounds(getNodes());
20
- const width = imageWidth > nodesBounds.width ? imageWidth : nodesBounds.width;
21
- const height = imageHeight > nodesBounds.height ? imageHeight : nodesBounds.height;
22
- const viewport = getViewportForBounds(nodesBounds, width, height, 0.5, 2, 0);
23
-
24
- // Hide the button
25
- // @ts-ignore
26
- document.getElementById('download-visual').style.display = 'none';
27
- // @ts-ignore
28
- document.querySelector('.react-flow__controls').style.display = 'none';
29
-
30
- // @ts-ignore
31
- toPng(document.querySelector('.react-flow__viewport'), {
32
- backgroundColor: '#f1f1f1',
33
- width,
34
- height,
35
- style: {
36
- width,
37
- height,
38
- transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`,
39
- },
40
- }).then((dataUrl: string) => {
41
- downloadImage(dataUrl, filename);
42
- // @ts-ignore
43
- document.getElementById('download-visual').style.display = 'block';
44
- // @ts-ignore
45
- document.querySelector('.react-flow__controls').style.display = 'block';
46
- });
47
- };
48
-
49
- return (
50
- <div id="download-visual">
51
- <button
52
- className={`hidden md:flex bg-white group download-btn items-center space-x-1 text-[14px] border border-gray-200 px-1 py-0.5 rounded-md hover:bg-gray-100/50 ${addPadding ? 'mt-14' : '-mt-1'}`}
53
- onClick={onClick}
54
- >
55
- <DocumentArrowDownIcon className="w-4 h-4 group-hover:text-primary" />
56
- <span className="group-hover:text-primary">Export visual </span>
57
- </button>
58
- </div>
59
- );
60
- }
61
-
62
- export default DownloadButton;