@eventcatalog/core 2.52.0 → 2.53.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.52.0";
40
+ var version = "2.53.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-6DB32LQO.js";
4
- import "../chunk-GR53VD3Z.js";
3
+ } from "../chunk-Q363JHA2.js";
4
+ import "../chunk-K5LYWIYR.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.52.0";
109
+ var version = "2.53.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-IXFKZMN2.js";
4
- import "../chunk-6DB32LQO.js";
5
- import "../chunk-GR53VD3Z.js";
3
+ } from "../chunk-BQDTPLND.js";
4
+ import "../chunk-Q363JHA2.js";
5
+ import "../chunk-K5LYWIYR.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
  raiseEvent
3
- } from "./chunk-6DB32LQO.js";
3
+ } from "./chunk-Q363JHA2.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.52.0";
2
+ var version = "2.53.1";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-GR53VD3Z.js";
3
+ } from "./chunk-K5LYWIYR.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.52.0";
28
+ var version = "2.53.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-GR53VD3Z.js";
3
+ } from "./chunk-K5LYWIYR.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.52.0";
160
+ var version = "2.53.1";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-XE6PFSH5.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-IXFKZMN2.js";
10
- import "./chunk-6DB32LQO.js";
9
+ } from "./chunk-BQDTPLND.js";
10
+ import "./chunk-Q363JHA2.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-LDBRNJIL.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-GR53VD3Z.js";
18
+ } from "./chunk-K5LYWIYR.js";
19
19
  import {
20
20
  isAuthEnabled,
21
21
  isBackstagePluginEnabled,
@@ -32,6 +32,7 @@ interface Props {
32
32
  linksToVisualiser?: boolean;
33
33
  showSearch?: boolean;
34
34
  showLegend?: boolean;
35
+ zoomOnScroll?: boolean;
35
36
  }
36
37
 
37
38
  const {
@@ -45,6 +46,7 @@ const {
45
46
  linksToVisualiser,
46
47
  showSearch = true,
47
48
  showLegend = true,
49
+ zoomOnScroll = false,
48
50
  } = Astro.props;
49
51
 
50
52
  let nodes = [],
@@ -136,6 +138,7 @@ if (collection === 'domains-entities') {
136
138
  mode={mode}
137
139
  showSearch={showSearch}
138
140
  includeKey={showLegend}
141
+ zoomOnScroll={zoomOnScroll}
139
142
  />
140
143
  </div>
141
144
 
@@ -57,6 +57,7 @@ interface Props {
57
57
  mode?: 'full' | 'simple';
58
58
  showFlowWalkthrough?: boolean;
59
59
  showSearch?: boolean;
60
+ zoomOnScroll?: boolean;
60
61
  }
61
62
 
62
63
  const getVisualiserUrlForCollection = (collectionItem: CollectionEntry<CollectionTypes>) => {
@@ -75,6 +76,7 @@ const NodeGraphBuilder = ({
75
76
  mode = 'full',
76
77
  showFlowWalkthrough = true,
77
78
  showSearch = true,
79
+ zoomOnScroll = false,
78
80
  }: Props) => {
79
81
  const nodeTypes = useMemo(
80
82
  () => ({
@@ -119,6 +121,8 @@ const NodeGraphBuilder = ({
119
121
  });
120
122
  const { fitView, getNodes } = useReactFlow();
121
123
  const searchRef = useRef<VisualiserSearchRef>(null);
124
+ const reactFlowWrapperRef = useRef<HTMLDivElement>(null);
125
+ const scrollableContainerRef = useRef<HTMLElement | null>(null);
122
126
 
123
127
  const resetNodesAndEdges = useCallback(() => {
124
128
  setNodes((nds) =>
@@ -224,6 +228,70 @@ const NodeGraphBuilder = ({
224
228
  }, 150);
225
229
  }, []);
226
230
 
231
+ // Handle scroll wheel events to forward to page when no modifier keys are pressed
232
+ // Only when zoomOnScroll is disabled
233
+ // This is a fix for when we embed node graphs into pages, and users are scrolling the documentation pages
234
+ // We dont want REACT FLOW to swallow the scroll events, so we forward them to the parent page
235
+ useEffect(() => {
236
+ // Skip scroll handling if zoomOnScroll is enabled
237
+ if (zoomOnScroll) return;
238
+
239
+ // Cache the scrollable container on mount (expensive operation done once)
240
+ const findScrollableContainer = (): HTMLElement | null => {
241
+ // Try specific known selectors first (fast)
242
+ const selectors = [
243
+ '.docs-layout .overflow-y-auto',
244
+ '.overflow-y-auto',
245
+ '[style*="overflow-y:auto"]',
246
+ '[style*="overflow-y: auto"]',
247
+ ];
248
+
249
+ for (const selector of selectors) {
250
+ const element = document.querySelector(selector) as HTMLElement;
251
+ if (element) return element;
252
+ }
253
+
254
+ return null;
255
+ };
256
+
257
+ // Find and cache the scrollable container once
258
+ if (!scrollableContainerRef.current) {
259
+ scrollableContainerRef.current = findScrollableContainer();
260
+ }
261
+
262
+ const handleWheel = (event: WheelEvent) => {
263
+ // Only forward scroll if no modifier keys are pressed
264
+ if (!event.ctrlKey && !event.shiftKey && !event.metaKey) {
265
+ event.preventDefault();
266
+
267
+ const scrollableContainer = scrollableContainerRef.current;
268
+
269
+ if (scrollableContainer) {
270
+ scrollableContainer.scrollBy({
271
+ top: event.deltaY,
272
+ left: event.deltaX,
273
+ behavior: 'instant',
274
+ });
275
+ } else {
276
+ // Fallback to window scroll
277
+ window.scrollBy({
278
+ top: event.deltaY,
279
+ left: event.deltaX,
280
+ behavior: 'instant',
281
+ });
282
+ }
283
+ }
284
+ };
285
+
286
+ const wrapper = reactFlowWrapperRef.current;
287
+ if (wrapper) {
288
+ wrapper.addEventListener('wheel', handleWheel, { passive: false });
289
+ return () => {
290
+ wrapper.removeEventListener('wheel', handleWheel);
291
+ };
292
+ }
293
+ }, [zoomOnScroll]);
294
+
227
295
  const handlePaneClick = useCallback(() => {
228
296
  setIsSettingsOpen(false);
229
297
  searchRef.current?.hideSuggestions();
@@ -463,167 +531,170 @@ const NodeGraphBuilder = ({
463
531
  const isFlowVisualization = edges.some((edge: Edge) => edge.type === 'flow-edge');
464
532
 
465
533
  return (
466
- <ReactFlow
467
- nodeTypes={nodeTypes}
468
- edgeTypes={edgeTypes}
469
- minZoom={0.07}
470
- nodes={nodes}
471
- edges={edges}
472
- fitView
473
- onNodesChange={onNodesChange}
474
- onEdgesChange={onEdgesChange}
475
- connectionLineType={ConnectionLineType.SmoothStep}
476
- nodeOrigin={[0.1, 0.1]}
477
- onNodeClick={handleNodeClick}
478
- onPaneClick={handlePaneClick}
479
- className="relative"
480
- >
481
- <Panel position="top-center" className="w-full pr-6 ">
482
- <div className="flex space-x-2 justify-between items-center">
483
- <div className="flex space-x-2">
484
- <div>
485
- <button
486
- onClick={() => setIsSettingsOpen(!isSettingsOpen)}
487
- 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"
488
- aria-label="Open settings"
489
- >
490
- <CogIcon className="h-5 w-5 text-gray-600" />
491
- </button>
534
+ <div ref={reactFlowWrapperRef} className="w-full h-full">
535
+ <ReactFlow
536
+ nodeTypes={nodeTypes}
537
+ edgeTypes={edgeTypes}
538
+ minZoom={0.07}
539
+ nodes={nodes}
540
+ edges={edges}
541
+ fitView
542
+ onNodesChange={onNodesChange}
543
+ onEdgesChange={onEdgesChange}
544
+ connectionLineType={ConnectionLineType.SmoothStep}
545
+ nodeOrigin={[0.1, 0.1]}
546
+ onNodeClick={handleNodeClick}
547
+ onPaneClick={handlePaneClick}
548
+ zoomOnScroll={zoomOnScroll}
549
+ className="relative"
550
+ >
551
+ <Panel position="top-center" className="w-full pr-6 ">
552
+ <div className="flex space-x-2 justify-between items-center">
553
+ <div className="flex space-x-2">
554
+ <div>
555
+ <button
556
+ onClick={() => setIsSettingsOpen(!isSettingsOpen)}
557
+ 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"
558
+ aria-label="Open settings"
559
+ >
560
+ <CogIcon className="h-5 w-5 text-gray-600" />
561
+ </button>
562
+ </div>
563
+ {title && (
564
+ <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">
565
+ {title}
566
+ </span>
567
+ )}
492
568
  </div>
493
- {title && (
494
- <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">
495
- {title}
496
- </span>
569
+ {mode === 'full' && showSearch && (
570
+ <div className="flex justify-end space-x-2 w-96">
571
+ <VisualiserSearch ref={searchRef} nodes={nodes} onNodeSelect={handleNodeSelect} onClear={handleSearchClear} />
572
+ </div>
497
573
  )}
498
574
  </div>
499
- {mode === 'full' && showSearch && (
500
- <div className="flex justify-end space-x-2 w-96">
501
- <VisualiserSearch ref={searchRef} nodes={nodes} onNodeSelect={handleNodeSelect} onClear={handleSearchClear} />
502
- </div>
503
- )}
504
- </div>
505
- {links.length > 0 && (
506
- <div className="flex justify-end mt-3">
507
- <div className="relative flex items-center -mt-1">
508
- <span className="absolute left-2 pointer-events-none flex items-center h-full">
509
- <HistoryIcon className="h-4 w-4 text-gray-600" />
510
- </span>
511
- <select
512
- value={links.find((link) => window.location.href.includes(link.url))?.url || links[0].url}
513
- onChange={(e) => navigate(e.target.value)}
514
- 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"
515
- style={{ minWidth: 120, height: '26px' }}
516
- >
517
- {links.map((link) => (
518
- <option key={link.url} value={link.url}>
519
- {link.label}
520
- </option>
521
- ))}
522
- </select>
523
- <span className="absolute right-2 pointer-events-none">
524
- <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
525
- <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
526
- </svg>
527
- </span>
528
- </div>
529
- </div>
530
- )}
531
- </Panel>
532
-
533
- {isSettingsOpen && (
534
- <div className="absolute top-[68px] left-5 w-72 p-4 bg-white rounded-lg shadow-lg z-30 border border-gray-200">
535
- <h3 className="text-lg font-semibold mb-4">Visualizer Settings</h3>
536
- <div className="space-y-4 ">
537
- <div>
538
- <div className="flex items-center justify-between">
539
- <label htmlFor="message-animation-toggle" className="text-sm font-medium text-gray-700">
540
- Simulate Messages
541
- </label>
542
- <button
543
- id="message-animation-toggle"
544
- onClick={toggleAnimateMessages}
545
- className={`${
546
- animateMessages ? 'bg-purple-600' : 'bg-gray-200'
547
- } relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2`}
575
+ {links.length > 0 && (
576
+ <div className="flex justify-end mt-3">
577
+ <div className="relative flex items-center -mt-1">
578
+ <span className="absolute left-2 pointer-events-none flex items-center h-full">
579
+ <HistoryIcon className="h-4 w-4 text-gray-600" />
580
+ </span>
581
+ <select
582
+ value={links.find((link) => window.location.href.includes(link.url))?.url || links[0].url}
583
+ onChange={(e) => navigate(e.target.value)}
584
+ 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"
585
+ style={{ minWidth: 120, height: '26px' }}
548
586
  >
549
- <span
550
- className={`${
551
- animateMessages ? 'translate-x-6' : 'translate-x-1'
552
- } inline-block h-4 w-4 transform rounded-full bg-white transition-transform`}
553
- />
554
- </button>
587
+ {links.map((link) => (
588
+ <option key={link.url} value={link.url}>
589
+ {link.label}
590
+ </option>
591
+ ))}
592
+ </select>
593
+ <span className="absolute right-2 pointer-events-none">
594
+ <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
595
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
596
+ </svg>
597
+ </span>
555
598
  </div>
556
- <p className="text-[10px] text-gray-500">Animate events, queries and commands.</p>
557
599
  </div>
558
- {hasChannels && (
600
+ )}
601
+ </Panel>
602
+
603
+ {isSettingsOpen && (
604
+ <div className="absolute top-[68px] left-5 w-72 p-4 bg-white rounded-lg shadow-lg z-30 border border-gray-200">
605
+ <h3 className="text-lg font-semibold mb-4">Visualizer Settings</h3>
606
+ <div className="space-y-4 ">
559
607
  <div>
560
608
  <div className="flex items-center justify-between">
561
- <label htmlFor="hide-channels-toggle" className="text-sm font-medium text-gray-700">
562
- Hide Channels
609
+ <label htmlFor="message-animation-toggle" className="text-sm font-medium text-gray-700">
610
+ Simulate Messages
563
611
  </label>
564
612
  <button
565
- id="hide-channels-toggle"
566
- onClick={toggleChannelsVisibility}
613
+ id="message-animation-toggle"
614
+ onClick={toggleAnimateMessages}
567
615
  className={`${
568
- hideChannels ? 'bg-purple-600' : 'bg-gray-200'
616
+ animateMessages ? 'bg-purple-600' : 'bg-gray-200'
569
617
  } relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2`}
570
618
  >
571
619
  <span
572
620
  className={`${
573
- hideChannels ? 'translate-x-6' : 'translate-x-1'
621
+ animateMessages ? 'translate-x-6' : 'translate-x-1'
574
622
  } inline-block h-4 w-4 transform rounded-full bg-white transition-transform`}
575
623
  />
576
624
  </button>
577
625
  </div>
578
- <p className="text-[10px] text-gray-500">Show or hide channels in the visualizer.</p>
626
+ <p className="text-[10px] text-gray-500">Animate events, queries and commands.</p>
579
627
  </div>
580
- )}
581
- <div className="pt-4 border-t border-gray-200">
582
- <button
583
- onClick={handleExportVisual}
584
- 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"
585
- >
586
- <DocumentArrowDownIcon className="w-4 h-4" />
587
- <span>Export Visual</span>
588
- </button>
589
- </div>
590
- </div>
591
- </div>
592
- )}
593
- {includeBackground && <Background color="#bbb" gap={16} />}
594
- {includeBackground && <Controls />}
595
- {isFlowVisualization && showFlowWalkthrough && (
596
- <Panel position="bottom-left">
597
- <StepWalkthrough
598
- nodes={nodes}
599
- edges={edges}
600
- isFlowVisualization={isFlowVisualization}
601
- onStepChange={handleStepChange}
602
- mode={mode}
603
- />
604
- </Panel>
605
- )}
606
- {includeKey && (
607
- <Panel position="bottom-right">
608
- <div className=" bg-white font-light px-4 text-[12px] shadow-md py-1 rounded-md">
609
- <ul className="m-0 p-0 ">
610
- {Object.entries(legend).map(([key, { count, colorClass, groupId }]) => (
611
- <li
612
- key={key}
613
- className="flex space-x-2 items-center text-[10px] cursor-pointer hover:text-purple-600 hover:underline"
614
- onClick={() => handleLegendClick(key, groupId)}
628
+ {hasChannels && (
629
+ <div>
630
+ <div className="flex items-center justify-between">
631
+ <label htmlFor="hide-channels-toggle" className="text-sm font-medium text-gray-700">
632
+ Hide Channels
633
+ </label>
634
+ <button
635
+ id="hide-channels-toggle"
636
+ onClick={toggleChannelsVisibility}
637
+ className={`${
638
+ hideChannels ? 'bg-purple-600' : 'bg-gray-200'
639
+ } relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2`}
640
+ >
641
+ <span
642
+ className={`${
643
+ hideChannels ? 'translate-x-6' : 'translate-x-1'
644
+ } inline-block h-4 w-4 transform rounded-full bg-white transition-transform`}
645
+ />
646
+ </button>
647
+ </div>
648
+ <p className="text-[10px] text-gray-500">Show or hide channels in the visualizer.</p>
649
+ </div>
650
+ )}
651
+ <div className="pt-4 border-t border-gray-200">
652
+ <button
653
+ onClick={handleExportVisual}
654
+ 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"
615
655
  >
616
- <span className={`w-2 h-2 block ${colorClass}`} />
617
- <span className="block capitalize">
618
- {key} ({count})
619
- </span>
620
- </li>
621
- ))}
622
- </ul>
656
+ <DocumentArrowDownIcon className="w-4 h-4" />
657
+ <span>Export Visual</span>
658
+ </button>
659
+ </div>
660
+ </div>
623
661
  </div>
624
- </Panel>
625
- )}
626
- </ReactFlow>
662
+ )}
663
+ {includeBackground && <Background color="#bbb" gap={16} />}
664
+ {includeBackground && <Controls />}
665
+ {isFlowVisualization && showFlowWalkthrough && (
666
+ <Panel position="bottom-left">
667
+ <StepWalkthrough
668
+ nodes={nodes}
669
+ edges={edges}
670
+ isFlowVisualization={isFlowVisualization}
671
+ onStepChange={handleStepChange}
672
+ mode={mode}
673
+ />
674
+ </Panel>
675
+ )}
676
+ {includeKey && (
677
+ <Panel position="bottom-right">
678
+ <div className=" bg-white font-light px-4 text-[12px] shadow-md py-1 rounded-md">
679
+ <ul className="m-0 p-0 ">
680
+ {Object.entries(legend).map(([key, { count, colorClass, groupId }]) => (
681
+ <li
682
+ key={key}
683
+ className="flex space-x-2 items-center text-[10px] cursor-pointer hover:text-purple-600 hover:underline"
684
+ onClick={() => handleLegendClick(key, groupId)}
685
+ >
686
+ <span className={`w-2 h-2 block ${colorClass}`} />
687
+ <span className="block capitalize">
688
+ {key} ({count})
689
+ </span>
690
+ </li>
691
+ ))}
692
+ </ul>
693
+ </div>
694
+ </Panel>
695
+ )}
696
+ </ReactFlow>
697
+ </div>
627
698
  );
628
699
  };
629
700
 
@@ -643,6 +714,7 @@ interface NodeGraphProps {
643
714
  portalId?: string;
644
715
  showFlowWalkthrough?: boolean;
645
716
  showSearch?: boolean;
717
+ zoomOnScroll?: boolean;
646
718
  }
647
719
 
648
720
  const NodeGraph = ({
@@ -661,6 +733,7 @@ const NodeGraph = ({
661
733
  portalId,
662
734
  showFlowWalkthrough = true,
663
735
  showSearch = true,
736
+ zoomOnScroll = false,
664
737
  }: NodeGraphProps) => {
665
738
  const [elem, setElem] = useState(null);
666
739
  const [showFooter, setShowFooter] = useState(true);
@@ -697,6 +770,7 @@ const NodeGraph = ({
697
770
  mode={mode}
698
771
  showFlowWalkthrough={showFlowWalkthrough}
699
772
  showSearch={showSearch}
773
+ zoomOnScroll={zoomOnScroll}
700
774
  />
701
775
 
702
776
  {showFooter && (
@@ -75,12 +75,20 @@ const consumersList = consumers.map((c) => ({
75
75
  tag: `v${c.data.version}`,
76
76
  href: buildUrl(`/docs/${c.collection}/${c.data.id}/${c.data.version}`),
77
77
  }));
78
+
79
+ const shouldRenderSideBarSection = (section: string) => {
80
+ if (!channel.data.detailsPanel) {
81
+ return true;
82
+ }
83
+ // @ts-ignore
84
+ return channel.data.detailsPanel[section]?.visible ?? true;
85
+ };
78
86
  ---
79
87
 
80
88
  <aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
81
89
  <div class="">
82
90
  {
83
- producersList.length > 0 && (
91
+ producersList.length > 0 && shouldRenderSideBarSection('producers') && (
84
92
  <PillListFlat
85
93
  title={`Producers (${producersList.length})`}
86
94
  pills={producersList}
@@ -92,7 +100,7 @@ const consumersList = consumers.map((c) => ({
92
100
  }
93
101
 
94
102
  {
95
- consumersList.length > 0 && (
103
+ consumersList.length > 0 && shouldRenderSideBarSection('consumers') && (
96
104
  <PillListFlat
97
105
  title={`Consumers (${consumersList.length})`}
98
106
  pills={consumersList}
@@ -104,7 +112,7 @@ const consumersList = consumers.map((c) => ({
104
112
  }
105
113
 
106
114
  {
107
- messageList.length > 0 && (
115
+ messageList.length > 0 && shouldRenderSideBarSection('messages') && (
108
116
  <PillListFlat
109
117
  title={`Messages using channel (${messageList.length})`}
110
118
  pills={messageList}
@@ -116,13 +124,13 @@ const consumersList = consumers.map((c) => ({
116
124
  }
117
125
 
118
126
  {
119
- protocolList.length > 0 && (
127
+ protocolList.length > 0 && shouldRenderSideBarSection('protocols') && (
120
128
  <ProtocolList color="pink" title={`Protocols (${protocolList.length})`} pills={protocolList} client:load />
121
129
  )
122
130
  }
123
131
 
124
132
  {
125
- channel.data.versions && (
133
+ channel.data.versions && shouldRenderSideBarSection('versions') && (
126
134
  <VersionList
127
135
  title={`Versions (${channel.data.versions?.length})`}
128
136
  versions={channel.data.versions}
@@ -131,27 +139,31 @@ const consumersList = consumers.map((c) => ({
131
139
  )
132
140
  }
133
141
 
134
- <OwnersList
135
- title={`Owners (${filteredOwners.length})`}
136
- owners={ownersList}
137
- emptyMessage={`This channel does not have any documented owners.`}
138
- client:load
139
- />
142
+ {
143
+ ownersList.length > 0 && shouldRenderSideBarSection('owners') && (
144
+ <OwnersList
145
+ title={`Owners (${filteredOwners.length})`}
146
+ owners={ownersList}
147
+ emptyMessage={`This channel does not have any documented owners.`}
148
+ client:load
149
+ />
150
+ )
151
+ }
140
152
 
141
153
  {
142
- channel.data.repository && (
154
+ channel.data.repository && shouldRenderSideBarSection('repository') && (
143
155
  <RepositoryList repository={channel.data.repository?.url} language={channel.data.repository?.language} />
144
156
  )
145
157
  }
146
158
 
147
159
  {
148
- paramsList.length > 0 && (
160
+ paramsList.length > 0 && shouldRenderSideBarSection('parameters') && (
149
161
  <PillListFlat color="pink" title={`Parameters (${paramsList.length})`} pills={paramsList} client:load />
150
162
  )
151
163
  }
152
164
 
153
165
  {
154
- isChangelogEnabled() && (
166
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
155
167
  <div class="space-y-2">
156
168
  <a
157
169
  href={buildUrl(`/docs/${channel.collection}/${channel.data.id}/${channel.data.latestVersion}/changelog`)}
@@ -105,12 +105,20 @@ const ownersList = filteredOwners.map((o) => ({
105
105
  avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
106
106
  href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
107
107
  }));
108
+
109
+ const shouldRenderSideBarSection = (section: string) => {
110
+ if (!domain.data.detailsPanel) {
111
+ return true;
112
+ }
113
+ // @ts-ignore
114
+ return domain.data.detailsPanel[section]?.visible ?? true;
115
+ };
108
116
  ---
109
117
 
110
118
  <aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
111
119
  <div>
112
120
  {
113
- parentDomains.length > 0 && (
121
+ parentDomains.length > 0 && shouldRenderSideBarSection('parentDomains') && (
114
122
  <PillListFlat
115
123
  title={`Parent domains (${parentDomains.length})`}
116
124
  pills={parentDomainList}
@@ -123,7 +131,7 @@ const ownersList = filteredOwners.map((o) => ({
123
131
  }
124
132
 
125
133
  {
126
- subDomains.length > 0 && (
134
+ subDomains.length > 0 && shouldRenderSideBarSection('subdomains') && (
127
135
  <PillListFlat
128
136
  title={`Subdomains (${subDomains.length})`}
129
137
  pills={subDomainList}
@@ -139,29 +147,41 @@ const ownersList = filteredOwners.map((o) => ({
139
147
  .filter((section) => section.items.length > 0 && section.sidebar)
140
148
  .map((section) => <CustomSideBarSectionList section={section} />)
141
149
  }
142
- <PillListFlat
143
- title={`Services (${services.length})`}
144
- pills={serviceList}
145
- emptyMessage={`This domain does not contain any services.`}
146
- color="pink"
147
- client:load
148
- />
149
- <PillListFlat
150
- title={`Sends messages (${sendsList.length})`}
151
- pills={sendsList}
152
- emptyMessage={`This domain does not send any messages.`}
153
- color="orange"
154
- client:load
155
- />
156
- <PillListFlat
157
- title={`Receives messages (${receivesList.length})`}
158
- pills={receivesList}
159
- emptyMessage={`This domain does not receive any messages.`}
160
- color="orange"
161
- client:load
162
- />
163
150
  {
164
- ubiquitousLanguageList && hasUbiquitousLanguage && (
151
+ shouldRenderSideBarSection('services') && (
152
+ <PillListFlat
153
+ title={`Services (${services.length})`}
154
+ pills={serviceList}
155
+ emptyMessage={`This domain does not contain any services.`}
156
+ color="pink"
157
+ client:load
158
+ />
159
+ )
160
+ }
161
+ {
162
+ shouldRenderSideBarSection('messages') && (
163
+ <PillListFlat
164
+ title={`Sends messages (${sendsList.length})`}
165
+ pills={sendsList}
166
+ emptyMessage={`This domain does not send any messages.`}
167
+ color="orange"
168
+ client:load
169
+ />
170
+ )
171
+ }
172
+ {
173
+ shouldRenderSideBarSection('messages') && (
174
+ <PillListFlat
175
+ title={`Receives messages (${receivesList.length})`}
176
+ pills={receivesList}
177
+ emptyMessage={`This domain does not receive any messages.`}
178
+ color="orange"
179
+ client:load
180
+ />
181
+ )
182
+ }
183
+ {
184
+ ubiquitousLanguageList && hasUbiquitousLanguage && shouldRenderSideBarSection('ubiquitousLanguage') && (
165
185
  <PillListFlat
166
186
  title={`Ubiquitous Language Dictionary (${ubiquitousLanguageDictionary?.length})`}
167
187
  pills={ubiquitousLanguageList}
@@ -173,7 +193,7 @@ const ownersList = filteredOwners.map((o) => ({
173
193
  )
174
194
  }
175
195
  {
176
- entities.length > 0 && (
196
+ entities.length > 0 && shouldRenderSideBarSection('entities') && (
177
197
  <PillListFlat
178
198
  title={`Entities (${entities.length})`}
179
199
  pills={entityList}
@@ -183,18 +203,26 @@ const ownersList = filteredOwners.map((o) => ({
183
203
  />
184
204
  )
185
205
  }
186
- {domain.data.versions && <VersionList versions={domain.data.versions} collectionItem={domain} />}
187
206
  {
188
- domain.data.repository && (
207
+ domain.data.versions && shouldRenderSideBarSection('versions') && (
208
+ <VersionList versions={domain.data.versions} collectionItem={domain} />
209
+ )
210
+ }
211
+ {
212
+ domain.data.repository && shouldRenderSideBarSection('repository') && (
189
213
  <RepositoryList repository={domain.data.repository?.url} language={domain.data.repository?.language} />
190
214
  )
191
215
  }
192
- <OwnersList
193
- title={`Owners (${ownersList.length})`}
194
- owners={ownersList}
195
- emptyMessage={`This domain does not have any documented owners.`}
196
- client:load
197
- />
216
+ {
217
+ shouldRenderSideBarSection('owners') && (
218
+ <OwnersList
219
+ title={`Owners (${ownersList.length})`}
220
+ owners={ownersList}
221
+ emptyMessage={`This domain does not have any documented owners.`}
222
+ client:load
223
+ />
224
+ )
225
+ }
198
226
 
199
227
  <div class="space-y-2">
200
228
  <a
@@ -205,7 +233,7 @@ const ownersList = filteredOwners.map((o) => ({
205
233
  <span class="block">View in visualiser</span>
206
234
  </a>
207
235
  {
208
- isChangelogEnabled() && (
236
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
209
237
  <a
210
238
  href={buildUrl(`/docs/${domain.collection}/${domain.data.id}/${domain.data.latestVersion}/changelog`)}
211
239
  class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
@@ -48,12 +48,20 @@ const domainsList = domains.map((p) => ({
48
48
  tag: `v${p.data.version}`,
49
49
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
50
50
  }));
51
+
52
+ const shouldRenderSideBarSection = (section: string) => {
53
+ if (!entity.data.detailsPanel) {
54
+ return true;
55
+ }
56
+ // @ts-ignore
57
+ return entity.data.detailsPanel[section]?.visible ?? true;
58
+ };
51
59
  ---
52
60
 
53
61
  <aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
54
62
  <div class="">
55
63
  {
56
- (
64
+ shouldRenderSideBarSection('domains') && (
57
65
  <PillListFlat
58
66
  title={`Domains (${domainsList.length})`}
59
67
  pills={domainsList}
@@ -64,7 +72,7 @@ const domainsList = domains.map((p) => ({
64
72
  )
65
73
  }
66
74
  {
67
- servicesList.length > 0 && (
75
+ servicesList.length > 0 && shouldRenderSideBarSection('services') && (
68
76
  <PillListFlat
69
77
  title={`Services (${servicesList.length})`}
70
78
  pills={servicesList}
@@ -74,16 +82,24 @@ const domainsList = domains.map((p) => ({
74
82
  />
75
83
  )
76
84
  }
77
- {entity.data.versions && <VersionList versions={entity.data.versions} collectionItem={entity} />}
78
- <OwnersList
79
- title={`Owners (${filteredOwners.length})`}
80
- owners={ownersList}
81
- emptyMessage={`This entity does not have any documented owners.`}
82
- client:load
83
- />
85
+ {
86
+ entity.data.versions && shouldRenderSideBarSection('versions') && (
87
+ <VersionList versions={entity.data.versions} collectionItem={entity} />
88
+ )
89
+ }
90
+ {
91
+ filteredOwners.length > 0 && shouldRenderSideBarSection('owners') && (
92
+ <OwnersList
93
+ title={`Owners (${filteredOwners.length})`}
94
+ owners={ownersList}
95
+ emptyMessage={`This entity does not have any documented owners.`}
96
+ client:load
97
+ />
98
+ )
99
+ }
84
100
 
85
101
  {
86
- isChangelogEnabled() && (
102
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
87
103
  <div class="space-y-2">
88
104
  <a
89
105
  href={buildUrl(`/docs/${entity.collection}/${entity.data.id}/${entity.data.latestVersion}/changelog`)}
@@ -29,6 +29,14 @@ const ownersList = filteredOwners.map((o) => ({
29
29
  }));
30
30
 
31
31
  const isRSSEnabled = config.rss?.enabled;
32
+
33
+ const shouldRenderSideBarSection = (section: string) => {
34
+ if (!flow.data.detailsPanel) {
35
+ return true;
36
+ }
37
+ // @ts-ignore
38
+ return flow.data.detailsPanel[section]?.visible ?? true;
39
+ };
32
40
  ---
33
41
 
34
42
  <aside class="sticky top-28 left-0 h-full overflow-y-auto pr-6 py-4">
@@ -38,14 +46,22 @@ const isRSSEnabled = config.rss?.enabled;
38
46
  .filter((section) => section.items.length > 0 && section.sidebar)
39
47
  .map((section) => <CustomSideBarSectionList section={section} />)
40
48
  }
41
- {flow.data.versions && <VersionList versions={flow.data.versions} collectionItem={flow} />}
49
+ {
50
+ flow.data.versions && shouldRenderSideBarSection('versions') && (
51
+ <VersionList versions={flow.data.versions} collectionItem={flow} />
52
+ )
53
+ }
42
54
 
43
- <OwnersList
44
- title={`Owners (${ownersList.length})`}
45
- owners={ownersList}
46
- emptyMessage={`This flow does not have any documented owners.`}
47
- client:load
48
- />
55
+ {
56
+ shouldRenderSideBarSection('owners') && (
57
+ <OwnersList
58
+ title={`Owners (${ownersList.length})`}
59
+ owners={ownersList}
60
+ emptyMessage={`This flow does not have any documented owners.`}
61
+ client:load
62
+ />
63
+ )
64
+ }
49
65
 
50
66
  {
51
67
  isRSSEnabled && (
@@ -72,7 +88,7 @@ const isRSSEnabled = config.rss?.enabled;
72
88
  <span class="block">View in visualiser</span>
73
89
  </a>
74
90
  {
75
- isChangelogEnabled() && (
91
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
76
92
  <a
77
93
  href={buildUrl(`/docs/${flow.collection}/${flow.data.id}/${flow.data.latestVersion}/changelog`)}
78
94
  class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
@@ -98,6 +98,14 @@ const publicPath = message?.catalog?.publicPath;
98
98
 
99
99
  const schemaFilePath = message?.data?.schemaPath;
100
100
  const schemaURL = path.join(publicPath, schemaFilePath || '');
101
+
102
+ const shouldRenderSideBarSection = (section: string) => {
103
+ if (!message.data.detailsPanel) {
104
+ return true;
105
+ }
106
+ // @ts-ignore
107
+ return message.data.detailsPanel[section]?.visible ?? true;
108
+ };
101
109
  ---
102
110
 
103
111
  <aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
@@ -108,7 +116,7 @@ const schemaURL = path.join(publicPath, schemaFilePath || '');
108
116
  .map((section) => <CustomSideBarSectionList section={section} />)
109
117
  }
110
118
  {
111
- producerList.length > 0 && (
119
+ producerList.length > 0 && shouldRenderSideBarSection('producers') && (
112
120
  <PillListFlat
113
121
  color="pink"
114
122
  title={`Producers (${producerList.length})`}
@@ -119,7 +127,7 @@ const schemaURL = path.join(publicPath, schemaFilePath || '');
119
127
  )
120
128
  }
121
129
  {
122
- consumerList.length > 0 && (
130
+ consumerList.length > 0 && shouldRenderSideBarSection('consumers') && (
123
131
  <PillListFlat
124
132
  color="pink"
125
133
  title={`Consumers (${consumerList.length})`}
@@ -130,13 +138,13 @@ const schemaURL = path.join(publicPath, schemaFilePath || '');
130
138
  )
131
139
  }
132
140
  {
133
- channelList.length > 0 && (
141
+ channelList.length > 0 && shouldRenderSideBarSection('channels') && (
134
142
  <PillListFlat color="pink" title={`Channels (${channelList.length})`} pills={channelList} client:load />
135
143
  )
136
144
  }
137
145
 
138
146
  {
139
- message.data.versions && (
147
+ message.data.versions && shouldRenderSideBarSection('versions') && (
140
148
  <VersionList
141
149
  title={`Versions (${message.data.versions?.length})`}
142
150
  versions={message.data.versions}
@@ -145,15 +153,19 @@ const schemaURL = path.join(publicPath, schemaFilePath || '');
145
153
  )
146
154
  }
147
155
 
148
- <OwnersList
149
- title={`Owners (${ownersList.length})`}
150
- owners={ownersList}
151
- emptyMessage={`This ${type} does not have any documented owners.`}
152
- client:load
153
- />
156
+ {
157
+ ownersList.length > 0 && shouldRenderSideBarSection('owners') && (
158
+ <OwnersList
159
+ title={`Owners (${ownersList.length})`}
160
+ owners={ownersList}
161
+ emptyMessage={`This ${type} does not have any documented owners.`}
162
+ client:load
163
+ />
164
+ )
165
+ }
154
166
 
155
167
  {
156
- message.data.repository && (
168
+ message.data.repository && shouldRenderSideBarSection('repository') && (
157
169
  <RepositoryList repository={message.data.repository?.url} language={message.data.repository?.language} />
158
170
  )
159
171
  }
@@ -196,7 +208,7 @@ const schemaURL = path.join(publicPath, schemaFilePath || '');
196
208
  </a>
197
209
 
198
210
  {
199
- isChangelogEnabled() && (
211
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
200
212
  <a
201
213
  href={buildUrl(`/docs/${message.collection}/${message.data.id}/${message.data.latestVersion}/changelog`)}
202
214
  class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
@@ -87,6 +87,14 @@ const isRSSEnabled = config.rss?.enabled;
87
87
  const publicPath = service?.catalog?.publicPath;
88
88
  const schemaFilePath = service?.data?.schemaPath;
89
89
  const schemaURL = join(publicPath, schemaFilePath || '');
90
+
91
+ const shouldRenderSideBarSection = (section: string) => {
92
+ if (!service.data.detailsPanel) {
93
+ return true;
94
+ }
95
+ // @ts-ignore
96
+ return service.data.detailsPanel[section]?.visible ?? true;
97
+ };
90
98
  ---
91
99
 
92
100
  <aside class="sticky top-28 left-0 h-full overflow-y-auto pr-6 py-4">
@@ -97,7 +105,7 @@ const schemaURL = join(publicPath, schemaFilePath || '');
97
105
  .map((section) => <CustomSideBarSectionList section={section} />)
98
106
  }
99
107
  {
100
- domainList.length > 0 && (
108
+ domainList.length > 0 && shouldRenderSideBarSection('domains') && (
101
109
  <PillListFlat
102
110
  title={`Domains (${domainList.length})`}
103
111
  pills={domainList}
@@ -107,26 +115,40 @@ const schemaURL = join(publicPath, schemaFilePath || '');
107
115
  />
108
116
  )
109
117
  }
110
- <PillListFlat
111
- title={`Receives Messages (${receivesList.length})`}
112
- pills={receivesList}
113
- emptyMessage={`This service does not receive any messages.`}
114
- color="orange"
115
- client:load
116
- />
117
- <PillListFlat
118
- title={`Sends Messages (${sendsList.length})`}
119
- pills={sendsList}
120
- emptyMessage={`This service does not send any messages.`}
121
- color="orange"
122
- client:load
123
- />
124
- {service.data.versions && <VersionList versions={service.data.versions} collectionItem={service} />}
125
-
126
- {service.data.specifications && <SpecificationsList collectionItem={service} />}
118
+ {
119
+ shouldRenderSideBarSection('messages') && (
120
+ <>
121
+ <PillListFlat
122
+ title={`Receives Messages (${receivesList.length})`}
123
+ pills={receivesList}
124
+ emptyMessage={`This service does not receive any messages.`}
125
+ color="orange"
126
+ client:load
127
+ />
128
+ <PillListFlat
129
+ title={`Sends Messages (${sendsList.length})`}
130
+ pills={sendsList}
131
+ emptyMessage={`This service does not send any messages.`}
132
+ color="orange"
133
+ client:load
134
+ />
135
+ </>
136
+ )
137
+ }
138
+ {
139
+ service.data.versions && shouldRenderSideBarSection('versions') && (
140
+ <VersionList versions={service.data.versions} collectionItem={service} />
141
+ )
142
+ }
143
+
144
+ {
145
+ service.data.specifications && shouldRenderSideBarSection('specifications') && (
146
+ <SpecificationsList collectionItem={service} />
147
+ )
148
+ }
127
149
 
128
150
  {
129
- entities.length > 0 && (
151
+ entities.length > 0 && shouldRenderSideBarSection('entities') && (
130
152
  <PillListFlat
131
153
  title={`Entities (${entities.length})`}
132
154
  pills={entityList}
@@ -137,15 +159,19 @@ const schemaURL = join(publicPath, schemaFilePath || '');
137
159
  )
138
160
  }
139
161
 
140
- <OwnersList
141
- title={`Owners (${ownersList.length})`}
142
- owners={ownersList}
143
- emptyMessage={`This service does not have any documented owners.`}
144
- client:load
145
- />
162
+ {
163
+ shouldRenderSideBarSection('owners') && (
164
+ <OwnersList
165
+ title={`Owners (${ownersList.length})`}
166
+ owners={ownersList}
167
+ emptyMessage={`This service does not have any documented owners.`}
168
+ client:load
169
+ />
170
+ )
171
+ }
146
172
 
147
173
  {
148
- service.data.repository && (
174
+ service.data.repository && shouldRenderSideBarSection('repository') && (
149
175
  <RepositoryList repository={service.data.repository?.url} language={service.data.repository?.language} />
150
176
  )
151
177
  }
@@ -187,7 +213,7 @@ const schemaURL = join(publicPath, schemaFilePath || '');
187
213
  <span class="block">View in visualiser</span>
188
214
  </a>
189
215
  {
190
- isChangelogEnabled() && (
216
+ isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
191
217
  <a
192
218
  href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.latestVersion}/changelog`)}
193
219
  class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
@@ -31,6 +31,10 @@ const pointer = z.object({
31
31
  version: z.string().optional().default('latest'),
32
32
  });
33
33
 
34
+ const detailPanelPropertySchema = z.object({
35
+ visible: z.boolean().optional(),
36
+ });
37
+
34
38
  const channelPointer = z
35
39
  .object({
36
40
  parameters: z.record(z.string()).optional(),
@@ -175,6 +179,13 @@ const flows = defineCollection({
175
179
  }),
176
180
  schema: z
177
181
  .object({
182
+ detailsPanel: z
183
+ .object({
184
+ owners: detailPanelPropertySchema.optional(),
185
+ versions: detailPanelPropertySchema.optional(),
186
+ changelog: detailPanelPropertySchema.optional(),
187
+ })
188
+ .optional(),
178
189
  steps: z.array(
179
190
  z
180
191
  .object({
@@ -185,6 +196,7 @@ const flows = defineCollection({
185
196
  message: pointer.optional(),
186
197
  service: pointer.optional(),
187
198
  flow: pointer.optional(),
199
+
188
200
  actor: z
189
201
  .object({
190
202
  name: z.string(),
@@ -233,6 +245,16 @@ const flows = defineCollection({
233
245
  .merge(baseSchema),
234
246
  });
235
247
 
248
+ const messageDetailsPanelPropertySchema = z.object({
249
+ producers: detailPanelPropertySchema.optional(),
250
+ consumers: detailPanelPropertySchema.optional(),
251
+ channels: detailPanelPropertySchema.optional(),
252
+ versions: detailPanelPropertySchema.optional(),
253
+ repository: detailPanelPropertySchema.optional(),
254
+ owners: detailPanelPropertySchema.optional(),
255
+ changelog: detailPanelPropertySchema.optional(),
256
+ });
257
+
236
258
  const events = defineCollection({
237
259
  loader: glob({
238
260
  pattern: ['**/events/*/index.(md|mdx)', '**/events/*/versioned/*/index.(md|mdx)'],
@@ -248,6 +270,7 @@ const events = defineCollection({
248
270
  channels: z.array(channelPointer).optional(),
249
271
  // Used by eventcatalog
250
272
  messageChannels: z.array(reference('channels')).optional(),
273
+ detailsPanel: messageDetailsPanelPropertySchema.optional(),
251
274
  })
252
275
  .merge(baseSchema),
253
276
  });
@@ -265,6 +288,7 @@ const commands = defineCollection({
265
288
  producers: z.array(reference('services')).optional(),
266
289
  consumers: z.array(reference('services')).optional(),
267
290
  channels: z.array(channelPointer).optional(),
291
+ detailsPanel: messageDetailsPanelPropertySchema.optional(),
268
292
  // Used by eventcatalog
269
293
  messageChannels: z.array(reference('channels')).optional(),
270
294
  })
@@ -284,6 +308,7 @@ const queries = defineCollection({
284
308
  producers: z.array(reference('services')).optional(),
285
309
  consumers: z.array(reference('services')).optional(),
286
310
  channels: z.array(channelPointer).optional(),
311
+ detailsPanel: messageDetailsPanelPropertySchema.optional(),
287
312
  // Used by eventcatalog
288
313
  messageChannels: z.array(reference('channels')).optional(),
289
314
  })
@@ -314,6 +339,18 @@ const services = defineCollection({
314
339
  sends: z.array(pointer).optional(),
315
340
  receives: z.array(pointer).optional(),
316
341
  entities: z.array(pointer).optional(),
342
+ detailsPanel: z
343
+ .object({
344
+ domains: detailPanelPropertySchema.optional(),
345
+ messages: detailPanelPropertySchema.optional(),
346
+ versions: detailPanelPropertySchema.optional(),
347
+ specifications: detailPanelPropertySchema.optional(),
348
+ entities: detailPanelPropertySchema.optional(),
349
+ repository: detailPanelPropertySchema.optional(),
350
+ owners: detailPanelPropertySchema.optional(),
351
+ changelog: detailPanelPropertySchema.optional(),
352
+ })
353
+ .optional(),
317
354
  })
318
355
  .merge(baseSchema),
319
356
  });
@@ -356,6 +393,20 @@ const domains = defineCollection({
356
393
  services: z.array(pointer).optional(),
357
394
  domains: z.array(pointer).optional(),
358
395
  entities: z.array(pointer).optional(),
396
+ detailsPanel: z
397
+ .object({
398
+ parentDomains: detailPanelPropertySchema.optional(),
399
+ subdomains: detailPanelPropertySchema.optional(),
400
+ services: detailPanelPropertySchema.optional(),
401
+ entities: detailPanelPropertySchema.optional(),
402
+ messages: detailPanelPropertySchema.optional(),
403
+ ubiquitousLanguage: detailPanelPropertySchema.optional(),
404
+ repository: detailPanelPropertySchema.optional(),
405
+ versions: detailPanelPropertySchema.optional(),
406
+ owners: detailPanelPropertySchema.optional(),
407
+ changelog: detailPanelPropertySchema.optional(),
408
+ })
409
+ .optional(),
359
410
  })
360
411
  .merge(baseSchema),
361
412
  });
@@ -383,6 +434,19 @@ const channels = defineCollection({
383
434
  )
384
435
  .optional(),
385
436
  messages: z.array(z.object({ collection: z.string(), name: z.string(), ...pointer.shape })).optional(),
437
+ detailsPanel: z
438
+ .object({
439
+ producers: detailPanelPropertySchema.optional(),
440
+ consumers: detailPanelPropertySchema.optional(),
441
+ messages: detailPanelPropertySchema.optional(),
442
+ protocols: detailPanelPropertySchema.optional(),
443
+ parameters: detailPanelPropertySchema.optional(),
444
+ versions: detailPanelPropertySchema.optional(),
445
+ repository: detailPanelPropertySchema.optional(),
446
+ owners: detailPanelPropertySchema.optional(),
447
+ changelog: detailPanelPropertySchema.optional(),
448
+ })
449
+ .optional(),
386
450
  })
387
451
  .merge(baseSchema),
388
452
  });
@@ -438,6 +502,16 @@ const entities = defineCollection({
438
502
  .optional(),
439
503
  services: z.array(reference('services')).optional(),
440
504
  domains: z.array(reference('domains')).optional(),
505
+ detailsPanel: z
506
+ .object({
507
+ domains: detailPanelPropertySchema.optional(),
508
+ services: detailPanelPropertySchema.optional(),
509
+ messages: detailPanelPropertySchema.optional(),
510
+ versions: detailPanelPropertySchema.optional(),
511
+ owners: detailPanelPropertySchema.optional(),
512
+ changelog: detailPanelPropertySchema.optional(),
513
+ })
514
+ .optional(),
441
515
  })
442
516
 
443
517
  .merge(baseSchema),
@@ -30,6 +30,7 @@ const {
30
30
  linkTo="visualiser"
31
31
  version={props.data.version}
32
32
  linksToVisualiser={false}
33
+ zoomOnScroll={true}
33
34
  href={{
34
35
  label: `Open documentation for ${props.data.name} v${props.data.version}`,
35
36
  url: buildUrl(`/docs/${props.collection}/${props.data.id}/${props.data.version}`),
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.52.0",
9
+ "version": "2.53.1",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },