@eventcatalog/core 2.54.8 → 2.55.1

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 (58) 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 +4 -4
  5. package/dist/catalog-to-astro-content-directory.cjs +1 -1
  6. package/dist/catalog-to-astro-content-directory.js +3 -3
  7. package/dist/{chunk-BLDONK5J.js → chunk-2C7LRK2M.js} +3 -3
  8. package/dist/{chunk-YEQVKHST.js → chunk-3W6JYTHP.js} +2 -2
  9. package/dist/{chunk-LDBRNJIL.js → chunk-55D645EH.js} +1 -1
  10. package/dist/{chunk-LK5JF3WD.js → chunk-D4MIDRVV.js} +2 -2
  11. package/dist/{chunk-MCSZBCOG.js → chunk-I23A46WZ.js} +3 -3
  12. package/dist/{chunk-XE6PFSH5.js → chunk-PLNJC7NZ.js} +2 -2
  13. package/dist/{chunk-ERICNBX2.js → chunk-Q3RTITUV.js} +1 -1
  14. package/dist/{chunk-IZMM7ZGY.js → chunk-R2BJ7MJG.js} +4 -4
  15. package/dist/{chunk-ZVJRM3VC.js → chunk-SKPKGCT7.js} +1 -1
  16. package/dist/{chunk-E7TXTI7G.js → chunk-UPONRQSN.js} +4 -4
  17. package/dist/constants.cjs +1 -1
  18. package/dist/constants.js +1 -1
  19. package/dist/eventcatalog-config-file-utils.js +1 -1
  20. package/dist/eventcatalog.cjs +2 -2
  21. package/dist/eventcatalog.js +14 -14
  22. package/dist/features.js +2 -2
  23. package/dist/generate.js +2 -2
  24. package/dist/map-catalog-to-astro.js +1 -1
  25. package/dist/resolve-catalog-dependencies.js +2 -2
  26. package/dist/watcher.js +2 -2
  27. package/eventcatalog/astro.config.mjs +2 -0
  28. package/eventcatalog/integrations/ecstudio-watcher.mjs +62 -0
  29. package/eventcatalog/src/components/Grids/ServiceGrid.tsx +2 -2
  30. package/eventcatalog/src/components/MDX/Design/Design.astro +67 -0
  31. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +39 -16
  32. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Actor.tsx +24 -0
  33. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Channel.tsx +20 -119
  34. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Command.tsx +19 -76
  35. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Data.tsx +24 -0
  36. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Event.tsx +20 -82
  37. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/ExternalSystem2.tsx +24 -0
  38. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/MessageContextMenu.tsx +9 -3
  39. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Query.tsx +19 -74
  40. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Service.tsx +19 -73
  41. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/View.tsx +24 -0
  42. package/eventcatalog/src/components/MDX/components.tsx +2 -0
  43. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +23 -0
  44. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +8 -0
  45. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +11 -0
  46. package/eventcatalog/src/content.config.ts +35 -0
  47. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +75 -0
  48. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +31 -0
  49. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -2
  50. package/eventcatalog/src/utils/collections/designs.ts +13 -0
  51. package/eventcatalog/src/utils/collections/file-diffs.ts +1 -1
  52. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +3 -3
  53. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +7 -7
  54. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +8 -3
  55. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +7 -6
  56. package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -1
  57. package/eventcatalog/tailwind.config.mjs +1 -0
  58. package/package.json +2 -1
