@eventcatalog/core 3.0.0-beta.0 → 3.0.0-beta.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 (33) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-TQ4HZREX.js → chunk-FH5AN4Z6.js} +1 -1
  6. package/dist/{chunk-X4W4YC3U.js → chunk-KE2IUVK6.js} +1 -1
  7. package/dist/{chunk-JB4YT5JY.js → chunk-M6QG3NPM.js} +1 -1
  8. package/dist/constants.cjs +1 -1
  9. package/dist/constants.js +1 -1
  10. package/dist/eventcatalog.cjs +1 -1
  11. package/dist/eventcatalog.js +3 -3
  12. package/eventcatalog/src/components/Header.astro +5 -11
  13. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +0 -10
  14. package/eventcatalog/src/components/Search/Search.astro +2 -2
  15. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +58 -44
  16. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +1 -1
  17. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +1 -1
  18. package/eventcatalog/src/layouts/DirectoryLayout.astro +1 -1
  19. package/eventcatalog/src/layouts/DiscoverLayout.astro +1 -1
  20. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +42 -155
  21. package/eventcatalog/src/pages/chat/feature.astro +1 -1
  22. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +4 -4
  23. package/eventcatalog/src/pages/docs/custom/feature.astro +1 -1
  24. package/eventcatalog/src/pages/docs/custom/index.astro +1 -1
  25. package/eventcatalog/src/pages/plans/index.astro +1 -1
  26. package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -1
  27. package/eventcatalog/src/pages/studio.astro +1 -1
  28. package/eventcatalog/src/pages/unauthorized/index.astro +1 -1
  29. package/eventcatalog/src/utils/collections/domains.ts +1 -1
  30. package/eventcatalog/src/utils/collections/types.ts +6 -0
  31. package/eventcatalog/src/utils/feature.ts +2 -0
  32. package/eventcatalog/tsconfig.json +2 -1
  33. package/package.json +1 -1
@@ -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 = "3.0.0-beta.0";
40
+ var version = "3.0.0-beta.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-JB4YT5JY.js";
4
- import "../chunk-TQ4HZREX.js";
3
+ } from "../chunk-M6QG3NPM.js";
4
+ import "../chunk-FH5AN4Z6.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 = "3.0.0-beta.0";
109
+ var version = "3.0.0-beta.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-X4W4YC3U.js";
4
- import "../chunk-JB4YT5JY.js";
5
- import "../chunk-TQ4HZREX.js";
3
+ } from "../chunk-KE2IUVK6.js";
4
+ import "../chunk-M6QG3NPM.js";
5
+ import "../chunk-FH5AN4Z6.js";
6
6
  import "../chunk-UPONRQSN.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "3.0.0-beta.0";
2
+ var version = "3.0.0-beta.1";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-JB4YT5JY.js";
3
+ } from "./chunk-M6QG3NPM.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-TQ4HZREX.js";
3
+ } from "./chunk-FH5AN4Z6.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 = "3.0.0-beta.0";
28
+ var version = "3.0.0-beta.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-TQ4HZREX.js";
3
+ } from "./chunk-FH5AN4Z6.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 = "3.0.0-beta.0";
160
+ var version = "3.0.0-beta.1";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-X4W4YC3U.js";
10
- import "./chunk-JB4YT5JY.js";
9
+ } from "./chunk-KE2IUVK6.js";
10
+ import "./chunk-M6QG3NPM.js";
11
11
  import {
12
12
  runMigrations
13
13
  } from "./chunk-BH3JMNAV.js";
