@eventcatalog/core 3.29.2 → 3.31.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 (113) 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-36IA4UE4.js → chunk-7IGMIOQF.js} +1 -1
  6. package/dist/{chunk-EGQGCB2B.js → chunk-HVOLSUC2.js} +1 -1
  7. package/dist/{chunk-DB4IQ3GB.js → chunk-LWVHWR77.js} +1 -1
  8. package/dist/{chunk-VEUNSJ6Z.js → chunk-QIJOBQZ7.js} +1 -1
  9. package/dist/{chunk-MEJOYC5Z.js → chunk-UY5QDWK7.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +5 -5
  14. package/dist/generate.cjs +1 -1
  15. package/dist/generate.js +3 -3
  16. package/dist/utils/cli-logger.cjs +1 -1
  17. package/dist/utils/cli-logger.js +2 -2
  18. package/eventcatalog/astro.config.mjs +11 -7
  19. package/eventcatalog/public/logo.png +0 -0
  20. package/eventcatalog/src/components/CopyAsMarkdown.tsx +29 -24
  21. package/eventcatalog/src/components/EnvironmentDropdown.tsx +33 -21
  22. package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +3 -53
  23. package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +144 -91
  24. package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +112 -109
  25. package/eventcatalog/src/components/Header.astro +9 -19
  26. package/eventcatalog/src/components/MDX/Accordion/Accordion.tsx +12 -14
  27. package/eventcatalog/src/components/MDX/Accordion/AccordionGroup.astro +11 -3
  28. package/eventcatalog/src/components/MDX/Design/Design.astro +1 -1
  29. package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +15 -5
  30. package/eventcatalog/src/components/MDX/Tiles/Tile.astro +11 -8
  31. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +164 -53
  32. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +1 -1
  33. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +4 -4
  34. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +12 -10
  35. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +48 -77
  36. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +238 -169
  37. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +189 -230
  38. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +39 -36
  39. package/eventcatalog/src/components/Search/Search.astro +1 -1
  40. package/eventcatalog/src/components/Seo.astro +1 -1
  41. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +218 -0
  42. package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +265 -0
  43. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +371 -0
  44. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +183 -0
  45. package/eventcatalog/src/components/Settings/LogoUpload.tsx +137 -0
  46. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +91 -0
  47. package/eventcatalog/src/components/Settings/ReadOnlyBanner.tsx +18 -0
  48. package/eventcatalog/src/components/Settings/Row.tsx +59 -0
  49. package/eventcatalog/src/components/Settings/SettingsShared.tsx +176 -0
  50. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +3 -3
  51. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +233 -261
  52. package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +116 -68
  53. package/eventcatalog/src/components/Tables/Discover/FilterComponents.tsx +2 -2
  54. package/eventcatalog/src/components/Tables/Discover/columns.tsx +130 -197
  55. package/eventcatalog/src/components/Tables/Table.tsx +21 -18
  56. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +79 -131
  57. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +104 -175
  58. package/eventcatalog/src/content.config.ts +1 -1
  59. package/eventcatalog/src/enterprise/auth/error.astro +1 -1
  60. package/eventcatalog/src/enterprise/auth/login.astro +1 -1
  61. package/eventcatalog/src/enterprise/auth/middleware/middleware-auth.ts +11 -7
  62. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +97 -95
  63. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +232 -181
  64. package/eventcatalog/src/enterprise/feature.ts +2 -1
  65. package/eventcatalog/src/enterprise/fields/pages/fields.astro +10 -8
  66. package/eventcatalog/src/enterprise/integrations/eventcatalog-features.ts +0 -8
  67. package/eventcatalog/src/layouts/DirectoryLayout.astro +17 -88
  68. package/eventcatalog/src/layouts/SettingsLayout.astro +116 -0
  69. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +562 -141
  70. package/eventcatalog/src/layouts/VisualiserLayout.astro +7 -2
  71. package/eventcatalog/src/pages/_index.astro +253 -256
  72. package/eventcatalog/src/pages/api/settings/ai.ts +57 -0
  73. package/eventcatalog/src/pages/api/settings/general.ts +71 -0
  74. package/eventcatalog/src/pages/api/settings/logo.ts +113 -0
  75. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -3
  76. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +223 -73
  77. package/eventcatalog/src/pages/discover/[type]/index.astro +22 -141
  78. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +130 -30
  79. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +147 -53
  80. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +6 -2
  81. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +2 -2
  82. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +22 -19
  83. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +71 -61
  84. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +5 -1
  85. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +3 -3
  86. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +6 -32
  87. package/eventcatalog/src/pages/docs/llm/llms.txt.ts +5 -1
  88. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +11 -4
  89. package/eventcatalog/src/pages/docs/users/[id]/index.astro +12 -5
  90. package/eventcatalog/src/pages/schemas/explorer/index.astro +10 -8
  91. package/eventcatalog/src/pages/settings/assistant.astro +37 -0
  92. package/eventcatalog/src/pages/settings/billing.astro +17 -0
  93. package/eventcatalog/src/pages/settings/general.astro +32 -0
  94. package/eventcatalog/src/pages/settings/index.astro +21 -0
  95. package/eventcatalog/src/pages/settings/llm-access.astro +34 -0
  96. package/eventcatalog/src/pages/settings/mcp.astro +14 -0
  97. package/eventcatalog/src/pages/studio.astro +1 -1
  98. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +2 -7
  99. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +2 -2
  100. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +2 -7
  101. package/eventcatalog/src/styles/theme.css +95 -30
  102. package/eventcatalog/src/styles/themes/forest.css +17 -9
  103. package/eventcatalog/src/styles/themes/ocean.css +10 -2
  104. package/eventcatalog/src/styles/themes/sapphire.css +10 -2
  105. package/eventcatalog/src/styles/themes/sunset.css +25 -17
  106. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +13 -0
  107. package/eventcatalog/src/utils/eventcatalog-config/config-schema.ts +49 -0
  108. package/eventcatalog/src/utils/eventcatalog-config/config-writer.ts +149 -0
  109. package/eventcatalog/src/utils/url-builder.ts +4 -2
  110. package/package.json +7 -5
  111. package/eventcatalog/public/logo.svg +0 -14
  112. package/eventcatalog/src/enterprise/plans/index.astro +0 -319
  113. package/eventcatalog/src/pages/docs/llm/llms-services.txt.ts +0 -81
@@ -2,22 +2,20 @@
2
2
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
3
  import { render } from 'astro:content';
4
4
  import config from '@config';
5
- import { AlignLeftIcon } from 'lucide-react';
5
+ import { AlignLeftIcon, UserIcon, UsersIcon } from 'lucide-react';
6
6
 
7
7
  import mdxComponents from '@components/MDX/components';
8
- import OwnersList from '@components/Lists/OwnersList';
9
8
 
10
9
  import { getOwner } from '@utils/collections/owners';
11
- import { buildUrl } from '@utils/url-builder';
10
+ import { buildUrl, buildEditUrlForResource } from '@utils/url-builder';
12
11
  import { resourceToCollectionMap } from '@utils/collections/util';
13
12
  import { getMDXComponentsByName } from '@utils/markdown';
14
- import { getAdjacentPages } from '@enterprise/custom-documentation/utils/custom-docs';
15
- import { getCustomDocsContentBadgeClasses } from '@enterprise/custom-documentation/utils/badge-styles';
16
-
13
+ import { getAdjacentPages, getNavigationItems } from '@enterprise/custom-documentation/utils/custom-docs';
17
14
  import CustomDocsNav from '@enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro';
18
15
  import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
16
+ import CopyAsMarkdown from '@components/CopyAsMarkdown';
19
17
 
20
- import { isVisualiserEnabled } from '@utils/feature';
18
+ import { isVisualiserEnabled, isMarkdownDownloadEnabled, isRSSEnabled, isEventCatalogChatEnabled } from '@utils/feature';
21
19
 
22
20
  const props = Astro.props;
23
21
  const doc = props.data;
@@ -25,44 +23,6 @@ const { Content, headings } = await render(props as any);
25
23
  const currentSlug = props.id;
26
24
 
27
25
  const nodeGraphs = getMDXComponentsByName(props.body, 'NodeGraph') || [];
28
- // Get sidebar data
29
- const sidebar = config?.customDocs?.sidebar || [];
30
-
31
- // Flatten the sidebar to find previous and next pages
32
- type FlatItem = {
33
- label: string;
34
- slug: string;
35
- };
36
-
37
- // Define sidebar section type
38
- type SidebarSection = {
39
- label: string;
40
- slug?: string;
41
- items?: Array<{
42
- label: string;
43
- slug: string;
44
- }>;
45
- };
46
-
47
- const flattenedItems: FlatItem[] = [];
48
-
49
- // Process all sidebar sections to create a flattened array
50
- sidebar.forEach((section: SidebarSection) => {
51
- if (section.slug && !section.items) {
52
- flattenedItems.push({
53
- label: section.label,
54
- slug: section.slug,
55
- });
56
- }
57
- if (section.items) {
58
- section.items.forEach((item: { label: string; slug: string }) => {
59
- flattenedItems.push({
60
- label: item.label,
61
- slug: item.slug,
62
- });
63
- });
64
- }
65
- });
66
26
 
67
27
  const { prev, next } = await getAdjacentPages(currentSlug);
68
28
 
@@ -80,160 +40,247 @@ const ownersList = filteredOwners.map((o) => ({
80
40
 
81
41
  const badges = doc?.badges || [];
82
42
 
83
- const getCustomDocBadgeClasses = (badge: any) => {
84
- const color = badge?.backgroundColor || badge?.textColor;
85
- return `${getCustomDocsContentBadgeClasses(color)} ${badge?.class ? badge.class : ''}`;
43
+ // Find the immediate parent group label, for the accent header label above the title.
44
+ // Walks the processed navigation tree (which expands `autogenerated` directories into nested groups)
45
+ // so that nested groups like "Creating new microservices" are surfaced rather than only the top-level section.
46
+ const normalizeSlug = (s: string | undefined) => (s || '').replace(/^\//, '').replace(/^docs\//, '');
47
+ const currentSlugNorm = normalizeSlug(currentSlug);
48
+ const navigationItems = await getNavigationItems();
49
+
50
+ type NavItem = { label: string; slug?: string; items?: NavItem[] };
51
+
52
+ const findParentLabel = (items: NavItem[], parentLabel: string): string | null => {
53
+ for (const item of items) {
54
+ if (item.slug && normalizeSlug(item.slug) === currentSlugNorm) {
55
+ return parentLabel;
56
+ }
57
+ if (item.items?.length) {
58
+ const found = findParentLabel(item.items, item.label);
59
+ if (found !== null) return found;
60
+ }
61
+ }
62
+ return null;
86
63
  };
64
+
65
+ const sectionLabel = findParentLabel(navigationItems as NavItem[], '') || '';
66
+
67
+ const editUrl =
68
+ (doc as any)?.editUrl ||
69
+ (config.editUrl && (props as any)?.filePath ? buildEditUrlForResource(config.editUrl, (props as any).filePath) : '');
87
70
  ---
88
71
 
89
72
  <VerticalSideBarLayout title={doc.title || 'Documentation'} showNestedSideBar={false}>
90
- <div class="flex w-full" data-pagefind-body data-pagefind-meta={`title:${doc.title}`}>
73
+ <div class="custom-docs-shell flex w-full" data-pagefind-body data-pagefind-meta={`title:${doc.title}`}>
91
74
  <!-- Left Sidebar Navigation -->
92
75
  <aside
93
- class="sidebar-transition overflow-y-auto bg-[rgb(var(--ec-page-bg))] border-r border-[rgb(var(--ec-page-border))] w-80 fixed top-16 bottom-0 z-10"
76
+ class="sidebar-transition fixed top-0 bottom-0 left-[var(--ec-vertical-nav-width,14rem)] z-10 w-[var(--ec-custom-docs-sidebar-width,20rem)] overflow-hidden border-r border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-rail-bg))]"
94
77
  >
95
- <CustomDocsNav />
78
+ <div class="h-full">
79
+ <CustomDocsNav />
80
+ </div>
96
81
  </aside>
97
82
 
98
- <!-- Main Content Area - Independent scrolling -->
99
- <main
100
- class="sidebar-transition w-full max-h-content ml-[22em] md:ml-[21em] lg:mr-2 2xl:mr-2 2xl:ml-[22em] pr-2 overflow-y-auto"
101
- >
102
- <div class="max-w-none mx-auto px-4 py-10">
103
- <div class="border-b border-[rgb(var(--ec-page-border))] flex justify-between items-start md:pb-6">
104
- <div>
105
- <h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{doc.title}</h2>
106
- <p class="text-lg pt-2 text-[rgb(var(--ec-page-text-muted))] font-light">{doc.summary}</p>
107
- {
108
- badges && (
109
- <div class="flex flex-wrap pt-4">
110
- {badges.map((badge: any) => {
111
- return (
112
- <a href={badge.url || '#'} class="pb-2">
113
- <span id={badge.id || ''} class={`${getCustomDocBadgeClasses(badge)} mr-2`}>
114
- {badge.icon && <badge.icon className="w-4 h-4 flex-shrink-0 text-[rgb(var(--ec-icon-color))]" />}
115
- {badge.iconURL && <img src={badge.iconURL} class="w-4 h-4 flex-shrink-0 opacity-80" alt="" />}
116
- <span>{badge.content}</span>
117
- </span>
118
- </a>
119
- );
120
- })}
83
+ <div class="sidebar-transition flex w-full min-w-0" style="margin-left: var(--ec-custom-docs-sidebar-width, 20rem);">
84
+ <main class="min-w-0 flex-1">
85
+ <div
86
+ class="w-full lg:mr-2 pr-10 py-10 bg-[rgb(var(--ec-page-bg))]"
87
+ style="padding-left: var(--ec-app-content-padding-left, 5rem);"
88
+ >
89
+ <div class="border-b border-[rgb(var(--ec-page-border))] md:pb-4">
90
+ <div class="flex flex-col gap-4">
91
+ {
92
+ sectionLabel && (
93
+ <span class="text-xs md:text-sm font-semibold text-[rgb(var(--ec-accent))] capitalize">{sectionLabel}</span>
94
+ )
95
+ }
96
+ <div class="flex justify-between items-center gap-4">
97
+ <h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">
98
+ {doc.title}
99
+ </h2>
100
+ <div class="hidden lg:block shrink-0">
101
+ <CopyAsMarkdown
102
+ client:only="react"
103
+ schemas={[]}
104
+ chatEnabled={isEventCatalogChatEnabled()}
105
+ markdownDownloadEnabled={isMarkdownDownloadEnabled()}
106
+ rssFeedEnabled={isRSSEnabled()}
107
+ editUrl={editUrl}
108
+ preferChatAsDefault={isEventCatalogChatEnabled()}
109
+ />
121
110
  </div>
122
- )
123
- }
111
+ </div>
112
+ <p class="text-base text-[rgb(var(--ec-page-text-muted))] font-light">{doc.summary}</p>
113
+ {
114
+ badges && badges.length > 0 && (
115
+ <div class="flex flex-wrap gap-3 py-2">
116
+ {badges.map((badge: any) => {
117
+ return (
118
+ <a href={badge.url || '#'}>
119
+ <span
120
+ id={badge.id || ''}
121
+ class={`
122
+ inline-flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm font-medium
123
+ bg-[rgb(var(--ec-content-hover))] border border-[rgb(var(--ec-page-border))]
124
+ text-[rgb(var(--ec-page-text))]
125
+ shadow-xs
126
+ ${badge.class ? badge.class : ''}
127
+ `}
128
+ >
129
+ {badge.icon && <badge.icon className="w-4 h-4 flex-shrink-0 text-[rgb(var(--ec-icon-color))]" />}
130
+ {badge.iconURL && <img src={badge.iconURL} class="w-4 h-4 flex-shrink-0 opacity-80" alt="" />}
131
+ <span>{badge.content}</span>
132
+ </span>
133
+ </a>
134
+ );
135
+ })}
136
+ </div>
137
+ )
138
+ }
139
+ </div>
140
+ </div>
141
+ <div class="prose prose-md max-w-none py-4 w-full text-[15px]">
142
+ <Content components={{ ...mdxComponents(props) }} />
124
143
  </div>
125
- </div>
126
- <div class="flex-auto prose py-8 max-w-none">
127
- <Content components={{ ...mdxComponents(props) }} />
128
- </div>
129
144
 
130
- {
131
- nodeGraphs.length > 0 &&
132
- nodeGraphs.map((nodeGraph: any) => {
133
- const collection = resourceToCollectionMap[nodeGraph.type as keyof typeof resourceToCollectionMap];
134
- return (
135
- <NodeGraph
136
- id={nodeGraph.id}
137
- version={nodeGraph.version}
138
- collection={collection}
139
- title={nodeGraph.title}
140
- mode="simple"
141
- linksToVisualiser={true}
142
- href={
143
- isVisualiserEnabled()
144
- ? {
145
- label: 'Open in Visualiser',
146
- url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
147
- }
148
- : undefined
149
- }
150
- />
151
- );
152
- })
153
- }
145
+ {
146
+ nodeGraphs.length > 0 &&
147
+ nodeGraphs.map((nodeGraph: any) => {
148
+ const collection = resourceToCollectionMap[nodeGraph.type as keyof typeof resourceToCollectionMap];
149
+ return (
150
+ <NodeGraph
151
+ id={nodeGraph.id}
152
+ version={nodeGraph.version}
153
+ collection={collection}
154
+ title={nodeGraph.title}
155
+ mode="simple"
156
+ linksToVisualiser={true}
157
+ href={
158
+ isVisualiserEnabled()
159
+ ? {
160
+ label: 'Open in Visualiser',
161
+ url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
162
+ }
163
+ : undefined
164
+ }
165
+ />
166
+ );
167
+ })
168
+ }
154
169
 
155
- <!-- Previous / Next Navigation -->
156
- <div class="py-8 border-t border-[rgb(var(--ec-page-border))] mt-8">
157
- <div class="flex flex-col sm:flex-row justify-between w-full gap-4">
158
- {
159
- prev && (
160
- <a
161
- href={buildUrl(`/docs/custom/${prev.slug}`)}
162
- class="group flex flex-col border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
163
- >
164
- <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Previous</span>
165
- <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
166
- {prev.label}
167
- </span>
168
- </a>
169
- )
170
- }
170
+ <!-- Previous / Next Navigation -->
171
+ <div class="py-8 border-t border-[rgb(var(--ec-page-border))] mt-8">
172
+ <div class="flex flex-col sm:flex-row justify-between w-full gap-4">
173
+ {
174
+ prev && (
175
+ <a
176
+ href={buildUrl(`/docs/custom/${prev.slug}`)}
177
+ class="group flex flex-col border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
178
+ >
179
+ <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Previous</span>
180
+ <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
181
+ {prev.label}
182
+ </span>
183
+ </a>
184
+ )
185
+ }
171
186
 
172
- {!prev && <div class="w-full sm:w-1/2" />}
173
-
174
- {
175
- next && (
176
- <a
177
- href={buildUrl(`/docs/custom/${next.slug}`)}
178
- class="group flex flex-col items-end text-right border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
179
- >
180
- <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Next</span>
181
- <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
182
- {next.label}
183
- </span>
184
- </a>
185
- )
186
- }
187
+ {!prev && <div class="w-full sm:w-1/2" />}
188
+
189
+ {
190
+ next && (
191
+ <a
192
+ href={buildUrl(`/docs/custom/${next.slug}`)}
193
+ class="group flex flex-col items-end text-right border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
194
+ >
195
+ <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Next</span>
196
+ <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
197
+ {next.label}
198
+ </span>
199
+ </a>
200
+ )
201
+ }
202
+ </div>
187
203
  </div>
188
204
  </div>
189
- </div>
190
- </main>
191
-
192
- <!-- Right Sidebar TOC -->
193
- <aside
194
- class="hidden lg:block sticky top-0 pb-10 w-80 overflow-y-auto border-l border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] p-6 flex-shrink-0 py-2"
195
- >
196
- <div class="py-4">
197
- <div>
205
+ </main>
206
+
207
+ <!-- Right Sidebar TOC -->
208
+ <aside
209
+ id="eventcatalog-docs-sidebar"
210
+ class="hidden xl:block sticky top-[4rem] self-start w-[200px] max-h-[calc(100vh-4rem)] overflow-y-auto py-2 flex-shrink-0 bg-[rgb(var(--ec-page-bg))]"
211
+ >
212
+ <div class="mt-8 space-y-8">
198
213
  {
199
- ownersList.length > 0 && (
200
- <OwnersList
201
- title={`Document Owners (${ownersList.length})`}
202
- emptyMessage={`This page does not have any documented owners.`}
203
- owners={ownersList}
204
- client:load
205
- />
214
+ headings.length > 0 && (
215
+ <div>
216
+ <h3 class="text-xs text-[rgb(var(--ec-page-text))] font-semibold capitalize flex items-center gap-2 mb-4">
217
+ <AlignLeftIcon className="w-4 h-4" />
218
+ On this page
219
+ </h3>
220
+ <nav class="text-xs border-l border-[rgb(var(--ec-page-border))]">
221
+ {headings.map((heading) => {
222
+ const level = heading.depth > 2 ? heading.depth : 1;
223
+ if (heading.depth > 3) {
224
+ return null;
225
+ }
226
+ return (
227
+ <a
228
+ href={`#${heading.slug}`}
229
+ class="block py-1.5 pr-2.5 leading-5 text-[rgb(var(--ec-page-text-muted))] hover:border-[rgb(var(--ec-page-border))] hover:text-[rgb(var(--ec-page-text))] border-l-2 border-transparent -ml-px transition-all duration-200"
230
+ style={`padding-left: ${level * 0.75}rem`}
231
+ >
232
+ {heading.text}
233
+ </a>
234
+ );
235
+ })}
236
+ </nav>
237
+ </div>
206
238
  )
207
239
  }
208
- </div>
209
- <h3 class="text-sm text-[rgb(var(--ec-page-text))] font-semibold capitalize flex items-center gap-2">
210
- <AlignLeftIcon className="w-4 h-4" />
211
- On this page
212
- </h3>
213
- <nav class="space-y-1 text-sm py-4">
214
240
  {
215
- headings.map((heading) => {
216
- if (heading.depth > 3) {
217
- return null;
218
- }
219
- return (
220
- <a
221
- href={`#${heading.slug}`}
222
- class={`block text-[12px] py-0.5 ${heading.depth === 1 ? 'font-light' : ''} text-[rgb(var(--ec-page-text-muted))] hover:text-primary-600`}
223
- style={`padding-left: ${(heading.depth - 1) * 8}px`}
224
- >
225
- {heading.text}
226
- </a>
227
- );
228
- })
241
+ ownersList.length > 0 && (
242
+ <div>
243
+ <h3 class="text-xs text-[rgb(var(--ec-page-text))] font-semibold capitalize mb-4">
244
+ {`Document Owners (${ownersList.length})`}
245
+ </h3>
246
+ <div class="space-y-2">
247
+ {ownersList.map((owner) => (
248
+ <a
249
+ href={owner.href}
250
+ class="flex items-center gap-2 text-xs text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] transition-colors"
251
+ >
252
+ {owner.type === 'users' ? (
253
+ <UserIcon className="h-4 w-4 flex-shrink-0 text-[rgb(var(--ec-page-text-muted))]" />
254
+ ) : (
255
+ <UsersIcon className="h-4 w-4 flex-shrink-0 text-[rgb(var(--ec-page-text-muted))]" />
256
+ )}
257
+ <span class="truncate">{owner.label}</span>
258
+ </a>
259
+ ))}
260
+ </div>
261
+ </div>
262
+ )
229
263
  }
230
- </nav>
231
- </div>
232
- </aside>
264
+ </div>
265
+ </aside>
266
+ </div>
233
267
  </div>
234
268
  </VerticalSideBarLayout>
235
269
 
236
270
  <style is:global>
271
+ :root {
272
+ --ec-custom-docs-sidebar-width: 20rem;
273
+ }
274
+
275
+ #eventcatalog-header {
276
+ left: calc(var(--ec-vertical-nav-width, 14rem) + var(--ec-custom-docs-sidebar-width, 20rem)) !important;
277
+ }
278
+
279
+ .custom-docs-shell {
280
+ margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1);
281
+ margin-right: calc(var(--ec-app-content-padding-right, 5rem) * -1);
282
+ }
283
+
237
284
  .mermaid svg {
238
285
  margin: 1em auto 2em;
239
286
  }
@@ -249,6 +296,10 @@ const getCustomDocBadgeClasses = (badge: any) => {
249
296
  .toc-active-text {
250
297
  color: rgb(var(--ec-accent));
251
298
  }
299
+
300
+ .toc-active-border {
301
+ border-color: rgb(var(--ec-accent));
302
+ }
252
303
  </style>
253
304
 
254
305
  <script define:vars={{ props, config }}>
@@ -275,16 +326,16 @@ const getCustomDocBadgeClasses = (badge: any) => {
275
326
  // Function to highlight a TOC item
276
327
  function highlightTocItem(id: string) {
277
328
  // Remove active class from all links
278
- document.querySelectorAll('.active-toc-item').forEach((link) => {
279
- link.classList.remove('active-toc-item', 'toc-active-text', 'font-light');
280
- link.classList.add('text-gray-400');
329
+ document.querySelectorAll('#eventcatalog-docs-sidebar .active-toc-item').forEach((link) => {
330
+ link.classList.remove('active-toc-item', 'toc-active-text', 'font-medium', 'toc-active-border');
331
+ link.classList.add('border-transparent');
281
332
  });
282
333
 
283
334
  // Add active class to current link
284
- const tocLink = document.querySelector(`nav a[href="#${id}"]`);
335
+ const tocLink = document.querySelector(`#eventcatalog-docs-sidebar nav a[href="#${id}"]`);
285
336
  if (tocLink) {
286
- tocLink.classList.add('active-toc-item', 'toc-active-text', 'font-light');
287
- tocLink.classList.remove('text-gray-400');
337
+ tocLink.classList.add('active-toc-item', 'toc-active-text', 'font-medium', 'toc-active-border');
338
+ tocLink.classList.remove('border-transparent');
288
339
 
289
340
  // Scroll the highlighted item into view with a small delay to ensure DOM updates first
290
341
  setTimeout(() => {
@@ -343,7 +394,7 @@ const getCustomDocBadgeClasses = (badge: any) => {
343
394
  }
344
395
 
345
396
  // Add click event listeners to all TOC links
346
- const tocLinks = document.querySelectorAll('nav a[href^="#"]');
397
+ const tocLinks = document.querySelectorAll('#eventcatalog-docs-sidebar nav a[href^="#"]');
347
398
  tocLinks.forEach((link) => {
348
399
  link.addEventListener('click', (e) => {
349
400
  // Get the ID from the href attribute
@@ -44,7 +44,8 @@ export const isEventCatalogChatEnabled = () => {
44
44
  const isFeatureEnabledFromPlan = isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
45
45
  const directory = process.env.PROJECT_DIR || process.cwd();
46
46
  const hasChatConfigurationFile = fs.existsSync(join(directory, 'eventcatalog.chat.js'));
47
- return isFeatureEnabledFromPlan && hasChatConfigurationFile && isSSR();
47
+ const isEnabledInConfig = config?.chat?.enabled ?? true;
48
+ return isFeatureEnabledFromPlan && hasChatConfigurationFile && isSSR() && isEnabledInConfig;
48
49
  };
49
50
 
50
51
  export const isEventCatalogUpgradeEnabled = () => !isEventCatalogStarterEnabled() && !isEventCatalogScaleEnabled();
@@ -7,13 +7,15 @@ export const prerender = false;
7
7
  ---
8
8
 
9
9
  <VerticalSideBarLayout title="Fields Explorer - EventCatalog" showNestedSideBar={false}>
10
- <main class="flex docs-layout h-[calc(100vh-var(--header-height,0px)-64px)] bg-[rgb(var(--ec-page-bg))]">
11
- <div class="flex docs-layout w-full h-full">
12
- <div class="w-full flex flex-col h-full">
13
- <div class="w-full max-w-none! h-full flex flex-col overflow-hidden">
14
- <FieldsExplorer client:load isScaleEnabled={isEventCatalogScaleEnabled()} />
15
- </div>
16
- </div>
17
- </div>
10
+ <style is:global>
11
+ #eventcatalog-header {
12
+ left: calc(var(--ec-vertical-nav-width, 14rem) + var(--ec-fields-sidebar-width, 320px)) !important;
13
+ }
14
+ </style>
15
+ <main
16
+ class="min-h-0 overflow-hidden bg-[rgb(var(--ec-page-bg))]"
17
+ style="--ec-fields-sidebar-width: 320px; margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1); margin-right: calc(var(--ec-app-content-padding-right, 5rem) * -1); height: calc(100dvh - 60px);"
18
+ >
19
+ <FieldsExplorer client:load isScaleEnabled={isEventCatalogScaleEnabled()} />
18
20
  </main>
19
21
  </VerticalSideBarLayout>
@@ -77,14 +77,6 @@ export default function eventCatalogIntegration(): AstroIntegration {
77
77
  configureAuthentication(params);
78
78
  }
79
79
 
80
- // If non paying user, add the plans route into the project
81
- if (!isEventCatalogStarterEnabled() && !isEventCatalogScaleEnabled()) {
82
- params.injectRoute({
83
- pattern: '/plans',
84
- entrypoint: path.join(catalogDirectory, 'src/enterprise/plans/index.astro'),
85
- });
86
- }
87
-
88
80
  // Custom documentation routes (Starter/Scale plan)
89
81
  if (isCustomDocsEnabled()) {
90
82
  params.injectRoute({