@@ -0,0 +1,24 @@
1
+ import { Handle, Position } from '@xyflow/react';
2
+
3
+ import { nodeComponents, type ActorNode } from '@eventcatalog/visualizer';
4
+ const ActorComponent = nodeComponents.actor;
5
+
6
+ export default function ActorNode(props: ActorNode) {
7
+ return (
8
+ <div className="relative">
9
+ <Handle
10
+ type="target"
11
+ position={Position.Left}
12
+ style={{ width: 10, height: 10, background: 'orange', zIndex: 10 }}
13
+ className="bg-gray-500"
14
+ />
15
+ <Handle
16
+ type="source"
17
+ position={Position.Right}
18
+ style={{ width: 10, height: 10, background: 'orange', zIndex: 10 }}
19
+ className="bg-gray-500"
20
+ />
21
+ <ActorComponent {...props} />
22
+ </div>
23
+ );
24
+ }
@@ -1,130 +1,31 @@
1
- import type { CollectionMessageTypes } from '@types';
2
- import type { CollectionEntry } from 'astro:content';
3
- import { Handle } from '@xyflow/react';
1
+ import { Handle, Position } from '@xyflow/react';
4
2
  import * as ContextMenu from '@radix-ui/react-context-menu';
5
3
  import { buildUrl } from '@utils/url-builder';