@@ -19,7 +19,7 @@ import {
19
19
  import "./chunk-55D645EH.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-TQ4HZREX.js";
22
+ } from "./chunk-FH5AN4Z6.js";
23
23
  import {
24
24
  isAuthEnabled,
25
25
  isOutputServer
@@ -13,7 +13,7 @@ if (isAuthEnabled()) {
13
13
  }
14
14
 
15
15
  const logo = {
16
- src: ('/' + (catalog?.logo?.src || 'logo.png')).replace(/^\/+/, '/'),
16
+ src: ('/' + (catalog?.logo?.src || '')).replace(/^\/+/, '/'),
17
17
  alt: catalog?.logo?.alt || 'Event Catalog',
18
18
  text: catalog?.logo?.text || 'EventCatalog',
19
19
  };
@@ -30,7 +30,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
30
30
  <div class="flex-shrink-0 flex items-center w-3/12">
31
31
  <a href={buildUrl(catalog.landingPage || '/')} class="flex space-x-2 items-center group">
32
32
  {
33
- logo.src && (
33
+ logo.src && logo.src !== '/' && (
34
34
  <img alt={logo.alt} src={buildUrl(logo.src, true)} class="w-8 h-8 transition-transform group-hover:scale-105" />
35
35
  )
36
36
  }
@@ -42,7 +42,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
42
42
  </a>
43
43
  </div>
44
44
 
45
- <div class="hidden lg:block flex-grow w-6/12 px-10">
45
+ <div class="hidden lg:block flex-grow -ml-1">
46
46
  <Search />
47
47
  </div>
48
48
 
@@ -118,10 +118,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
118
118
  href="https://discord.com/invite/3rjaZMmrAm"
119
119
  class="block p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
120
120
  >
121
- <img
122
- src={buildUrl('/icons/discord.svg', true)}
123
- class="h-6 w-6 opacity-70 hover:opacity-100 transition-opacity"
124
- />
121
+ <img src={buildUrl('/icons/discord.svg', true)} class="h-6 w-6 hover:opacity-100 transition-opacity" />
125
122
  </a>
126
123
  </li>
127
124
  <li>
@@ -129,10 +126,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
129
126
  href="https://github.com/event-catalog/eventcatalog"
130
127
  class="block p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
131
128
  >
132
- <img
133
- src={buildUrl('/icons/github.svg', true)}
134
- class="h-6 w-6 opacity-70 hover:opacity-100 transition-opacity"
135
- />
129
+ <img src={buildUrl('/icons/github.svg', true)} class="h-6 w-6 hover:opacity-100 transition-opacity" />
136
130
  </a>
137
131
  </li>
138
132
  </ul>
@@ -314,16 +314,6 @@ export default function SchemaExplorer({ schemas, apiAccessEnabled = false }: Sc
314
314
 
315
315
  return (
316
316
  <div className="h-full flex flex-col overflow-hidden">
317
- {/* Compact Header */}
318
- <div className="flex-shrink-0 border-b border-gray-200 pb-2 mb-3">
319
- <div>
320
- <h1 className="text-2xl font-bold text-gray-900">Schema Explorer</h1>
321
- <p className="mt-0.5 text-xs text-gray-600">
322
- {filteredMessages.length} schema{filteredMessages.length !== 1 ? 's' : ''} available
323
- </p>
324
- </div>
325
- </div>
326
-
327
317
  {/* Split View */}
328
318
  <div className="flex-1 flex gap-4 overflow-hidden">
329
319
  {/* Left: Filters + Schema List */}
@@ -4,7 +4,7 @@ import SearchModal from './SearchModal.tsx';
4
4
  ---
5
5
 
6
6
  <div>
7
- <div class="relative flex items-center">
7
+ <div class="relative flex items-center w-10/12">
8
8
  <input
9
9
  id="search-dummy-input"
10
10
  type="text"
@@ -13,7 +13,7 @@ import SearchModal from './SearchModal.tsx';
13
13
  autocomplete="off"
14
14
  class="block w-full rounded-md caret-transparent border-0 py-1.5 pr-14 pl-10 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 font-light sm:text-sm sm:leading-6 px-4"
15
15
  />
16
- <MagnifyingGlassIcon className="absolute inset-y-0 -left-1 h-9 w-8 flex items-center pl-4 text-gray-400" />
16
+ <MagnifyingGlassIcon className="absolute inset-y-0 left-0 h-9 w-8 flex items-center pl-4 text-gray-400" />
17
17
  <div class="absolute inset-y-0 right-0 flex py-1.5 pr-1.5">
18
18
  <kbd class="inline-flex items-center rounded px-1 font-sans text-xs text-gray-400">⌘K</kbd>
19
19
  </div>
@@ -42,13 +42,15 @@ type NavigationLevel = {
42
42
 
43
43
  export default function NestedSideBar() {
44
44
  const data = useStore(sidebarStore);
45
+ const favorites = useStore(favoritesStore);
45
46
 
46
47
  // Guard against undefined data (e.g., during hydration)
47
- const roots = data?.roots ?? [];
48
- const nodes = data?.nodes ?? {};
48
+ // Use useMemo to ensure stable references for roots and nodes
49
+ const roots = useMemo(() => data?.roots ?? [], [data?.roots]);
50
+ const nodes = useMemo(() => data?.nodes ?? {}, [data?.nodes]);
49
51
 
50
- const [navigationStack, setNavigationStack] = useState<NavigationLevel[]>([
51
- { key: null, entries: roots, title: 'Documentation' },
52
+ const [navigationStack, setNavigationStack] = useState<NavigationLevel[]>(() => [
53
+ { key: null, entries: [], title: 'Documentation' },
52
54
  ]);
53
55
  const [animationKey, setAnimationKey] = useState(0);
54
56
  const [slideDirection, setSlideDirection] = useState<'forward' | 'backward' | null>(null);
@@ -57,7 +59,6 @@ export default function NestedSideBar() {
57
59
  const [collapsedSections, setCollapsedSections] = useState<Set<string>>(new Set());
58
60
  const [showPathPreview, setShowPathPreview] = useState(false);
59
61
  const [showFullPath, setShowFullPath] = useState(false);
60
- const favorites = useStore(favoritesStore);
61
62
  const [isSearching, setIsSearching] = useState(false);
62
63
 
63
64
  // Build a lookup map for faster URL navigation
@@ -113,6 +114,21 @@ export default function NestedSideBar() {
113
114
  }
114
115
  }, []);
115
116
 
117
+ /**
118
+ * Update navigation stack when roots become available
119
+ */
120
+ useEffect(() => {
121
+ if (roots.length > 0) {
122
+ setNavigationStack((prevStack) => {
123
+ // Only update if the current stack has no entries (initial state)
124
+ if (prevStack.length === 1 && prevStack[0].entries.length === 0) {
125
+ return [{ key: null, entries: roots, title: 'Documentation' }];
126
+ }
127
+ return prevStack;
128
+ });
129
+ }
130
+ }, [roots]);
131
+
116
132
  /**
117
133
  * Populate the store with the data when the component mounts or data changes
118
134
  */
@@ -300,43 +316,47 @@ export default function NestedSideBar() {
300
316
  const foundNodeKey = findNodeKeyByUrl(url);
301
317
 
302
318
  if (foundNodeKey) {
303
- // Try to connect to current stack first
304
- const connectedStack = tryConnectStack(foundNodeKey, navigationStack);
319
+ setNavigationStack((currentStack) => {
320
+ // Try to connect to current stack first
321
+ const connectedStack = tryConnectStack(foundNodeKey, currentStack);
305
322
 
306
- if (connectedStack) {
307
- setNavigationStack(connectedStack);
308
- return true;
309
- }
323
+ if (connectedStack) {
324
+ return connectedStack;
325
+ }
310
326
 
311
- const foundNode = nodes[foundNodeKey];
312
- if (foundNode && foundNode.pages && foundNode.pages.length > 0) {
313
- // Fallback: Flattened navigation
314
- setNavigationStack([
315
- { key: null, entries: roots, title: 'Documentation' },
316
- { key: foundNodeKey, entries: foundNode.pages, title: foundNode.title, badge: foundNode.badge },
317
- ]);
318
- return true;
319
- }
327
+ const foundNode = nodes[foundNodeKey];
328
+ if (foundNode && foundNode.pages && foundNode.pages.length > 0) {
329
+ // Fallback: Flattened navigation
330
+ return [
331
+ { key: null, entries: roots, title: 'Documentation' },
332
+ { key: foundNodeKey, entries: foundNode.pages, title: foundNode.title, badge: foundNode.badge },
333
+ ];
334
+ }
335
+
336
+ return currentStack;
337
+ });
338
+ return true;
320
339
  } else if (url === '/' || url === '') {
321
340
  // Reset to root if we are on homepage
322
- if (navigationStack.length > 1) {
323
- setSlideDirection('backward');
324
- setAnimationKey((prev) => prev + 1);
325
- }
326
- setNavigationStack([{ key: null, entries: roots, title: 'Documentation' }]);
341
+ setNavigationStack((currentStack) => {
342
+ if (currentStack.length > 1) {
343
+ setSlideDirection('backward');
344
+ setAnimationKey((prev) => prev + 1);
345
+ }
346
+ return [{ key: null, entries: roots, title: 'Documentation' }];
347
+ });
327
348
  return true;
328
349
  }
329
350
  return false;
330
351
  },
331
- [findNodeKeyByUrl, tryConnectStack, navigationStack, nodes, roots]
352
+ [findNodeKeyByUrl, tryConnectStack, nodes, roots]
332
353
  );
333
354
 
334
355
  /**
335
356
  * Restore state from localStorage on mount, or navigate to URL
336
357
  */
337
358
  useEffect(() => {
338
- if (!data || roots.length === 0) return;
339
- if (isInitialized) return;
359
+ if (!data || roots.length === 0 || isInitialized) return;
340
360
 
341
361
  const currentUrl = window.location.pathname;
342
362
 
@@ -387,7 +407,7 @@ export default function NestedSideBar() {
387
407
  }
388
408
 
389
409
  setIsInitialized(true);
390
- }, [data, roots, buildStackFromPath, isInitialized, findNodeKeyByUrl, tryConnectStack, nodes]);
410
+ }, [data, roots, nodes, isInitialized, buildStackFromPath, findNodeKeyByUrl, tryConnectStack]);
391
411
 
392
412
  /**
393
413
  * Save state whenever navigation changes
@@ -750,10 +770,7 @@ export default function NestedSideBar() {
750
770
  <div className="flex items-center gap-2.5 min-w-0 flex-1 ">
751
771
  {IconComponent && (
752
772
  <span
753
- className={cn(
754
- 'flex items-center justify-center w-5 h-5 flex-shrink-0',
755
- isActive ? 'text-purple-600' : 'text-gray-500'
756
- )}
773
+ className={cn('flex items-center justify-center w-5 h-5 flex-shrink-0', isActive ? 'text-black' : 'text-gray-500')}
757
774
  >
758
775
  <IconComponent className="w-4 h-4" />
759
776
  </span>
@@ -761,7 +778,7 @@ export default function NestedSideBar() {
761
778
  <span
762
779
  className={cn(
763
780
  'text-[13px] truncate',
764
- isActive ? 'text-purple-600 font-medium' : 'text-gray-600 group-hover:text-gray-900'
781
+ isActive ? 'text-black font-medium' : 'text-gray-600 group-hover:text-gray-900'
765
782
  )}
766
783
  >
767
784
  {item.title}
@@ -782,7 +799,7 @@ export default function NestedSideBar() {
782
799
  </button>
783
800
  )}
784
801
  {itemHasChildren && (
785
- <span className="flex items-center justify-center w-5 h-5 text-gray-400 group-hover:text-purple-500 group-hover:translate-x-0.5 transition-transform">
802
+ <span className="flex items-center justify-center w-5 h-5 text-gray-400 group-hover:text-black group-hover:translate-x-0.5 transition-transform">
786
803
  <ChevronRight className="w-4 h-4" />
787
804
  </span>
788
805
  )}
@@ -793,7 +810,7 @@ export default function NestedSideBar() {
793
810
  const baseClasses =
794
811
  'group flex items-center justify-between w-full px-3 py-1 rounded-lg cursor-pointer text-left transition-colors hover:bg-gray-100 active:bg-gray-200';
795
812
  const parentClasses = itemHasChildren ? 'font-medium' : '';
796
- const activeClasses = isActive ? 'bg-purple-100 hover:bg-purple-100 border-l-4 border-purple-600 rounded-l-none' : '';
813
+ const activeClasses = isActive ? 'bg-gray-200 hover:bg-gray-200 border-l-4 border-black rounded-l-none' : '';
797
814
 
798
815
  // Leaf item with href → render as link
799
816
  if (item.href && !itemHasChildren) {
@@ -899,7 +916,7 @@ export default function NestedSideBar() {
899
916
  className={cn(
900
917
  'flex items-center gap-2 px-2 py-1.5 rounded text-left transition-colors',
901
918
  !isCurrentLevel && 'hover:bg-gray-100 cursor-pointer',
902
- isCurrentLevel && 'bg-purple-50 cursor-default'
919
+ isCurrentLevel && 'bg-gray-200 cursor-default'
903
920
  )}
904
921
  style={{ paddingLeft: `${displayIndex * 12 + 8}px` }}
905
922
  >
@@ -909,10 +926,7 @@ export default function NestedSideBar() {
909
926
  <ChevronRight className="w-3.5 h-3.5 text-gray-300 flex-shrink-0" />
910
927
  )}
911
928
  <span
912
- className={cn(
913
- 'text-sm truncate',
914
- isCurrentLevel ? 'font-medium text-purple-700' : 'text-gray-600'
915
- )}
929
+ className={cn('text-sm truncate', isCurrentLevel ? 'font-medium text-black' : 'text-gray-600')}
916
930
  >
917
931
  {level.title}
918
932
  </span>
@@ -1000,14 +1014,14 @@ export default function NestedSideBar() {
1000
1014
  onClick={() => navigateToFavorite(fav)}
1001
1015
  className={cn(
1002
1016
  'group flex items-center justify-between w-full px-3 py-1.5 rounded-lg cursor-pointer text-left transition-colors hover:bg-amber-50 active:bg-amber-100',
1003
- isActive && 'bg-purple-100 hover:bg-purple-100 border-l-4 border-purple-600 rounded-l-none'
1017
+ isActive && 'bg-gray-200 hover:bg-gray-200 border-l-4 border-black rounded-l-none'
1004
1018
  )}
1005
1019
  >
1006
1020
  <div className="flex items-center gap-2.5 min-w-0 flex-1">
1007
1021
  <span
1008
1022
  className={cn(
1009
1023
  'text-[14px] truncate',
1010
- isActive ? 'text-purple-600 font-medium' : 'text-gray-600 group-hover:text-gray-900'
1024
+ isActive ? 'text-black font-medium' : 'text-gray-600 group-hover:text-gray-900'
1011
1025
  )}
1012
1026
  >
1013
1027
  {fav.title}
@@ -1034,7 +1048,7 @@ export default function NestedSideBar() {
1034
1048
  <Star className="w-3.5 h-3.5 fill-current" />
1035
1049
  </button>
1036
1050
  {node?.pages && node.pages.length > 0 && (
1037
- <span className="flex items-center justify-center w-5 h-5 text-gray-400 group-hover:text-purple-500">
1051
+ <span className="flex items-center justify-center w-5 h-5 text-gray-400 group-hover:text-black">
1038
1052
  <ChevronRight className="w-4 h-4" />
1039
1053
  </span>
1040
1054
  )}
@@ -80,7 +80,7 @@ const ownersList = filteredOwners.map((o) => ({
80
80
  const badges = doc?.badges || [];
81
81
  ---
82
82
 
83
- <VerticalSideBarLayout title={doc.title || 'Documentation'}>
83
+ <VerticalSideBarLayout title={doc.title || 'Documentation'} showNestedSideBar={false}>
84
84
  <div class="flex w-full" data-pagefind-body data-pagefind-meta={`title:${doc.title}`}>
85
85
  <!-- Left Sidebar Navigation -->
86
86
  <aside class="sidebar-transition overflow-y-auto bg-white border-r border-gray-100 w-80 fixed top-16 bottom-0 z-10">
@@ -29,7 +29,7 @@ const chatPrompts = await getChatPromptsGroupedByCategory();
29
29
  const resources = allItems.map((item) => ({ id: item.data.id, type: item.collection, name: item.data.name }));
30
30
  ---
31
31
 
32
- <VerticalSideBarLayout title="AI Chat">
32
+ <VerticalSideBarLayout title="AI Chat" showNestedSideBar={false}>
33
33
  <div class="flex h-[calc(100vh-60px)] bg-white">
34
34
  {
35
35
  isEnabled ? (
@@ -48,7 +48,7 @@ const tabs = [
48
48
  ];
49
49
  ---
50
50
 
51
- <VerticalSideBarLayout title={`Explore | ${title}`}>
51
+ <VerticalSideBarLayout title={`Explore | ${title}`} showNestedSideBar={false}>
52
52
  <main class="ml-0">
53
53
  <div id="discover-collection-tabs">
54
54
  <div class="hidden sm:block">
@@ -106,7 +106,7 @@ const tabs = [
106
106
  ];
107
107
  ---
108
108
 
109
- <VerticalSideBarLayout title={`Explore | ${title}`}>
109
+ <VerticalSideBarLayout title={`Explore | ${title}`} showNestedSideBar={false}>
110
110
  <main class="ml-0">
111
111
  <div id="discover-collection-tabs">
112
112
  <div class="hidden sm:block">
@@ -3,22 +3,19 @@ interface Props {
3
3
  title: string;
4
4
  sidebar?: boolean;
5
5
  description?: string;
6
+ showNestedSideBar?: boolean;
6
7
  }
7
8
 
8
9
  import {
9
- BookOpenText,
10
- Workflow,
11
10
  TableProperties,
12
- House,
13
- BookUser,
14
11
  BotMessageSquare,
15
12
  Users,
13
+ BookOpen,
16
14
  Sparkles,
17
15
  Rocket,
18
16
  FileText,
19
17
  SquareDashedMousePointerIcon,
20
- PackageSearch,
21
- FileJson,
18
+ MailSearch,
22
19
  } from 'lucide-react';
23
20
  import Header from '../components/Header.astro';
24
21
  import SEO from '../components/Seo.astro';
@@ -41,6 +38,8 @@ import { buildUrl } from '@utils/url-builder';
41
38
  import { getQueries } from '@utils/collections/queries';
42
39
  import { hasLandingPageForDocs } from '@utils/pages';
43
40
 
41
+ import { isEventCatalogUpgradeEnabled, isEmbedEnabled } from '@utils/feature';
42
+
44
43
  const catalogHasDefaultLandingPageForDocs = await hasLandingPageForDocs();
45
44
  const customDocs = await getCollection('customPages');
46
45
 
@@ -62,8 +61,6 @@ if (!catalogHasDefaultLandingPageForDocs) {
62
61
  ]);
63
62
  }
64
63
 
65
- import { isEventCatalogUpgradeEnabled, isVisualiserEnabled } from '@utils/feature';
66
-
67
64
  // Try and load any custom styles if they exist
68
65
  try {
69
66
  await import('../../eventcatalog.styles.css');
@@ -105,8 +102,8 @@ const userSideBarConfiguration = config.sidebar || [];
105
102
  const navigationItems = [
106
103
  {
107
104
  id: '/',
108
- label: 'Home',
109
- icon: House,
105
+ label: 'Documentation',
106
+ icon: BookOpen,
110
107
  href: buildUrl(config.landingPage || '/'),
111
108
  current:
112
109
  currentPath === '/' ||
@@ -114,8 +111,6 @@ const navigationItems = [
114
111
  currentPath.includes('/architecture/') ||
115
112
  currentPath.includes('/visualiser') ||
116
113
  (currentPath.includes('/schemas') && !currentPath.includes('/schemas/explorer')),
117
- sidebar: true,
118
- hidden: false,
119
114
  },
120
115
  {
121
116
  id: '/discover',
@@ -123,22 +118,13 @@ const navigationItems = [
123
118
  icon: TableProperties,
124
119
  href: buildUrl('/discover/events'),
125
120
  current: currentPath.includes('/discover/'),
126
- sidebar: false,
127
- },
128
- {
129
- id: '/schemas',
130
- label: 'Schema Explorer',
131
- icon: FileJson,
132
- sidebar: true,
133
- hidden: true,
134
121
  },
135
122
  {
136
123
  id: '/schemas/explorer',
137
124
  label: 'Schema Explorer',
138
- icon: FileJson,
125
+ icon: MailSearch,
139
126
  href: buildUrl('/schemas/explorer'),
140
127
  current: currentPath.includes('/schemas/explorer'),
141
- sidebar: false,
142
128
  },
143
129
  {
144
130
  id: '/directory',
@@ -146,16 +132,6 @@ const navigationItems = [
146
132
  icon: Users,
147
133
  href: buildUrl('/directory/users'),
148
134
  current: currentPath.includes('/directory'),
149
- sidebar: false,
150
- },
151
- {
152
- id: '/architecture',
153
- label: 'Architecture',
154
- icon: BookUser,
155
- href: buildUrl('/architecture/domains'),
156
- current: currentPath.includes('/architecture/'),
157
- sidebar: true,
158
- hidden: true,
159
135
  },
160
136
  ].filter((item) => {
161
137
  const userSideBarOption = userSideBarConfiguration.find((config: { id: string; visible: boolean }) => config.id === item.id);
@@ -169,7 +145,6 @@ const studioNavigationItem = [
169
145
  icon: SquareDashedMousePointerIcon,
170
146
  href: buildUrl('/studio'),
171
147
  current: currentPath.includes('/studio'),
172
- sidebar: false,
173
148
  },
174
149
  ].filter((item) => {
175
150
  const userSideBarOption = userSideBarConfiguration.find((config: { id: string; visible: boolean }) => config.id === item.id);
@@ -183,7 +158,6 @@ const premiumFeatures = [
183
158
  icon: FileText,
184
159
  href: getDefaultUrl('docs/custom', '/docs/custom'),
185
160
  current: currentPath.includes('/docs/custom'),
186
- sidebar: false,
187
161
  isPremium: true,
188
162
  },
189
163
  {
@@ -200,11 +174,9 @@ const premiumFeatures = [
200
174
  });
201
175
 
202
176
  const currentNavigationItem = [...navigationItems, ...studioNavigationItem, ...premiumFeatures].find((item) => item.current);
203
- const { title, description } = Astro.props;
177
+ const { title, description, showNestedSideBar = true } = Astro.props;
204
178
 
205
- const showSideBarOnLoad = currentNavigationItem?.sidebar;
206
-
207
- const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
179
+ const canPageBeEmbedded = isEmbedEnabled();
208
180
  ---
209
181
 
210
182
  <!doctype html>
@@ -270,29 +242,25 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
270
242
  <nav class="flex flex-col h-[calc(100vh-70px)] justify-between">
271
243
  <div class="flex flex-col items-center flex-1 space-y-6">
272
244
  {
273
- navigationItems
274
- .filter((item) => !item.hidden)
275
- .map((item) => {
276
- return (
277
- <a
278
- id={item.id}
279
- data-role="nav-item"
280
- href={item.href}
281
- class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${
282
- item.current
283
- ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700'
284
- : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'
285
- }`}
286
- >
287
- <div class="has-tooltip">
288
- <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
289
- {item.label}
290
- </span>
291
- <item.icon className="h-6 w-6" />
292
- </div>
293
- </a>
294
- );
295
- })
245
+ navigationItems.map((item) => {
246
+ return (
247
+ <a
248
+ id={item.id}
249
+ data-role="nav-item"
250
+ href={item.href}
251
+ class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${
252
+ item.current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'
253
+ }`}
254
+ >
255
+ <div class="has-tooltip">
256
+ <span class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap">
257
+ {item.label}
258
+ </span>
259
+ <item.icon className="h-6 w-6" />
260
+ </div>
261
+ </a>
262
+ );
263
+ })
296
264
  }
297
265
 
298
266
  <hr class="w-8 border-t border-gray-200" />
@@ -303,10 +271,10 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
303
271
  id={studioNavigationItem[0].id}
304
272
  data-role="nav-item"
305
273
  href={studioNavigationItem[0].href}
306
- class={`p-1.5 inline-block pt-1 pb-1 mt-0 mb-0 transition-colors duration-200 rounded-lg relative ${studioNavigationItem[0].current ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700' : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'}`}
274
+ class={`p-1.5 inline-block pt-1 pb-1 mt-0 mb-0 transition-colors duration-200 rounded-lg relative ${studioNavigationItem[0].current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'}`}
307
275
  >
308
276
  <div class="has-tooltip">
309
- <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
277
+ <span class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap">
310
278
  {studioNavigationItem[0].label}
311
279
  </span>
312
280
  <SquareDashedMousePointerIcon className="h-6 w-6" />
@@ -324,13 +292,11 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
324
292
  data-role="nav-item"
325
293
  href={item.href}
326
294
  class={`p-1.5 inline-block transition-colors duration-200 rounded-lg mb-8 relative ${
327
- item.current
328
- ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700'
329
- : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'
295
+ item.current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'
330
296
  }`}
331
297
  >
332
298
  <div class="has-tooltip">
333
- <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-indigo-500 to-indigo-700 text-white ml-10 flex items-center gap-1">
299
+ <span class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 flex items-center gap-1 whitespace-nowrap">
334
300
  <Sparkles className="h-3 w-3" /> {item.label}
335
301
  </span>
336
302
  <item.icon className="h-6 w-6" />
@@ -350,10 +316,10 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
350
316
  id="/pro"
351
317
  data-role="nav-item"
352
318
  href={buildUrl('/plans')}
353
- class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${currentPath.includes('/pro') ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700' : 'bg-gradient-to-r from-purple-100 to-indigo-100 hover:from-purple-500 hover:to-purple-700 hover:text-white text-purple-700'}`}
319
+ class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${currentPath.includes('/pro') ? 'text-white bg-gray-900' : 'bg-gray-200 hover:bg-gray-800 hover:text-white text-gray-700'}`}
354
320
  >
355
321
  <div class="has-tooltip">
356
- <span class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10">
322
+ <span class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap">
357
323
  Upgrade EventCatalog
358
324
  </span>
359
325
  <Rocket className="h-6 w-6" />
@@ -365,13 +331,14 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
365
331
  </nav>
366
332
  </div>
367
333
 
368
- <SideNav
369
- id="sidebar"
370
- class={`sidebar-transition h-content bg-white border-r border-gray-100 w-[320px] ml-14 ${showSideBarOnLoad ? 'block' : 'hidden'}`}
371
- />
334
+ {
335
+ showNestedSideBar && (
336
+ <SideNav id="sidebar" class={`sidebar-transition h-content bg-white border-r border-gray-100 w-[320px] ml-14`} />
337
+ )
338
+ }
372
339
  </aside>
373
340
  <main
374
- class={`sidebar-transition w-full max-h-content overflow-y-auto ${showSideBarOnLoad ? 'ml-0' : 'ml-14'}`}
341
+ class={`sidebar-transition w-full max-h-content overflow-y-auto ${showNestedSideBar ? 'ml-0' : 'ml-14'}`}
375
342
  id="content"
376
343
  >
377
344
  <slot />
@@ -396,7 +363,7 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
396
363
  </body>
397
364
  </html>
398
365
  <ClientRouter />
399
- <script define:vars={{ navigationItems, currentNavigationItem, showSideBarOnLoad, canPageBeEmbedded }}>
366
+ <script define:vars={{ navigationItems, currentNavigationItem, canPageBeEmbedded }}>
400
367
  // Listen for Astro transititions
401
368
  document.addEventListener('astro:page-load', () => {
402
369
  document.dispatchEvent(new CustomEvent('contentLoaded'));
@@ -440,45 +407,6 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
440
407
  return;
441
408
  }
442
409
 
443
- const sidebar = document.getElementById('sidebar');
444
- const currentPath = window.location.pathname;
445
-
446
- // Determine if we should show the sidebar based on current path
447
- let shouldShowSidebar = false;
448
-
449
- // Check each navigation item to see if it matches current path and has sidebar enabled
450
- for (const item of navigationItems) {
451
- if (!item.sidebar) continue; // Skip items that don't have sidebar
452
-
453
- if (item.id === '/') {
454
- // Home route - show sidebar for home, docs, architecture, visualiser, schemas (not explorer)
455
- if (
456
- currentPath === '/' ||
457
- (currentPath.includes('/docs') && !currentPath.includes('/docs/custom')) ||
458
- currentPath.includes('/architecture/') ||
459
- currentPath.includes('/visualiser') ||
460
- (currentPath.includes('/schemas') && !currentPath.includes('/schemas/explorer'))
461
- ) {
462
- shouldShowSidebar = true;
463
- break;
464
- }
465
- } else if (currentPath.includes(item.id)) {
466
- // Other routes - simple match
467
- shouldShowSidebar = true;
468
- break;
469
- }
470
- }
471
-
472
- // Show or hide sidebar based on result
473
- if (shouldShowSidebar) {
474
- sidebar.style.display = 'block';
475
- content.classList.remove('ml-14');
476
- } else {
477
- sidebar.style.display = 'none';
478
- content.style.width = '100%';
479
- content.classList.add('ml-14');
480
- }
481
-
482
410
  const navItems = document.querySelectorAll('[data-role="nav-item"]');
483
411
 
484
412
  // Navigation items simply navigate to their href - no toggle logic
@@ -492,46 +420,5 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
492
420
  }
493
421
  });
494
422
  });
495
-
496
- function showSidebar() {
497
- if (!sidebar || !content) return;
498
- isOpen = true;
499
- localStorage.setItem('sidebarState', 'open');
500
- sidebar.style.display = 'block';
501
- setTimeout(() => {
502
- sidebar.style.transform = 'translateX(0)';
503
- content.style.transform = 'translateX(0)';
504
- content.classList.remove('ml-14');
505
- content.style.width = 'calc(100% - 240px)';
506
- }, 10);
507
- }
508
-
509
- function hideSidebar() {
510
- if (!sidebar || !content) return;
511
- isOpen = false;
512
- sidebar.style.transform = 'translateX(-100%)';
513
- content.style.transform = 'translateX(0px)';
514
- content.style.width = '100%';
515
- content.classList.add('ml-14');
516
- }
517
-
518
- if (sidebar) {
519
- sidebar.addEventListener('transitionend', () => {
520
- if (!isOpen && sidebar && content) {
521
- sidebar.style.display = 'none';
522
- content.style.transform = 'translateX(0px)';
523
- }
524
- });
525
- }
526
-
527
- // Listen for custom sidebar toggle event from React components
528
- window.addEventListener('sidebarToggle', (event) => {
529
- const { action } = event.detail;
530
- if (action === 'hide') {
531
- hideSidebar();
532
- } else if (action === 'show') {
533
- showSidebar();
534
- }
535
- });
536
423
  });
537
424
  </script>
@@ -19,7 +19,7 @@ if (hasChatLicense) {
19
19
  <title>EventCatalog chat?</title>
20
20
  </head>
21
21
  <body>
22
- <VerticalSideBarLayout title="AI Chat">
22
+ <VerticalSideBarLayout title="AI Chat" showNestedSideBar={false}>
23
23
  <div class="min-h-[calc(100vh-60px)] bg-white">
24
24
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
25
25
  {/* Hero Section */}
@@ -275,7 +275,7 @@ nodeGraphs.push({
275
275
 
276
276
  <VerticalSideBarLayout title={pageTitle} description={props.data.summary}>
277
277
  <main class="flex docs-layout h-full" {...pagefindAttributes}>
278
- <div class="flex docs-layout w-full pl-16 pr-24">
278
+ <div class="flex docs-layout w-full pl-16">
279
279
  <div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
280
280
  <div class="border-b border-gray-200 md:pb-2">
281
281
  <div>
@@ -286,7 +286,7 @@ nodeGraphs.push({
286
286
  class={`text-2xl md:text-4xl font-bold text-black ${props.data.deprecated && hasDeprecated ? 'text-red-500' : ''}`}
287
287
  >
288
288
  {props.data.name}
289
- <span class="">(v{props.data.version})</span>
289
+ {props.data.latestVersion !== props.data.version && <span>(v{props.data.version})</span>}
290
290
  </h2>
291
291
  <FavoriteButton
292
292
  client:load
@@ -491,8 +491,8 @@ nodeGraphs.push({
491
491
  }
492
492
  </div>
493
493
  </div>
494
- <aside class="hidden lg:block sticky top-0 pb-10 w-80 overflow-y-auto bg-white py-2 flex-shrink-0">
495
- <div class="py-4 mt-4 space-y-8">
494
+ <aside class="hidden xl:block sticky top-0 pb-10 w-[280px] overflow-y-auto py-2 flex-shrink-0 pr-10">
495
+ <div class="mt-4 space-y-8">
496
496
  {
497
497
  headings.length > 0 && (
498
498
  <div>
@@ -3,7 +3,7 @@ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
3
  import { BookOpenIcon, FileText } from 'lucide-react';
4
4
  ---
5
5
 
6
- <VerticalSideBarLayout title="Custom Documentation">
6
+ <VerticalSideBarLayout title="Custom Documentation" showNestedSideBar={false}>
7
7
  <div class="min-h-[calc(100vh-60px)] bg-white">
8
8
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
9
9
  {/* Hero Section */}
@@ -98,7 +98,7 @@ if (!isCustomDocsEnabled()) {
98
98
  }
99
99
  ---
100
100
 
101
- <VerticalSideBarLayout title="Custom Documentation">
101
+ <VerticalSideBarLayout title="Custom Documentation" showNestedSideBar={false}>
102
102
  <body class="min-h-screen font-inter">
103
103
  <main class="container px-8 lg:px-8 mx-auto py-8 max-w-[80em]">
104
104
  <div class="mb-12">
@@ -16,7 +16,7 @@ import {
16
16
  } from 'lucide-react';
17
17
  ---
18
18
 
19
- <VerticalSideBarLayout title="EventCatalog Pro">
19
+ <VerticalSideBarLayout title="EventCatalog Pro" showNestedSideBar={false}>
20
20
  <div class="min-h-[calc(100vh-60px)] bg-white">
21
21
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
22
22
  {/* Hero Section */}
@@ -162,7 +162,7 @@ const allSchemas = [...messagesWithSchemas, ...flatServicesWithSpecs];
162
162
  const apiAccessEnabled = isEventCatalogScaleEnabled();
163
163
  ---
164
164
 
165
- <VerticalSideBarLayout title="Schema Explorer - EventCatalog">
165
+ <VerticalSideBarLayout title="Schema Explorer - EventCatalog" showNestedSideBar={false}>
166
166
  <main class="flex sm:px-8 docs-layout h-[calc(100vh-var(--header-height,0px)-64px)]">
167
167
  <div class="flex docs-layout w-full h-full">
168
168
  <div class="w-full lg:mr-2 pr-8 py-6 flex flex-col h-full">
@@ -44,7 +44,7 @@ const resourcesToShow = [
44
44
  <title>EventCatalog Studio</title>
45
45
  </head>
46
46
  <body>
47
- <VerticalSideBarLayout title="EventCatalog Studio">
47
+ <VerticalSideBarLayout title="EventCatalog Studio" showNestedSideBar={false}>
48
48
  <div class="min-h-[calc(100vh-60px)] bg-white">
49
49
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
50
50
  {/* Hero Section */}
@@ -2,7 +2,7 @@
2
2
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
3
  ---
4
4
 
5
- <VerticalSideBarLayout title="Unauthorized - EventCatalog">
5
+ <VerticalSideBarLayout title="Unauthorized - EventCatalog" showNestedSideBar={false}>
6
6
  <div class="flex h-[calc(100vh-120px)] bg-white">
7
7
  <main class="flex w-full items-center justify-center bg-white text-center sm:p-12">
8
8
  <div class="w-full max-w-xl text-center">
@@ -2,7 +2,7 @@ import { getCollection } from 'astro:content';
2
2
  import type { CollectionEntry } from 'astro:content';
3
3
  import path from 'path';
4
4
  import type { CollectionMessageTypes } from '@types';
5
- import type { Service } from './services';
5
+ import type { Service } from './types';
6
6
  import utils from '@eventcatalog/sdk';
7
7
  import { createVersionedMap, findInMap } from '@utils/collections/util';
8
8
 
@@ -0,0 +1,6 @@
1
+ import type { CollectionEntry } from 'astro:content';
2
+
3
+ // Shared types to avoid circular dependencies between domains.ts and services.ts
4
+ export type Service = CollectionEntry<'services'>;
5
+ export type Domain = CollectionEntry<'domains'>;
6
+ export type UbiquitousLanguage = CollectionEntry<'ubiquitousLanguages'>;
@@ -21,6 +21,8 @@ export const isEventCatalogScaleEnabled = () => process.env.EVENTCATALOG_SCALE =
21
21
 
22
22
  export const isPrivateRemoteSchemaEnabled = () => isEventCatalogScaleEnabled() || isEventCatalogStarterEnabled();
23
23
 
24
+ export const isEmbedEnabled = () => process.env.ENABLE_EMBED === 'true';
25
+
24
26
  export const showEventCatalogBranding = () => {
25
27
  const override = process.env.EVENTCATALOG_SHOW_BRANDING;
26
28
  // if any value we return true
@@ -21,5 +21,6 @@
21
21
  "jsx": "react-jsx",
22
22
  "jsxImportSource": "react",
23
23
  "types": ["vitest/globals"]
24
- }
24
+ },
25
+ "exclude": ["**/*.spec.ts", "**/*.test.ts"]
25
26
  }
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "3.0.0-beta.0",
9
+ "version": "3.0.0-beta.1",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },