@eventcatalog/core 2.44.0 → 2.44.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.
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "2.44.0";
40
+ var version = "2.44.1";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-NUHIER2H.js";
4
- import "../chunk-C4NENBPQ.js";
3
+ } from "../chunk-AUGREOCT.js";
4
+ import "../chunk-HGLZ22GT.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "2.44.0";
109
+ var version = "2.44.1";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-MF3FQSRF.js";
4
- import "../chunk-NUHIER2H.js";
5
- import "../chunk-C4NENBPQ.js";
3
+ } from "../chunk-ECUXDBJ7.js";
4
+ import "../chunk-AUGREOCT.js";
5
+ import "../chunk-HGLZ22GT.js";
6
6
  import "../chunk-E7TXTI7G.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-C4NENBPQ.js";
3
+ } from "./chunk-HGLZ22GT.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-NUHIER2H.js";
3
+ } from "./chunk-AUGREOCT.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.44.0";
2
+ var version = "2.44.1";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.44.0";
28
+ var version = "2.44.1";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-C4NENBPQ.js";
3
+ } from "./chunk-HGLZ22GT.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -157,7 +157,7 @@ var import_axios = __toESM(require("axios"), 1);
157
157
  var import_os = __toESM(require("os"), 1);
158
158
 
159
159
  // package.json