6
- import { getIcon } from '@utils/badges';
7
- interface Data {
8
- title: string;
9
- label: string;
10
- bgColor: string;
11
- color: string;
12
- mode: 'simple' | 'full';
13
- channel: CollectionEntry<'channels'>;
14
- source: CollectionEntry<CollectionMessageTypes>;
15
- target: CollectionEntry<CollectionMessageTypes>;
16
- showTarget?: boolean;
17
- showSource?: boolean;
18
- }
19
-
20
- function classNames(...classes: any) {
21
- return classes.filter(Boolean).join(' ');
22
- }
23
-
24
- import { LinkIcon } from '@heroicons/react/24/outline';
25
- import { getIconForProtocol } from '@utils/protocols';
26
-
27
- export default function ChannelNode({ data, sourcePosition, targetPosition }: any) {
28
- const { mode, channel, source, target } = data as Data;
29
4
 
30
- const { id, name, version, summary, owners = [], address, protocols = [], styles } = channel.data;
31
- const protocol = protocols[0];
32
- const { node: { color = 'gray', label } = {}, icon = 'ArrowsRightLeftIcon' } = styles || {};
5
+ import { nodeComponents, type ChannelNode } from '@eventcatalog/visualizer';
6
+ const ChannelComponent = nodeComponents.channel;
33
7
 
34
- const Icon = getIconForProtocol(protocol);
35
-
36
- const SideBarIcon = getIcon(icon);
37
- const nodeLabel = label || channel?.data?.sidebar?.badge || 'Channel';
38
- const fontSize = nodeLabel.length > 10 ? '5px' : '9px';
39
-
40
- const getAddress = () => {
41
- const sourceChannel = source.data.channels?.find((channel) => channel.id === id);
42
- const targetChannel = target.data.channels?.find((channel) => channel.id === id);
43
- const sourceParams = sourceChannel?.parameters || {};
44
- const targetParams = targetChannel?.parameters || {};
45
- const params = { ...sourceParams, ...targetParams };
46
-
47
- let updatedAddress = address;
48
- if (params) {
49
- Object.keys(params).forEach((key) => {
50
- const placeholder = `{${key}}`;
51
- if (updatedAddress && updatedAddress.includes(placeholder)) {
52
- updatedAddress = updatedAddress.replace(new RegExp(`{${key}}`, 'g'), params[key]);
53
- }
54
- });
55
- }
56
-
57
- return updatedAddress;
58
- };
8
+ export default function ChannelNode(props: ChannelNode) {
9
+ // @ts-ignore
10
+ const { id, version } = props.data.channel;
59
11
 
60
12
  return (
61
13
  <ContextMenu.Root>
62
14
  <ContextMenu.Trigger>
63
- <div
64
- className={classNames(
65
- mode === 'simple' ? 'min-h-[3em]' : 'min-h-[6.5em]',
66
- `w-full rounded-md border flex justify-start bg-white text-black border-${color}-400 transform `
67
- )}
68
- >
69
- <div
70
- className={classNames(
71
- `bg-gradient-to-b from-${color}-500 to-${color}-700 relative flex items-center w-5 justify-center rounded-l-sm text-${color}-100`,
72
- `border-r-[1px] border-${color}-500`
73
- )}
74
- >
75
- {SideBarIcon && <SideBarIcon className="w-4 h-4 opacity-90 text-white absolute top-1 " />}
76
- {mode === 'full' && (
77
- <span
78
- className={`rotate -rotate-90 w-1/2 text-center absolute bottom-1 text-[${fontSize}] text-white font-bold uppercase tracking-[3px] `}
79
- >
80
- {nodeLabel}
81
- </span>
82
- )}
83
- </div>
84
- <div className="p-1 min-w-60 max-w-[min-content]">
85
- {targetPosition && <Handle type="target" position={targetPosition} />}
86
- {sourcePosition && <Handle type="source" position={sourcePosition} />}
87
- <div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
88
- <div className="flex justify-between items-center">
89
- <span className="text-xs font-bold block pb-0.5">{name}</span>
90
- {Icon && <Icon className="w-5 h-5 opacity-60 p-0.5" />}
91
- </div>
92
- <div className="flex justify-between">
93
- <span className="text-[10px] font-light block pt-0.5 pb-0.5 ">v{version}</span>
94
- {mode === 'simple' && (
95
- <span className="text-[10px] text-gray-500 font-light block pt-0.5 pb-0.5 ">{nodeLabel}</span>
96
- )}
97
- </div>
98
- </div>
99
- {mode === 'full' && (
100
- <div className="divide-y divide-gray-200 ">
101
- <div className="leading-[10px] py-1 ">
102
- <span className="text-[8px] font-light">{summary}</span>
103
- </div>
104
- {address && (
105
- <div className="leading-3 py-1 flex flex-col items-start space-y-0.5">
106
- <div className="text-[6px] flex items-center space-x-0.5 ">
107
- <LinkIcon className="w-2 h-2 opacity-60" />
108
- <span className="block font-normal ">{getAddress()}</span>
109
- </div>
110
- {protocols.length > 0 && (
111
- <div className="text-[6px] font-semibold flex space-x-2 items-center ">
112
- {[...protocols].map((protocol, index) => {
113
- const ProtoColIcon = getIconForProtocol(protocol);
114
- return (
115
- <span key={index} className="font-normal flex items-center -ml-[1px] space-x-0.5">
116
- {ProtoColIcon && <ProtoColIcon className="w-2 h-2 opacity-60 inline-block" />}
117
- <span>{protocol}</span>
118
- </span>
119
- );
120
- })}
121
- </div>
122
- )}
123
- </div>
124
- )}
125
- </div>
126
- )}
127
- </div>
15
+ <div className="relative">
16
+ <Handle
17
+ type="target"
18
+ position={Position.Left}
19
+ style={{ width: 10, height: 10, background: 'green', zIndex: 10 }}
20
+ className="bg-gray-500"
21
+ />
22
+ <Handle
23
+ type="source"
24
+ position={Position.Right}
25
+ style={{ width: 10, height: 10, background: 'green', zIndex: 10 }}
26
+ className="bg-gray-500"
27
+ />
28
+ <ChannelComponent {...props} />
128
29
  </div>
129
30
  </ContextMenu.Trigger>
130
31
  <ContextMenu.Portal>
@@ -1,83 +1,26 @@
1
- import { ChatBubbleLeftIcon } from '@heroicons/react/16/solid';
2
- import type { CollectionEntry } from 'astro:content';
3
- import { Handle } from '@xyflow/react';
1
+ import { Handle, Position } from '@xyflow/react';
4
2
  import MessageContextMenu from './MessageContextMenu';
5
- import { getIcon } from '@utils/badges';
6
3
 
7
- interface Data {
8
- title: string;
9
- label: string;
10
- bgColor: string;
11
- color: string;
12
- mode: 'simple' | 'full';
13
- message: CollectionEntry<'commands'>;
14
- showTarget?: boolean;
15
- showSource?: boolean;
16
- }
17
-
18
- function classNames(...classes: any) {
19
- return classes.filter(Boolean).join(' ');
20
- }
21
-
22
- export default function CommandNode({ data, sourcePosition, targetPosition }: any) {
23
- const { mode, message } = data as Data;
24
-
25
- const { id, name, version, summary, owners = [], producers = [], consumers = [], schemaPath, styles } = message.data;
26
- const { node: { color = 'blue', label } = {}, icon = 'ChatBubbleLeftIcon' } = styles || {};
27
-
28
- const Icon = getIcon(icon);
29
- const nodeLabel = label || message?.data?.sidebar?.badge || 'Command';
30
- const fontSize = nodeLabel.length > 10 ? '7px' : '9px';
4
+ import { nodeComponents, type CommandNode } from '@eventcatalog/visualizer';
5
+ const CommandComponent = nodeComponents.command;
31
6
 
7
+ export default function CommandNode(props: CommandNode) {
32
8
  return (
33
- <MessageContextMenu message={message} messageType="commands">
34
- <div className={classNames(`w-full rounded-md border flex justify-start bg-white text-black border-${color}-400`)}>
35
- <div
36
- className={classNames(
37
- `bg-gradient-to-b from-${color}-500 to-${color}-700 relative flex items-center w-5 justify-center rounded-l-sm text-${color}-100`,
38
- `border-r-[1px] border-${color}-500`
39
- )}
40
- >
41
- {Icon && <Icon className="w-4 h-4 opacity-90 text-white absolute top-1 " />}
42
- {mode === 'full' && (
43
- <span
44
- className={`rotate -rotate-90 w-1/2 text-center absolute bottom-1 text-[${fontSize}] text-white font-bold uppercase tracking-[3px] `}
45
- >
46
- {nodeLabel}
47
- </span>
48
- )}
49
- </div>
50
- <div className="p-1 min-w-60 max-w-[min-content]">
51
- {targetPosition && <Handle type="target" position={targetPosition} />}
52
- {sourcePosition && <Handle type="source" position={sourcePosition} />}
53
- <div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
54
- <span className="text-xs font-bold block pb-0.5">{name}</span>
55
- <div className="flex justify-between">
56
- <span className="text-[10px] font-light block pt-0.5 pb-0.5 ">v{version}</span>
57
- {mode === 'simple' && (
58
- <span className="text-[10px] text-gray-500 font-light block pt-0.5 pb-0.5 ">{nodeLabel}</span>
59
- )}
60
- </div>
61
- </div>
62
- {mode === 'full' && (
63
- <div className="divide-y divide-gray-200 ">
64
- <div className="leading-3 py-1">
65
- <span className="text-[8px] font-light">{summary}</span>
66
- </div>
67
- <div className="grid grid-cols-2 gap-x-4 py-1">
68
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
69
- Producers: {producers.length}
70
- </span>
71
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
72
- Consumers: {consumers.length}
73
- </span>
74
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
75
- Owners: {owners.length}
76
- </span>
77
- </div>
78
- </div>
79
- )}
80
- </div>
9
+ <MessageContextMenu message={props.data.message as any} messageType="commands">
10
+ <div className="relative">
11
+ <Handle
12
+ type="target"
13
+ position={Position.Left}
14
+ style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
15
+ className="bg-blue-500"
16
+ />
17
+ <Handle
18
+ type="source"
19
+ position={Position.Right}
20
+ style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
21
+ className="bg-blue-500"
22
+ />
23
+ <CommandComponent {...props} />
81
24
  </div>
82
25
  </MessageContextMenu>
83
26
  );
@@ -0,0 +1,24 @@
1
+ import { Handle, Position } from '@xyflow/react';
2
+
3
+ import { nodeComponents, type DataNode } from '@eventcatalog/visualizer';
4
+ const DataComponent = nodeComponents.data;
5
+
6
+ export default function DataNode(props: DataNode) {
7
+ return (
8
+ <div className="relative">
9
+ <Handle
10
+ type="target"
11
+ position={Position.Left}
12
+ style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
13
+ className="bg-gray-500"
14
+ />
15
+ <Handle
16
+ type="source"
17
+ position={Position.Right}
18
+ style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
19
+ className="bg-gray-500"
20
+ />
21
+ <DataComponent {...props} />
22
+ </div>
23
+ );
24
+ }
@@ -1,90 +1,28 @@
1
- import { BoltIcon } from '@heroicons/react/16/solid';
2
- import type { CollectionEntry } from 'astro:content';
3
1
  import { Handle } from '@xyflow/react';
4
2
  import MessageContextMenu from './MessageContextMenu';
5
- import { getIcon } from '@utils/badges';
6
- interface Data {
7
- title: string;
8
- label: string;
9
- bgColor: string;
10
- color: string;
11
- mode: 'simple' | 'full';
12
- message: CollectionEntry<'events'>;
13
- showTarget?: boolean;
14
- showSource?: boolean;
15
- group?: {
16
- type: string;
17
- value: string;
18
- };
19
- }
20
-
21
- function classNames(...classes: any) {
22
- return classes.filter(Boolean).join(' ');
23
- }
24
-
25
- export default function EventNode({ data, sourcePosition, targetPosition }: any) {
26
- const { mode, message, group } = data as Data;
27
- const { name, version, summary, owners = [], producers = [], consumers = [], styles } = message.data;
28
- const { node: { color = 'orange', label } = {}, icon = 'BoltIcon' } = styles || {};
3
+ import { Position } from '@xyflow/react';
29
4
 
30
- const Icon = getIcon(icon);
31
- const nodeLabel = label || message?.data?.sidebar?.badge || 'Event';
32
- const fontSize = nodeLabel.length > 10 ? '7px' : '9px';
5
+ // Import from properly installed package
6
+ import { nodeComponents, type EventNode } from '@eventcatalog/visualizer';
7
+ const EventComponent = nodeComponents.event;
33
8
 
9
+ export default function EventNode(props: EventNode) {
34
10
  return (
35
- <MessageContextMenu message={message} messageType="events">
36
- <div className={classNames(`w-full rounded-md border flex justify-start bg-white text-black border-${color}-400`)}>
37
- <div
38
- className={classNames(
39
- `bg-gradient-to-b from-${color}-500 to-${color}-700 relative flex items-center w-5 justify-center rounded-l-sm text-${color}-100`,
40
- `border-r-[1px] border-${color}-500`
41
- )}
42
- >
43
- {Icon && <Icon className="w-4 h-4 opacity-90 text-white absolute top-1 " />}
44
- {mode === 'full' && (
45
- <span
46
- className={`rotate -rotate-90 w-1/2 text-center absolute bottom-1 text-[${fontSize}] text-white font-bold uppercase tracking-[3px] `}
47
- >
48
- {nodeLabel}
49
- </span>
50
- )}
51
- </div>
52
- <div className="p-1 min-w-60 max-w-[min-content]">
53
- {targetPosition && <Handle type="target" position={targetPosition} />}
54
- {sourcePosition && <Handle type="source" position={sourcePosition} />}
55
- <div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
56
- <span className="text-xs font-bold block pb-0.5">{name}</span>
57
- <div className="flex justify-between">
58
- <span className="text-[10px] font-light block pt-0.5 pb-0.5 ">v{version}</span>
59
- {mode === 'simple' && (
60
- <span className="text-[10px] text-gray-500 font-light block pt-0.5 pb-0.5 ">{nodeLabel}</span>
61
- )}
62
- </div>
63
- </div>
64
- {mode === 'full' && (
65
- <div className="divide-y divide-gray-200 ">
66
- <div className="leading-3 py-1">
67
- <span className="text-[8px] font-light">{summary}</span>
68
- </div>
69
- <div className="grid grid-cols-2 gap-x-4 py-1">
70
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
71
- Producers: {producers.length}
72
- </span>
73
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
74
- Consumers: {consumers.length}
75
- </span>
76
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
77
- Owners: {owners.length}
78
- </span>
79
- {group && (
80
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
81
- {group.type}: {group.value}
82
- </span>
83
- )}
84
- </div>
85
- </div>
86
- )}
87
- </div>
11
+ <MessageContextMenu message={props.data.message as any} messageType="events">
12
+ <div className="relative">
13
+ <Handle
14
+ type="target"
15
+ position={Position.Left}
16
+ style={{ width: 10, height: 10, background: 'orange', zIndex: 10 }}
17
+ className="bg-orange-500"
18
+ />
19
+ <Handle
20
+ type="source"
21
+ position={Position.Right}
22
+ style={{ width: 10, height: 10, background: 'orange', zIndex: 10 }}
23
+ className="bg-orange-500"
24
+ />
25
+ <EventComponent {...props} />
88
26
  </div>
89
27
  </MessageContextMenu>
90
28
  );
@@ -0,0 +1,24 @@
1
+ import { Handle, Position } from '@xyflow/react';
2
+
3
+ import { nodeComponents, type ExternalSystemNode } from '@eventcatalog/visualizer';
4
+ const ExternalSystemComponent = nodeComponents.externalSystem;
5
+
6
+ export default function ExternalSystemNode(props: ExternalSystemNode) {
7
+ return (
8
+ <div className="relative">
9
+ <Handle
10
+ type="target"
11
+ position={Position.Left}
12
+ style={{ width: 10, height: 10, background: 'pink', zIndex: 10 }}
13
+ className="bg-gray-500"
14
+ />
15
+ <Handle
16
+ type="source"
17
+ position={Position.Right}
18
+ style={{ width: 10, height: 10, background: 'pink', zIndex: 10 }}
19
+ className="bg-gray-500"
20
+ />
21
+ <ExternalSystemComponent {...props} />
22
+ </div>
23
+ );
24
+ }
@@ -1,16 +1,22 @@
1
1
  import * as ContextMenu from '@radix-ui/react-context-menu';
2
2
  import { buildUrl } from '@utils/url-builder';
3
- import type { CollectionEntry } from 'astro:content';
4
3
  import type { CollectionMessageTypes } from '@types';
5
4
  interface Data {
6
- message: CollectionEntry<CollectionMessageTypes>;
5
+ message: {
6
+ id: string;
7
+ version: string;
8
+ name: string;
9
+ schemaPath: string;
10
+ };
7
11
  messageType: CollectionMessageTypes;
8
12
  children: React.ReactNode;
9
13
  }
10
14
 
11
15
  export default function MessageContextMenu(data: Data) {
12
16
  const { message, messageType, children } = data;
13
- const { id, version, name, schemaPath } = message.data;
17
+ const { id, version, name, schemaPath } = message;
18
+
19
+ if (!id) return null;
14
20
 
15
21
  return (
16
22
  <ContextMenu.Root>
@@ -1,82 +1,27 @@
1
- import { MagnifyingGlassIcon } from '@heroicons/react/16/solid';
2
- import type { CollectionEntry } from 'astro:content';
3
1
  import { Handle } from '@xyflow/react';
4
2
  import MessageContextMenu from './MessageContextMenu';
5
- import { getIcon } from '@utils/badges';
6
- interface Data {
7
- title: string;
8
- label: string;
9
- bgColor: string;
10
- color: string;
11
- mode: 'simple' | 'full';
12
- message: CollectionEntry<'queries'>;
13
- }
14
-
15
- function classNames(...classes: any) {
16
- return classes.filter(Boolean).join(' ');
17
- }
18
-
19
- export default function QueryNode({ data, sourcePosition, targetPosition }: any) {
20
- const { mode, message } = data as Data;
21
-
22
- const { name, version, summary, owners = [], producers = [], consumers = [], styles } = message.data;
23
- const { node: { color = 'green', label } = {}, icon = 'MagnifyingGlassIcon' } = styles || {};
3
+ import { Position } from '@xyflow/react';
24
4
 
25
- const Icon = getIcon(icon);
26
- const nodeLabel = label || message?.data?.sidebar?.badge || 'Query';
27
- const fontSize = nodeLabel.length > 10 ? '7px' : '9px';
28
- const renderTarget = true;
29
- const renderSource = true;
5
+ import { nodeComponents, type QueryNode } from '@eventcatalog/visualizer';
6
+ const QueryComponent = nodeComponents.query;
30
7
 
8
+ export default function QueryNode(props: QueryNode) {
31
9
  return (
32
- <MessageContextMenu message={message} messageType="queries">
33
- <div className={classNames(`w-full rounded-md border flex justify-start bg-white text-black border-${color}-400`)}>
34
- <div
35
- className={classNames(
36
- `bg-gradient-to-b from-${color}-500 to-${color}-700 relative flex items-center w-5 justify-center rounded-l-sm text-${color}-100`,
37
- `border-r-[1px] border-${color}-500`
38
- )}
39
- >
40
- {Icon && <Icon className="w-4 h-4 opacity-90 text-white absolute top-1 " />}
41
- {mode === 'full' && (
42
- <span
43
- className={`rotate -rotate-90 w-1/2 text-center absolute bottom-1 text-[${fontSize}] text-white font-bold uppercase tracking-[3px] `}
44
- >
45
- {nodeLabel}
46
- </span>
47
- )}
48
- </div>
49
- <div className="p-1 min-w-60 max-w-[min-content]">
50
- {renderTarget && <Handle type="target" position={targetPosition} />}
51
- {renderSource && <Handle type="source" position={sourcePosition} />}
52
- <div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
53
- <span className="text-xs font-bold block pb-0.5">{name}</span>
54
- <div className="flex justify-between">
55
- <span className="text-[10px] font-light block pt-0.5 pb-0.5 ">v{version}</span>
56
- {mode === 'simple' && (
57
- <span className="text-[10px] text-gray-500 font-light block pt-0.5 pb-0.5 ">{nodeLabel}</span>
58
- )}
59
- </div>
60
- </div>
61
- {mode === 'full' && (
62
- <div className="divide-y divide-gray-200 ">
63
- <div className="leading-3 py-1">
64
- <span className="text-[8px] font-light">{summary}</span>
65
- </div>
66
- <div className="grid grid-cols-2 gap-x-4 py-1">
67
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
68
- Producers: {producers.length}
69
- </span>
70
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
71
- Consumers: {consumers.length}
72
- </span>
73
- <span className="text-xs" style={{ fontSize: '0.2em' }}>
74
- Owners: {owners.length}
75
- </span>
76
- </div>
77
- </div>
78
- )}
79
- </div>
10
+ <MessageContextMenu message={props.data.message as any} messageType="queries">
11
+ <div className="relative">
12
+ <Handle
13
+ type="target"
14
+ position={Position.Left}
15
+ style={{ width: 10, height: 10, background: 'green', zIndex: 10 }}
16
+ className="bg-green-500"
17
+ />
18
+ <Handle
19
+ type="source"
20
+ position={Position.Right}
21
+ style={{ width: 10, height: 10, background: 'green', zIndex: 10 }}
22
+ className="bg-green-500"
23
+ />
24
+ <QueryComponent {...props} />
80
25
  </div>
81
26
  </MessageContextMenu>
82
27
  );