160
- var version = "2.44.0";
160
+ var version = "2.44.1";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-DCLTVJDP.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-MF3FQSRF.js";
10
- import "./chunk-NUHIER2H.js";
9
+ } from "./chunk-ECUXDBJ7.js";
10
+ import "./chunk-AUGREOCT.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-EXAALOQA.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-C4NENBPQ.js";
18
+ } from "./chunk-HGLZ22GT.js";
19
19
  import {
20
20
  isAuthEnabled,
21
21
  isBackstagePluginEnabled,
@@ -103,6 +103,7 @@ if (collection === 'domain-context-map') {
103
103
  client:only="react"
104
104
  linksToVisualiser={linksToVisualiser}
105
105
  links={links}
106
+ mode={mode}
106
107
  />
107
108
  </div>
108
109
 
@@ -12,9 +12,13 @@ import {
12
12
  type Edge,
13
13
  type Node,
14
14
  useReactFlow,
15
+ getNodesBounds,
16
+ getViewportForBounds,
15
17
  } from '@xyflow/react';
16
18
  import '@xyflow/react/dist/style.css';
17
19
  import { HistoryIcon } from 'lucide-react';
20
+ import { toPng } from 'html-to-image';
21
+ import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
18
22
  // Nodes and edges
19
23
  import ServiceNode from './Nodes/Service';
20
24
  import FlowNode from './Nodes/Flow';
@@ -31,11 +35,11 @@ import CustomNode from './Nodes/Custom';
31
35
  import type { CollectionEntry } from 'astro:content';
32
36
  import { navigate } from 'astro:transitions/client';
33
37
  import type { CollectionTypes } from '@types';
34
- import DownloadButton from './DownloadButton';
35
38
  import { buildUrl } from '@utils/url-builder';
36
39
  import ChannelNode from './Nodes/Channel';
37
40
  import { CogIcon } from '@heroicons/react/20/solid';
38
41
  import { useEventCatalogVisualiser } from 'src/hooks/eventcatalog-visualizer';
42
+ import VisualiserSearch, { type VisualiserSearchRef } from './VisualiserSearch';
39
43
  interface Props {
40
44
  nodes: any;
41
45
  edges: any;
@@ -47,6 +51,7 @@ interface Props {
47
51
  includeKey?: boolean;
48
52
  linksToVisualiser?: boolean;
49
53
  links?: { label: string; url: string }[];
54
+ mode?: 'full' | 'simple';
50
55
  }
51
56
 
52
57
  const getVisualiserUrlForCollection = (collectionItem: CollectionEntry<CollectionTypes>) => {
@@ -62,6 +67,7 @@ const NodeGraphBuilder = ({
62
67
  includeKey = true,
63
68
  linksToVisualiser = false,
64
69
  links = [],
70
+ mode = 'full',
65
71
  }: Props) => {
66
72
  const nodeTypes = useMemo(
67
73
  () => ({
@@ -92,7 +98,8 @@ const NodeGraphBuilder = ({
92
98
  const [isAnimated, setIsAnimated] = useState(false);
93
99
  const [animateMessages, setAnimateMessages] = useState(false);
94
100
  const { hideChannels, toggleChannelsVisibility } = useEventCatalogVisualiser({ nodes, edges, setNodes, setEdges });
95
- const { fitView } = useReactFlow();
101
+ const { fitView, getNodes } = useReactFlow();
102
+ const searchRef = useRef<VisualiserSearchRef>(null);
96
103
 
97
104
  const resetNodesAndEdges = useCallback(() => {
98
105
  setNodes((nds) =>
@@ -200,10 +207,59 @@ const NodeGraphBuilder = ({
200
207
 
201
208
  const handlePaneClick = useCallback(() => {
202
209
  setIsSettingsOpen(false);
210
+ searchRef.current?.hideSuggestions();
203
211
  resetNodesAndEdges();
204
212
  fitView({ duration: 800 });
205
213
  }, [resetNodesAndEdges, fitView]);
206
214
 
215
+ const handleNodeSelect = useCallback(
216
+ (node: Node) => {
217
+ handleNodeClick(null, node);
218
+ },
219
+ [handleNodeClick]
220
+ );
221
+
222
+ const handleSearchClear = useCallback(() => {
223
+ resetNodesAndEdges();
224
+ fitView({ duration: 800 });
225
+ }, [resetNodesAndEdges, fitView]);
226
+
227
+ const downloadImage = useCallback((dataUrl: string, filename?: string) => {
228
+ const a = document.createElement('a');
229
+ a.setAttribute('download', `${filename || 'eventcatalog'}.png`);
230
+ a.setAttribute('href', dataUrl);
231
+ a.click();
232
+ }, []);
233
+
234
+ const handleExportVisual = useCallback(() => {
235
+ const imageWidth = 1024;
236
+ const imageHeight = 768;
237
+ const nodesBounds = getNodesBounds(getNodes());
238
+ const width = imageWidth > nodesBounds.width ? imageWidth : nodesBounds.width;
239
+ const height = imageHeight > nodesBounds.height ? imageHeight : nodesBounds.height;
240
+ const viewport = getViewportForBounds(nodesBounds, width, height, 0.5, 2, 0);
241
+
242
+ // Hide settings panel and controls during export
243
+ setIsSettingsOpen(false);
244
+ const controls = document.querySelector('.react-flow__controls') as HTMLElement;
245
+ if (controls) controls.style.display = 'none';
246
+
247
+ toPng(document.querySelector('.react-flow__viewport') as HTMLElement, {
248
+ backgroundColor: '#f1f1f1',
249
+ width,
250
+ height,
251
+ style: {
252
+ width: width.toString(),
253
+ height: height.toString(),
254
+ transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`,
255
+ },
256
+ }).then((dataUrl: string) => {
257
+ downloadImage(dataUrl, title);
258
+ // Restore controls
259
+ if (controls) controls.style.display = 'block';
260
+ });
261
+ }, [getNodes, downloadImage, title]);
262
+
207
263
  const handleLegendClick = useCallback(
208
264
  (collectionType: string, groupId?: string) => {
209
265
  const updatedNodes = nodes.map((node: Node<any>) => {
@@ -304,50 +360,55 @@ const NodeGraphBuilder = ({
304
360
  className="relative"
305
361
  >
306
362
  <Panel position="top-center" className="w-full pr-6 ">
307
- <div className="flex space-x-2 justify-between items-center">
308
- <div>
309
- <button
310
- onClick={() => setIsSettingsOpen(!isSettingsOpen)}
311
- className="py-2.5 px-3 bg-white rounded-md shadow-md hover:bg-purple-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
312
- aria-label="Open settings"
313
- >
314
- <CogIcon className="h-5 w-5 text-gray-600" />
315
- </button>
316
- </div>
317
- {title && (
318
- <span className="block shadow-sm bg-white text-xl z-10 text-black px-4 py-2 border-gray-200 rounded-md border opacity-80">
319
- {title}
320
- </span>
321
- )}
322
- <div className="flex justify-end space-x-2">
323
- <DownloadButton filename={title} addPadding={false} />
324
- {/* // Dropdown for links */}
325
- {links.length > 0 && (
326
- <div className="relative flex items-center -mt-1">
327
- <span className="absolute left-2 pointer-events-none flex items-center h-full">
328
- <HistoryIcon className="h-4 w-4 text-gray-600" />
329
- </span>
330
- <select
331
- value={links.find((link) => window.location.href.includes(link.url))?.url || links[0].url}
332
- onChange={(e) => navigate(e.target.value)}
333
- className="appearance-none pl-7 pr-6 py-0 text-[14px] bg-white rounded-md border border-gray-200 hover:bg-gray-100/50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
334
- style={{ minWidth: 120, height: '26px' }}
335
- >
336
- {links.map((link) => (
337
- <option key={link.url} value={link.url}>
338
- {link.label}
339
- </option>
340
- ))}
341
- </select>
342
- <span className="absolute right-2 pointer-events-none">
343
- <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
344
- <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
345
- </svg>
346
- </span>
347
- </div>
363
+ <div className="flex space-x-2 justify-between items-center">
364
+ <div className="flex space-x-2">
365
+ <div>
366
+ <button
367
+ onClick={() => setIsSettingsOpen(!isSettingsOpen)}
368
+ className="py-2.5 px-3 bg-white rounded-md shadow-md hover:bg-purple-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
369
+ aria-label="Open settings"
370
+ >
371
+ <CogIcon className="h-5 w-5 text-gray-600" />
372
+ </button>
373
+ </div>
374
+ {title && (
375
+ <span className="block shadow-sm bg-white text-xl z-10 text-black px-4 py-1.5 border-gray-200 rounded-md border opacity-80">
376
+ {title}
377
+ </span>
348
378
  )}
349
379
  </div>
380
+ {mode === 'full' && (
381
+ <div className="flex justify-end space-x-2 w-96">
382
+ <VisualiserSearch ref={searchRef} nodes={nodes} onNodeSelect={handleNodeSelect} onClear={handleSearchClear} />
383
+ </div>
384
+ )}
350
385
  </div>
386
+ {links.length > 0 && (
387
+ <div className="flex justify-end mt-3">
388
+ <div className="relative flex items-center -mt-1">
389
+ <span className="absolute left-2 pointer-events-none flex items-center h-full">
390
+ <HistoryIcon className="h-4 w-4 text-gray-600" />
391
+ </span>
392
+ <select
393
+ value={links.find((link) => window.location.href.includes(link.url))?.url || links[0].url}
394
+ onChange={(e) => navigate(e.target.value)}
395
+ className="appearance-none pl-7 pr-6 py-0 text-[14px] bg-white rounded-md border border-gray-200 hover:bg-gray-100/50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
396
+ style={{ minWidth: 120, height: '26px' }}
397
+ >
398
+ {links.map((link) => (
399
+ <option key={link.url} value={link.url}>
400
+ {link.label}
401
+ </option>
402
+ ))}
403
+ </select>
404
+ <span className="absolute right-2 pointer-events-none">
405
+ <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
406
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
407
+ </svg>
408
+ </span>
409
+ </div>
410
+ </div>
411
+ )}
351
412
  </Panel>
352
413
 
353
414
  {isSettingsOpen && (
@@ -396,6 +457,15 @@ const NodeGraphBuilder = ({
396
457
  </div>
397
458
  <p className="text-[10px] text-gray-500">Show or hide channels in the visualizer.</p>
398
459
  </div>
460
+ <div className="pt-4 border-t border-gray-200">
461
+ <button
462
+ onClick={handleExportVisual}
463
+ className="w-full flex items-center justify-center space-x-2 px-4 py-2 bg-purple-600 text-white text-sm font-medium rounded-md hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
464
+ >
465
+ <DocumentArrowDownIcon className="w-4 h-4" />
466
+ <span>Export Visual</span>
467
+ </button>
468
+ </div>
399
469
  </div>
400
470
  </div>
401
471
  )}
@@ -437,6 +507,7 @@ interface NodeGraphProps {
437
507
  footerLabel?: string;
438
508
  linksToVisualiser?: boolean;
439
509
  links?: { label: string; url: string }[];
510
+ mode?: 'full' | 'simple';
440
511
  }
441
512
 
442
513
  const NodeGraph = ({
@@ -451,6 +522,7 @@ const NodeGraph = ({
451
522
  footerLabel,
452
523
  linksToVisualiser = false,
453
524
  links = [],
525
+ mode = 'full',
454
526
  }: NodeGraphProps) => {
455
527
  const [elem, setElem] = useState(null);
456
528
  const [showFooter, setShowFooter] = useState(true);
@@ -482,6 +554,7 @@ const NodeGraph = ({
482
554
  includeKey={includeKey}
483
555
  linksToVisualiser={linksToVisualiser}
484
556
  links={links}
557
+ mode={mode}
485
558
  />
486
559
 
487
560
  {showFooter && (
@@ -0,0 +1,207 @@
1
+ import { useState, useCallback, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
2
+ import type { Node } from '@xyflow/react';
3
+
4
+ interface VisualiserSearchProps {
5
+ nodes: Node[];
6
+ onNodeSelect: (node: Node) => void;
7
+ onClear: () => void;
8
+ onPaneClick?: () => void;
9
+ }
10
+
11
+ export interface VisualiserSearchRef {
12
+ hideSuggestions: () => void;
13
+ }
14
+
15
+ const VisualiserSearch = forwardRef<VisualiserSearchRef, VisualiserSearchProps>(
16
+ ({ nodes, onNodeSelect, onClear, onPaneClick }, ref) => {
17
+ const [searchQuery, setSearchQuery] = useState('');
18
+ const [filteredSuggestions, setFilteredSuggestions] = useState<Node[]>([]);
19
+ const [showSuggestions, setShowSuggestions] = useState(false);
20
+ const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1);
21
+ const searchInputRef = useRef<HTMLInputElement>(null);
22
+ const containerRef = useRef<HTMLDivElement>(null);
23
+
24
+ const hideSuggestions = useCallback(() => {
25
+ setShowSuggestions(false);
26
+ setSelectedSuggestionIndex(-1);
27
+ }, []);
28
+
29
+ useImperativeHandle(
30
+ ref,
31
+ () => ({
32
+ hideSuggestions,
33
+ }),
34
+ [hideSuggestions]
35
+ );
36
+
37
+ const getNodeDisplayName = useCallback((node: Node) => {
38
+ // @ts-ignore
39
+ const name = node.data?.message?.data?.name || node.data?.service?.data?.name || node.data?.name || node.id;
40
+ // @ts-ignore
41
+ const version = node.data?.message?.data?.version || node.data?.service?.data?.version || node.data?.version;
42
+ return version ? `${name} (v${version})` : name;
43
+ }, []);
44
+
45
+ const getNodeTypeColorClass = useCallback((nodeType: string) => {
46
+ const colorClasses: { [key: string]: string } = {
47
+ events: 'bg-orange-600 text-white',
48
+ services: 'bg-pink-600 text-white',
49
+ flows: 'bg-teal-600 text-white',
50
+ commands: 'bg-blue-600 text-white',
51
+ queries: 'bg-green-600 text-white',
52
+ channels: 'bg-gray-600 text-white',
53
+ externalSystem: 'bg-pink-600 text-white',
54
+ actor: 'bg-yellow-500 text-white',
55
+ step: 'bg-gray-700 text-white',
56
+ user: 'bg-yellow-500 text-white',
57
+ custom: 'bg-gray-500 text-white',
58
+ };
59
+ return colorClasses[nodeType] || 'bg-gray-100 text-gray-700';
60
+ }, []);
61
+
62
+ const handleSearchChange = useCallback(
63
+ (event: React.ChangeEvent<HTMLInputElement>) => {
64
+ const query = event.target.value;
65
+ setSearchQuery(query);
66
+
67
+ if (query.length > 0) {
68
+ const filtered = nodes.filter((node) => {
69
+ const nodeName = getNodeDisplayName(node);
70
+ return nodeName.toLowerCase().includes(query.toLowerCase());
71
+ });
72
+ setFilteredSuggestions(filtered);
73
+ setShowSuggestions(true);
74
+ setSelectedSuggestionIndex(-1);
75
+ } else {
76
+ setFilteredSuggestions(nodes);
77
+ setShowSuggestions(true);
78
+ setSelectedSuggestionIndex(-1);
79
+ }
80
+ },
81
+ [nodes, getNodeDisplayName]
82
+ );
83
+
84
+ const handleSearchFocus = useCallback(() => {
85
+ if (searchQuery.length === 0) {
86
+ setFilteredSuggestions(nodes);
87
+ }
88
+ setShowSuggestions(true);
89
+ setSelectedSuggestionIndex(-1);
90
+ }, [nodes, searchQuery]);
91
+
92
+ const handleSuggestionClick = useCallback(
93
+ (node: Node) => {
94
+ setSearchQuery(getNodeDisplayName(node));
95
+ setShowSuggestions(false);
96
+ onNodeSelect(node);
97
+ },
98
+ [onNodeSelect, getNodeDisplayName]
99
+ );
100
+
101
+ const handleSearchKeyDown = useCallback(
102
+ (event: React.KeyboardEvent<HTMLInputElement>) => {
103
+ if (!showSuggestions || filteredSuggestions.length === 0) return;
104
+
105
+ switch (event.key) {
106
+ case 'ArrowDown':
107
+ event.preventDefault();
108
+ setSelectedSuggestionIndex((prev) => (prev < filteredSuggestions.length - 1 ? prev + 1 : 0));
109
+ break;
110
+ case 'ArrowUp':
111
+ event.preventDefault();
112
+ setSelectedSuggestionIndex((prev) => (prev > 0 ? prev - 1 : filteredSuggestions.length - 1));
113
+ break;
114
+ case 'Enter':
115
+ event.preventDefault();
116
+ if (selectedSuggestionIndex >= 0) {
117
+ handleSuggestionClick(filteredSuggestions[selectedSuggestionIndex]);
118
+ }
119
+ break;
120
+ case 'Escape':
121
+ setShowSuggestions(false);
122
+ setSelectedSuggestionIndex(-1);
123
+ break;
124
+ }
125
+ },
126
+ [showSuggestions, filteredSuggestions, selectedSuggestionIndex, handleSuggestionClick]
127
+ );
128
+
129
+ const clearSearch = useCallback(() => {
130
+ setSearchQuery('');
131
+ setShowSuggestions(false);
132
+ setFilteredSuggestions([]);
133
+ setSelectedSuggestionIndex(-1);
134
+ onClear();
135
+ if (searchInputRef.current) {
136
+ searchInputRef.current.focus();
137
+ }
138
+ }, [onClear]);
139
+
140
+ // Close suggestions when clicking outside
141
+ useEffect(() => {
142
+ const handleClickOutside = (event: MouseEvent) => {
143
+ if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
144
+ setShowSuggestions(false);
145
+ setSelectedSuggestionIndex(-1);
146
+ }
147
+ };
148
+
149
+ document.addEventListener('mousedown', handleClickOutside);
150
+ return () => {
151
+ document.removeEventListener('mousedown', handleClickOutside);
152
+ };
153
+ }, []);
154
+
155
+ return (
156
+ <div ref={containerRef} className="w-full max-w-md mx-auto relative">
157
+ <div className="relative">
158
+ <input
159
+ ref={searchInputRef}
160
+ type="text"
161
+ placeholder="Search nodes..."
162
+ value={searchQuery}
163
+ onChange={handleSearchChange}
164
+ onKeyDown={handleSearchKeyDown}
165
+ onFocus={handleSearchFocus}
166
+ className="w-full px-4 py-2 pr-10 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
167
+ />
168
+ {searchQuery && (
169
+ <button
170
+ onClick={clearSearch}
171
+ className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600"
172
+ aria-label="Clear search"
173
+ >
174
+ <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
175
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
176
+ </svg>
177
+ </button>
178
+ )}
179
+ </div>
180
+ {showSuggestions && filteredSuggestions.length > 0 && (
181
+ <div className="absolute top-full left-0 right-0 mt-1 bg-white border border-gray-300 rounded-md shadow-lg z-50 max-h-60 overflow-y-auto">
182
+ {filteredSuggestions.map((node, index) => {
183
+ const nodeName = getNodeDisplayName(node);
184
+ const nodeType = node.type || 'unknown';
185
+ return (
186
+ <div
187
+ key={node.id}
188
+ onClick={() => handleSuggestionClick(node)}
189
+ className={`px-4 py-2 cursor-pointer flex items-center justify-between hover:bg-gray-100 ${
190
+ index === selectedSuggestionIndex ? 'bg-purple-50' : ''
191
+ }`}
192
+ >
193
+ <span className="text-sm font-medium text-gray-900">{nodeName}</span>
194
+ <span className={`text-xs capitalize px-2 py-1 rounded ${getNodeTypeColorClass(nodeType)}`}>{nodeType}</span>
195
+ </div>
196
+ );
197
+ })}
198
+ </div>
199
+ )}
200
+ </div>
201
+ );
202
+ }
203
+ );
204
+
205
+ VisualiserSearch.displayName = 'VisualiserSearch';
206
+
207
+ export default VisualiserSearch;
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": "2.44.0",
9
+ "version": "2.44.1",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },