@eventcatalog/core 4.0.0-beta.0 → 4.0.0-beta.2
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.
- package/bin/eventcatalog.config.d.ts +1 -1
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-HN45LKSL.js → chunk-24K6JJV5.js} +1 -1
- package/dist/{chunk-7PMNFOIL.js → chunk-7NOXTLJP.js} +1 -1
- package/dist/{chunk-D3MI3OFO.js → chunk-FLLYUYF2.js} +1 -1
- package/dist/{chunk-NAOHQDLC.js → chunk-IK6AW6IC.js} +1 -1
- package/dist/{chunk-JMADW4J7.js → chunk-JRCXVY3E.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.config.d.cts +40 -7
- package/dist/eventcatalog.config.d.ts +40 -7
- package/dist/eventcatalog.js +5 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +16 -2
- package/eventcatalog/src/components/CopyAsMarkdown.tsx +6 -57
- package/eventcatalog/src/content.config.ts +2 -0
- package/eventcatalog/src/enterprise/ai/chat-api.ts +4 -2
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +26 -7
- package/eventcatalog/src/enterprise/feature.ts +0 -4
- package/eventcatalog/src/enterprise/integrations/eventcatalog-features.ts +0 -9
- package/eventcatalog/src/enterprise/tools/catalog-tools.ts +6 -1
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +343 -282
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +6 -81
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +0 -8
- package/eventcatalog/src/stores/sidebar-store/state.ts +4 -4
- package/eventcatalog/src/utils/feature.ts +0 -2
- package/package.json +4 -4
- package/eventcatalog/src/enterprise/print/_message.data.ts +0 -63
- package/eventcatalog/src/enterprise/print/components/PrintHeader.astro +0 -183
- package/eventcatalog/src/enterprise/print/components/PrintLayout.astro +0 -271
- package/eventcatalog/src/enterprise/print/components/PrintParticipantsTable.astro +0 -64
- package/eventcatalog/src/enterprise/print/components/PrintSchemaPropertiesTable.astro +0 -65
- package/eventcatalog/src/enterprise/print/components/PrintSchemaViewer.tsx +0 -55
- package/eventcatalog/src/enterprise/print/components/PrintSection.astro +0 -17
- package/eventcatalog/src/enterprise/print/message.astro +0 -353
- package/eventcatalog/src/enterprise/print/utils.ts +0 -58
- package/eventcatalog/src/utils/sidebar-visibility.ts +0 -41
|
@@ -10,18 +10,7 @@ interface Props {
|
|
|
10
10
|
reducedContentPadding?: boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
TableProperties,
|
|
15
|
-
House,
|
|
16
|
-
FileText,
|
|
17
|
-
SquareDashedMousePointerIcon,
|
|
18
|
-
FileCode,
|
|
19
|
-
Waypoints,
|
|
20
|
-
PanelLeftClose,
|
|
21
|
-
UserRound,
|
|
22
|
-
UsersRound,
|
|
23
|
-
Settings,
|
|
24
|
-
} from 'lucide-react';
|
|
13
|
+
import * as LucideIcons from 'lucide-react';
|
|
25
14
|
import BaseLayout from './BaseLayout.astro';
|
|
26
15
|
import Header from '../components/Header.astro';
|
|
27
16
|
import SideNav from '../components/SideNav/SideNav.astro';
|
|
@@ -59,10 +48,9 @@ import { getDataProducts } from '@utils/collections/data-products';
|
|
|
59
48
|
import { isCollectionVisibleInCatalog } from '@eventcatalog';
|
|
60
49
|
import { buildUrl } from '@utils/url-builder';
|
|
61
50
|
import { getQueries } from '@utils/collections/queries';
|
|
62
|
-
import { filterSidebarItems } from '@utils/sidebar-visibility';
|
|
63
51
|
import { getFirstNavigationPage } from '@enterprise/custom-documentation/utils/custom-docs';
|
|
64
52
|
|
|
65
|
-
import { isEmbedEnabled, isCustomStylesEnabled,
|
|
53
|
+
import { isEmbedEnabled, isCustomStylesEnabled, isCustomDocsEnabled, isSSR } from '@utils/feature';
|
|
66
54
|
|
|
67
55
|
const customDocs = await getCollection('customPages');
|
|
68
56
|
const firstCustomDocsPage = isCustomDocsEnabled() && customDocs.length > 0 ? await getFirstNavigationPage() : null;
|
|
@@ -132,163 +120,304 @@ const getDefaultUrl = (route: string, defaultValue: string) => {
|
|
|
132
120
|
return buildUrl(defaultValue);
|
|
133
121
|
};
|
|
134
122
|
|
|
135
|
-
const userSideBarConfiguration = config.sidebar || [];
|
|
136
|
-
|
|
137
|
-
const navigationItems = filterSidebarItems(
|
|
138
|
-
[
|
|
139
|
-
{
|
|
140
|
-
id: '/',
|
|
141
|
-
label: 'Home',
|
|
142
|
-
icon: House,
|
|
143
|
-
href: buildUrl(config.landingPage || '/'),
|
|
144
|
-
current:
|
|
145
|
-
currentPath === '/' ||
|
|
146
|
-
(currentPath.includes('/docs') && !currentPath.includes('/docs/custom')) ||
|
|
147
|
-
currentPath.includes('/architecture/') ||
|
|
148
|
-
currentPath.includes('/visualiser') ||
|
|
149
|
-
(currentPath.includes('/schemas') &&
|
|
150
|
-
!currentPath.includes('/schemas/explorer') &&
|
|
151
|
-
!currentPath.includes('/schemas/fields')),
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
id: '/docs/custom',
|
|
155
|
-
aliases: ['/docs'],
|
|
156
|
-
label: 'Documentation',
|
|
157
|
-
icon: FileText,
|
|
158
|
-
href: getDefaultUrl('docs/custom', '/docs/custom'),
|
|
159
|
-
current: currentPath.includes('/docs/custom'),
|
|
160
|
-
isPremium: true,
|
|
161
|
-
visible: isCustomDocsEnabled() && customDocs.length > 0,
|
|
162
|
-
},
|
|
163
|
-
...(isSSR()
|
|
164
|
-
? [
|
|
165
|
-
{
|
|
166
|
-
id: '/schemas/fields',
|
|
167
|
-
label: 'Schema Insights',
|
|
168
|
-
icon: Waypoints,
|
|
169
|
-
href: buildUrl('/schemas/fields'),
|
|
170
|
-
current: currentPath.includes('/schemas/fields'),
|
|
171
|
-
},
|
|
172
|
-
]
|
|
173
|
-
: []),
|
|
174
|
-
],
|
|
175
|
-
userSideBarConfiguration
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
const studioNavigationItem = filterSidebarItems(
|
|
179
|
-
[
|
|
180
|
-
{
|
|
181
|
-
id: '/studio',
|
|
182
|
-
label: 'EventCatalog Studio',
|
|
183
|
-
icon: SquareDashedMousePointerIcon,
|
|
184
|
-
href: buildUrl('/studio'),
|
|
185
|
-
current: currentPath.includes('/studio'),
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
userSideBarConfiguration
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
const premiumFeatures: Array<{
|
|
192
|
-
id: string;
|
|
193
|
-
label: string;
|
|
194
|
-
icon: any;
|
|
195
|
-
href: string;
|
|
196
|
-
current: boolean;
|
|
197
|
-
isPremium?: boolean;
|
|
198
|
-
}> = [];
|
|
199
|
-
|
|
200
123
|
const internalServices = services.filter((service) => !service.data.externalSystem);
|
|
201
124
|
const externalSystems = services.filter((service) => service.data.externalSystem);
|
|
202
125
|
const discoverTargets = [
|
|
203
|
-
{ id: '/discover/domains',
|
|
204
|
-
{ id: '/discover/systems',
|
|
126
|
+
{ id: '/discover/domains', href: buildUrl('/discover/domains'), count: domains.length },
|
|
127
|
+
{ id: '/discover/systems', href: buildUrl('/discover/systems'), count: systems.length },
|
|
205
128
|
{
|
|
206
129
|
id: '/discover/services',
|
|
207
|
-
aliases: ['/discover'],
|
|
208
130
|
href: buildUrl('/discover/services'),
|
|
209
131
|
count: internalServices.length,
|
|
210
132
|
},
|
|
211
133
|
{
|
|
212
134
|
id: '/discover/external-systems',
|
|
213
|
-
aliases: ['/discover'],
|
|
214
135
|
href: buildUrl('/discover/external-systems'),
|
|
215
136
|
count: externalSystems.length,
|
|
216
137
|
},
|
|
217
|
-
{ id: '/discover/agents',
|
|
218
|
-
{ id: '/discover/adrs',
|
|
138
|
+
{ id: '/discover/agents', href: buildUrl('/discover/agents'), count: agents.length },
|
|
139
|
+
{ id: '/discover/adrs', href: buildUrl('/discover/adrs'), count: adrs.length },
|
|
219
140
|
{
|
|
220
141
|
id: '/discover/data-products',
|
|
221
|
-
aliases: ['/discover'],
|
|
222
142
|
href: buildUrl('/discover/data-products'),
|
|
223
143
|
count: dataProducts.length,
|
|
224
144
|
},
|
|
225
|
-
{ id: '/discover/containers',
|
|
226
|
-
{ id: '/discover/events',
|
|
227
|
-
{ id: '/discover/commands',
|
|
228
|
-
{ id: '/discover/queries',
|
|
229
|
-
{ id: '/discover/flows',
|
|
145
|
+
{ id: '/discover/containers', href: buildUrl('/discover/containers'), count: containers.length },
|
|
146
|
+
{ id: '/discover/events', href: buildUrl('/discover/events'), count: events.length },
|
|
147
|
+
{ id: '/discover/commands', href: buildUrl('/discover/commands'), count: commands.length },
|
|
148
|
+
{ id: '/discover/queries', href: buildUrl('/discover/queries'), count: queries.length },
|
|
149
|
+
{ id: '/discover/flows', href: buildUrl('/discover/flows'), count: flows.length },
|
|
230
150
|
];
|
|
231
|
-
const defaultDiscoverTarget =
|
|
151
|
+
const defaultDiscoverTarget = discoverTargets.find((target) => target.count > 0);
|
|
232
152
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
current: currentPath === buildUrl('/discover') || currentPath.startsWith(buildUrl('/discover/', true)),
|
|
242
|
-
visible: Boolean(defaultDiscoverTarget),
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
id: '/schemas/explorer',
|
|
246
|
-
label: 'Schemas',
|
|
247
|
-
icon: FileCode,
|
|
248
|
-
href: buildUrl('/schemas/explorer'),
|
|
249
|
-
current: currentPath.includes('/schemas/explorer') && !currentPath.includes('/schemas/fields'),
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
userSideBarConfiguration
|
|
253
|
-
).filter((item) => item.visible !== false);
|
|
254
|
-
|
|
255
|
-
const organizationItems = filterSidebarItems(
|
|
256
|
-
[
|
|
257
|
-
{
|
|
258
|
-
id: '/directory/teams',
|
|
259
|
-
aliases: ['/directory'],
|
|
260
|
-
label: 'Teams',
|
|
261
|
-
icon: UsersRound,
|
|
262
|
-
href: buildUrl('/directory/teams'),
|
|
263
|
-
current: currentPath === buildUrl('/directory/teams'),
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
id: '/directory/users',
|
|
267
|
-
aliases: ['/directory'],
|
|
268
|
-
label: 'Users',
|
|
269
|
-
icon: UserRound,
|
|
270
|
-
href: buildUrl('/directory/users'),
|
|
271
|
-
current: currentPath === buildUrl('/directory/users'),
|
|
272
|
-
},
|
|
273
|
-
],
|
|
274
|
-
userSideBarConfiguration
|
|
275
|
-
);
|
|
153
|
+
type NavigationItemConfig = {
|
|
154
|
+
id: string;
|
|
155
|
+
label?: string;
|
|
156
|
+
icon?: string;
|
|
157
|
+
href?: string;
|
|
158
|
+
visible?: boolean;
|
|
159
|
+
match?: string | string[];
|
|
160
|
+
};
|
|
276
161
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
162
|
+
type NavigationGroupConfig = {
|
|
163
|
+
id: string;
|
|
164
|
+
label?: string;
|
|
165
|
+
visible?: boolean;
|
|
166
|
+
position?: 'top' | 'bottom';
|
|
167
|
+
items?: NavigationItemConfig[];
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
type VerticalNavigationItem = Required<Pick<NavigationItemConfig, 'id' | 'label' | 'href'>> & {
|
|
171
|
+
icon: string;
|
|
172
|
+
current: boolean;
|
|
173
|
+
matchId: string;
|
|
174
|
+
match?: string | string[];
|
|
175
|
+
target?: string;
|
|
176
|
+
rel?: string;
|
|
177
|
+
Icon: any;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const toPascalCase = (value: string) =>
|
|
181
|
+
value
|
|
182
|
+
.split(/[-_\s]+/)
|
|
183
|
+
.filter(Boolean)
|
|
184
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
185
|
+
.join('');
|
|
186
|
+
|
|
187
|
+
const resolveLucideIcon = (icon?: string) => {
|
|
188
|
+
if (!icon) return LucideIcons.Circle;
|
|
189
|
+
|
|
190
|
+
const icons = LucideIcons as unknown as Record<string, any>;
|
|
191
|
+
return (
|
|
192
|
+
icons[icon] || icons[`${icon}Icon`] || icons[toPascalCase(icon)] || icons[`${toPascalCase(icon)}Icon`] || LucideIcons.Circle
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const normalizeNavigationHref = (href: string) => {
|
|
197
|
+
if (/^(https?:)?\/\//.test(href) || href.startsWith('mailto:') || href.startsWith('#')) {
|
|
198
|
+
return href;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return buildUrl(href);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const isExternalNavigationHref = (href: string) => /^https?:\/\//.test(href);
|
|
205
|
+
|
|
206
|
+
const normalizeNavigationMatch = (match?: string | string[]) => {
|
|
207
|
+
if (!match) return undefined;
|
|
208
|
+
|
|
209
|
+
const normalizeMatch = (value: string) => (isExternalNavigationHref(value) ? value : buildUrl(value, true));
|
|
210
|
+
return Array.isArray(match) ? match.map(normalizeMatch) : normalizeMatch(match);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const navigationBuiltinAliases: Record<string, string> = {
|
|
214
|
+
home: '/',
|
|
215
|
+
docs: '/docs/custom',
|
|
216
|
+
catalog: '/discover',
|
|
217
|
+
schemas: '/schemas/explorer',
|
|
218
|
+
'schema-insights': '/schemas/fields',
|
|
219
|
+
teams: '/directory/teams',
|
|
220
|
+
users: '/directory/users',
|
|
221
|
+
settings: '/settings/general',
|
|
222
|
+
studio: '/studio',
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const builtinNavigationItems: Record<string, Omit<VerticalNavigationItem, 'current' | 'Icon'>> = {
|
|
226
|
+
'/': {
|
|
227
|
+
id: '/',
|
|
228
|
+
matchId: '/',
|
|
229
|
+
label: 'Home',
|
|
230
|
+
icon: 'House',
|
|
231
|
+
href: buildUrl(config.landingPage || '/'),
|
|
232
|
+
},
|
|
233
|
+
'/docs/custom': {
|
|
234
|
+
id: '/docs/custom',
|
|
235
|
+
matchId: '/docs/custom',
|
|
236
|
+
label: 'Docs',
|
|
237
|
+
icon: 'FileText',
|
|
238
|
+
href: getDefaultUrl('docs/custom', '/docs/custom'),
|
|
239
|
+
},
|
|
240
|
+
'/studio': {
|
|
241
|
+
id: '/studio',
|
|
242
|
+
matchId: '/studio',
|
|
243
|
+
label: 'EventCatalog Studio',
|
|
244
|
+
icon: 'SquareDashedMousePointer',
|
|
245
|
+
href: buildUrl('/studio'),
|
|
246
|
+
},
|
|
247
|
+
'/discover': {
|
|
248
|
+
id: '/discover',
|
|
249
|
+
matchId: '/discover',
|
|
250
|
+
label: 'Catalog',
|
|
251
|
+
icon: 'TableProperties',
|
|
252
|
+
href: defaultDiscoverTarget?.href ?? buildUrl('/discover/domains'),
|
|
253
|
+
},
|
|
254
|
+
'/schemas/explorer': {
|
|
255
|
+
id: '/schemas/explorer',
|
|
256
|
+
matchId: '/schemas/explorer',
|
|
257
|
+
label: 'Schemas & APIs',
|
|
258
|
+
icon: 'FileCode',
|
|
259
|
+
href: buildUrl('/schemas/explorer'),
|
|
260
|
+
},
|
|
261
|
+
'/schemas/fields': {
|
|
262
|
+
id: '/schemas/fields',
|
|
263
|
+
matchId: '/schemas/fields',
|
|
264
|
+
label: 'Schema Insights',
|
|
265
|
+
icon: 'Waypoints',
|
|
266
|
+
href: buildUrl('/schemas/fields'),
|
|
267
|
+
},
|
|
268
|
+
'/directory/teams': {
|
|
269
|
+
id: '/directory/teams',
|
|
270
|
+
matchId: '/directory/teams',
|
|
271
|
+
label: 'Teams',
|
|
272
|
+
icon: 'UsersRound',
|
|
273
|
+
href: buildUrl('/directory/teams'),
|
|
274
|
+
},
|
|
275
|
+
'/directory/users': {
|
|
276
|
+
id: '/directory/users',
|
|
277
|
+
matchId: '/directory/users',
|
|
278
|
+
label: 'Users',
|
|
279
|
+
icon: 'UserRound',
|
|
280
|
+
href: buildUrl('/directory/users'),
|
|
281
|
+
},
|
|
282
|
+
'/settings/general': {
|
|
283
|
+
id: '/settings/general',
|
|
284
|
+
matchId: '/settings/general',
|
|
285
|
+
label: 'Settings',
|
|
286
|
+
icon: 'Settings',
|
|
287
|
+
href: buildUrl('/settings/general'),
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const defaultNavigationGroups: NavigationGroupConfig[] = [
|
|
292
|
+
{
|
|
293
|
+
id: 'main',
|
|
294
|
+
items: [{ id: '/' }, { id: '/docs/custom', visible: isCustomDocsEnabled() && customDocs.length > 0 }],
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'browse',
|
|
298
|
+
label: 'Browse',
|
|
299
|
+
items: [
|
|
300
|
+
{ id: '/discover', visible: Boolean(defaultDiscoverTarget) },
|
|
301
|
+
{ id: '/schemas/explorer' },
|
|
302
|
+
{ id: '/schemas/fields', visible: isSSR() },
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: 'organization',
|
|
307
|
+
label: 'Organization',
|
|
308
|
+
items: [{ id: '/directory/teams' }, { id: '/directory/users' }],
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: 'settings',
|
|
312
|
+
position: 'bottom',
|
|
313
|
+
items: [{ id: '/settings/general' }],
|
|
314
|
+
},
|
|
315
|
+
];
|
|
316
|
+
|
|
317
|
+
const isNavigationItemCurrent = (item: Pick<VerticalNavigationItem, 'href' | 'matchId' | 'match'>, pathname: string) => {
|
|
318
|
+
const matchId = item.matchId;
|
|
319
|
+
|
|
320
|
+
if (matchId === '/') {
|
|
321
|
+
const itemPath = new URL(item.href, Astro.url.origin).pathname;
|
|
322
|
+
return (
|
|
323
|
+
pathname === itemPath ||
|
|
324
|
+
(pathname.includes('/docs') && !pathname.includes('/docs/custom')) ||
|
|
325
|
+
pathname.includes('/architecture/') ||
|
|
326
|
+
pathname.includes('/visualiser') ||
|
|
327
|
+
(pathname.includes('/schemas') && !pathname.includes('/schemas/explorer') && !pathname.includes('/schemas/fields'))
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (matchId === '/schemas/explorer') {
|
|
332
|
+
return pathname.includes('/schemas/explorer') && !pathname.includes('/schemas/fields');
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (matchId === '/schemas/fields') {
|
|
336
|
+
return pathname.includes('/schemas/fields');
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (matchId === '/discover') {
|
|
340
|
+
return pathname === buildUrl('/discover', true) || pathname.endsWith('/discover') || pathname.includes('/discover/');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (matchId === '/studio') {
|
|
344
|
+
return pathname.includes('/studio');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (matchId === '/docs/custom') {
|
|
348
|
+
return pathname.includes('/docs/custom');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (matchId === '/settings/general') {
|
|
352
|
+
return pathname.startsWith(buildUrl('/settings', true));
|
|
353
|
+
}
|
|
290
354
|
|
|
291
|
-
const
|
|
355
|
+
const configuredMatches = Array.isArray(item.match) ? item.match : item.match ? [item.match] : [];
|
|
356
|
+
if (configuredMatches.length > 0) {
|
|
357
|
+
return configuredMatches.some((match) => {
|
|
358
|
+
if (isExternalNavigationHref(match)) return false;
|
|
359
|
+
|
|
360
|
+
return pathname === buildUrl(match, true) || pathname.startsWith(buildUrl(match, true));
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (isExternalNavigationHref(item.href)) return false;
|
|
365
|
+
|
|
366
|
+
const itemPath = new URL(item.href, Astro.url.origin).pathname;
|
|
367
|
+
return pathname === itemPath;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const resolveNavigationItem = (item: NavigationItemConfig): VerticalNavigationItem | null => {
|
|
371
|
+
if (item.visible === false) return null;
|
|
372
|
+
|
|
373
|
+
const builtinId = navigationBuiltinAliases[item.id] || item.id;
|
|
374
|
+
const builtin = builtinNavigationItems[builtinId];
|
|
375
|
+
const href = item.href ? normalizeNavigationHref(item.href) : builtin?.href;
|
|
376
|
+
|
|
377
|
+
if (!href) return null;
|
|
378
|
+
|
|
379
|
+
const resolvedItem = {
|
|
380
|
+
id: item.id,
|
|
381
|
+
matchId: builtin?.matchId || item.id,
|
|
382
|
+
label: item.label || builtin?.label || item.id,
|
|
383
|
+
icon: item.icon || builtin?.icon || 'Circle',
|
|
384
|
+
href,
|
|
385
|
+
match: item.match,
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
...resolvedItem,
|
|
390
|
+
current: isNavigationItemCurrent(resolvedItem, currentPath),
|
|
391
|
+
target: isExternalNavigationHref(href) ? '_blank' : undefined,
|
|
392
|
+
rel: isExternalNavigationHref(href) ? 'noopener noreferrer' : undefined,
|
|
393
|
+
Icon: resolveLucideIcon(resolvedItem.icon),
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
const resolveNavigationGroups = (groups: NavigationGroupConfig[]) =>
|
|
398
|
+
groups
|
|
399
|
+
.filter((group) => group.visible !== false)
|
|
400
|
+
.map((group) => ({
|
|
401
|
+
id: group.id,
|
|
402
|
+
label: group.label,
|
|
403
|
+
position: group.position || 'top',
|
|
404
|
+
items: (group.items || []).map(resolveNavigationItem).filter((item): item is VerticalNavigationItem => Boolean(item)),
|
|
405
|
+
}))
|
|
406
|
+
.filter((group) => group.items.length > 0);
|
|
407
|
+
|
|
408
|
+
const navigationGroups = resolveNavigationGroups(
|
|
409
|
+
Array.isArray(config.navigation?.groups) ? (config.navigation.groups as NavigationGroupConfig[]) : defaultNavigationGroups
|
|
410
|
+
);
|
|
411
|
+
const topNavigationGroups = navigationGroups.filter((group) => group.position !== 'bottom');
|
|
412
|
+
const bottomNavigationGroups = navigationGroups.filter((group) => group.position === 'bottom');
|
|
413
|
+
const clientNavigationItems = navigationGroups.flatMap((group) =>
|
|
414
|
+
group.items.map(({ id, href, matchId, match }) => ({
|
|
415
|
+
id,
|
|
416
|
+
href,
|
|
417
|
+
matchId,
|
|
418
|
+
match: normalizeNavigationMatch(match),
|
|
419
|
+
}))
|
|
420
|
+
);
|
|
292
421
|
const { title, description, showNestedSideBar = true, showHeader = true, reducedContentPadding = false } = Astro.props;
|
|
293
422
|
|
|
294
423
|
const canPageBeEmbedded = isEmbedEnabled();
|
|
@@ -537,133 +666,72 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
537
666
|
|
|
538
667
|
<nav class="flex flex-col flex-1 overflow-y-auto px-3 py-4 gap-1">
|
|
539
668
|
{
|
|
540
|
-
|
|
541
|
-
return (
|
|
542
|
-
<a
|
|
543
|
-
id={item.id}
|
|
544
|
-
data-role="nav-item"
|
|
545
|
-
href={item.href}
|
|
546
|
-
aria-label={item.label}
|
|
547
|
-
class={`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-[13px] font-medium transition-all duration-150 ${
|
|
548
|
-
item.current
|
|
549
|
-
? 'border-[rgb(var(--ec-accent)/0.2)] bg-[rgb(var(--ec-page-bg)/0.88)] text-[rgb(var(--ec-accent))] shadow-sm'
|
|
550
|
-
: 'border-transparent text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]'
|
|
551
|
-
}`}
|
|
552
|
-
title={item.label}
|
|
553
|
-
>
|
|
554
|
-
<item.icon className="h-4 w-4 flex-shrink-0" aria-hidden="true" />
|
|
555
|
-
<span class="nav-item-label">{item.label}</span>
|
|
556
|
-
</a>
|
|
557
|
-
);
|
|
558
|
-
})
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
{
|
|
562
|
-
browseItems.length > 0 && (
|
|
563
|
-
<Fragment>
|
|
564
|
-
<hr class="rail-divider my-3 border-t border-[rgb(var(--ec-sidebar-border)/0.7)]" />
|
|
565
|
-
|
|
566
|
-
<div class="rail-section-label px-3 pb-1 text-[0.65rem] font-semibold tracking-[0.18em] uppercase text-[rgb(var(--ec-sidebar-text)/0.5)]">
|
|
567
|
-
Browse
|
|
568
|
-
</div>
|
|
569
|
-
|
|
570
|
-
{browseItems.map((item) => (
|
|
571
|
-
<a
|
|
572
|
-
id={item.id}
|
|
573
|
-
href={item.href}
|
|
574
|
-
data-role="secondary-nav-item"
|
|
575
|
-
aria-label={item.label}
|
|
576
|
-
class={`nav-secondary-item flex items-center gap-3 px-3 py-2.5 rounded-xl border text-[13px] font-medium transition-all duration-150 ${
|
|
577
|
-
item.current
|
|
578
|
-
? 'border-[rgb(var(--ec-accent)/0.2)] bg-[rgb(var(--ec-page-bg)/0.88)] text-[rgb(var(--ec-accent))] shadow-sm'
|
|
579
|
-
: 'border-transparent text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]'
|
|
580
|
-
}`}
|
|
581
|
-
title={item.label}
|
|
582
|
-
>
|
|
583
|
-
<item.icon className="h-3.5 w-3.5 flex-shrink-0" aria-hidden="true" />
|
|
584
|
-
<span class="nav-item-label">{item.label}</span>
|
|
585
|
-
</a>
|
|
586
|
-
))}
|
|
587
|
-
</Fragment>
|
|
588
|
-
)
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
{
|
|
592
|
-
organizationItems.length > 0 && (
|
|
669
|
+
topNavigationGroups.map((group, groupIndex) => (
|
|
593
670
|
<Fragment>
|
|
594
|
-
<hr class="rail-divider my-3 border-t border-[rgb(var(--ec-sidebar-border)/0.7)]" />
|
|
671
|
+
{groupIndex > 0 && <hr class="rail-divider my-3 border-t border-[rgb(var(--ec-sidebar-border)/0.7)]" />}
|
|
595
672
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
673
|
+
{group.label && (
|
|
674
|
+
<div class="rail-section-label px-3 pb-1 text-[0.65rem] font-semibold tracking-[0.18em] uppercase text-[rgb(var(--ec-sidebar-text)/0.5)]">
|
|
675
|
+
{group.label}
|
|
676
|
+
</div>
|
|
677
|
+
)}
|
|
599
678
|
|
|
600
|
-
{
|
|
679
|
+
{group.items.map((item) => (
|
|
601
680
|
<a
|
|
602
681
|
id={item.id}
|
|
603
682
|
href={item.href}
|
|
604
|
-
|
|
683
|
+
target={item.target}
|
|
684
|
+
rel={item.rel}
|
|
685
|
+
data-role="vertical-nav-item"
|
|
605
686
|
aria-label={item.label}
|
|
606
|
-
class={`
|
|
687
|
+
class={`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-[13px] font-medium transition-all duration-150 ${
|
|
607
688
|
item.current
|
|
608
689
|
? 'border-[rgb(var(--ec-accent)/0.2)] bg-[rgb(var(--ec-page-bg)/0.88)] text-[rgb(var(--ec-accent))] shadow-sm'
|
|
609
690
|
: 'border-transparent text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]'
|
|
610
691
|
}`}
|
|
611
692
|
title={item.label}
|
|
612
693
|
>
|
|
613
|
-
<item.
|
|
694
|
+
<item.Icon className="h-4 w-4 flex-shrink-0" aria-hidden="true" />
|
|
614
695
|
<span class="nav-item-label">{item.label}</span>
|
|
615
696
|
</a>
|
|
616
697
|
))}
|
|
617
698
|
</Fragment>
|
|
618
|
-
)
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
{premiumFeatures.length > 0 && <hr class="rail-divider my-2 border-t border-[rgb(var(--ec-sidebar-border)/0.7)]" />}
|
|
622
|
-
|
|
623
|
-
{
|
|
624
|
-
premiumFeatures.map((item) => (
|
|
625
|
-
<a
|
|
626
|
-
id={item.id}
|
|
627
|
-
data-role="nav-item"
|
|
628
|
-
href={item.href}
|
|
629
|
-
aria-label={item.label}
|
|
630
|
-
class={`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-[13px] font-medium transition-all duration-150 ${
|
|
631
|
-
item.current
|
|
632
|
-
? 'border-[rgb(var(--ec-accent)/0.2)] bg-[rgb(var(--ec-page-bg)/0.88)] text-[rgb(var(--ec-accent))] shadow-sm'
|
|
633
|
-
: 'border-transparent text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]'
|
|
634
|
-
}`}
|
|
635
|
-
title={item.label}
|
|
636
|
-
>
|
|
637
|
-
<item.icon className="h-4 w-4 flex-shrink-0" aria-hidden="true" />
|
|
638
|
-
<span class="nav-item-label">{item.label}</span>
|
|
639
|
-
</a>
|
|
640
699
|
))
|
|
641
700
|
}
|
|
642
701
|
|
|
643
702
|
<div class="mt-auto pt-3">
|
|
644
703
|
{
|
|
645
|
-
|
|
704
|
+
bottomNavigationGroups.map((group) => (
|
|
646
705
|
<Fragment>
|
|
647
706
|
<hr class="rail-divider mb-3 border-t border-[rgb(var(--ec-sidebar-border)/0.7)]" />
|
|
648
|
-
|
|
707
|
+
|
|
708
|
+
{group.label && (
|
|
709
|
+
<div class="rail-section-label px-3 pb-1 text-[0.65rem] font-semibold tracking-[0.18em] uppercase text-[rgb(var(--ec-sidebar-text)/0.5)]">
|
|
710
|
+
{group.label}
|
|
711
|
+
</div>
|
|
712
|
+
)}
|
|
713
|
+
|
|
714
|
+
{group.items.map((item) => (
|
|
649
715
|
<a
|
|
650
716
|
id={item.id}
|
|
651
717
|
href={item.href}
|
|
652
|
-
|
|
718
|
+
target={item.target}
|
|
719
|
+
rel={item.rel}
|
|
720
|
+
data-role="vertical-nav-item"
|
|
653
721
|
aria-label={item.label}
|
|
654
|
-
class={`
|
|
722
|
+
class={`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-[13px] font-medium transition-all duration-150 ${
|
|
655
723
|
item.current
|
|
656
724
|
? 'border-[rgb(var(--ec-accent)/0.2)] bg-[rgb(var(--ec-page-bg)/0.88)] text-[rgb(var(--ec-accent))] shadow-sm'
|
|
657
725
|
: 'border-transparent text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]'
|
|
658
726
|
}`}
|
|
659
727
|
title={item.label}
|
|
660
728
|
>
|
|
661
|
-
<item.
|
|
729
|
+
<item.Icon className="h-4 w-4 flex-shrink-0" aria-hidden="true" />
|
|
662
730
|
<span class="nav-item-label">{item.label}</span>
|
|
663
731
|
</a>
|
|
664
732
|
))}
|
|
665
733
|
</Fragment>
|
|
666
|
-
)
|
|
734
|
+
))
|
|
667
735
|
}
|
|
668
736
|
</div>
|
|
669
737
|
</nav>
|
|
@@ -675,7 +743,7 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
675
743
|
aria-label="Collapse sidebar"
|
|
676
744
|
class="flex items-center gap-3 px-3 py-2.5 rounded-xl border border-transparent text-[13px] font-medium text-[rgb(var(--ec-sidebar-text))] hover:border-[rgb(var(--ec-sidebar-border)/0.65)] hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))] transition-all duration-150 w-full"
|
|
677
745
|
>
|
|
678
|
-
<PanelLeftClose className="h-4 w-4 flex-shrink-0 nav-collapse-icon" aria-hidden="true" />
|
|
746
|
+
<LucideIcons.PanelLeftClose className="h-4 w-4 flex-shrink-0 nav-collapse-icon" aria-hidden="true" />
|
|
679
747
|
<span class="nav-label">Collapse</span>
|
|
680
748
|
</button>
|
|
681
749
|
</div>
|
|
@@ -725,8 +793,7 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
725
793
|
<ClientRouter />
|
|
726
794
|
<script
|
|
727
795
|
define:vars={{
|
|
728
|
-
|
|
729
|
-
currentNavigationItem,
|
|
796
|
+
clientNavigationItems,
|
|
730
797
|
canPageBeEmbedded,
|
|
731
798
|
verticalNavAutoCollapsePaths,
|
|
732
799
|
}}
|
|
@@ -746,10 +813,13 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
746
813
|
'hover:text-[rgb(var(--ec-page-text))]',
|
|
747
814
|
];
|
|
748
815
|
|
|
749
|
-
const isNavItemCurrent = (
|
|
750
|
-
|
|
816
|
+
const isNavItemCurrent = (item, pathname) => {
|
|
817
|
+
const matchId = item?.matchId || item?.id;
|
|
818
|
+
|
|
819
|
+
if (matchId === '/') {
|
|
820
|
+
const targetPath = item?.href ? new URL(item.href, window.location.origin).pathname : '/';
|
|
751
821
|
return (
|
|
752
|
-
pathname ===
|
|
822
|
+
pathname === targetPath ||
|
|
753
823
|
(pathname.includes('/docs') && !pathname.includes('/docs/custom')) ||
|
|
754
824
|
pathname.includes('/architecture/') ||
|
|
755
825
|
pathname.includes('/visualiser') ||
|
|
@@ -757,52 +827,57 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
757
827
|
);
|
|
758
828
|
}
|
|
759
829
|
|
|
760
|
-
if (
|
|
830
|
+
if (matchId === '/schemas/explorer') {
|
|
761
831
|
return pathname.includes('/schemas/explorer') && !pathname.includes('/schemas/fields');
|
|
762
832
|
}
|
|
763
833
|
|
|
764
|
-
if (
|
|
834
|
+
if (matchId === '/schemas/fields') {
|
|
765
835
|
return pathname.includes('/schemas/fields');
|
|
766
836
|
}
|
|
767
837
|
|
|
768
|
-
if (
|
|
769
|
-
return pathname
|
|
838
|
+
if (matchId === '/discover') {
|
|
839
|
+
return pathname.endsWith('/discover') || pathname.includes('/discover/');
|
|
770
840
|
}
|
|
771
841
|
|
|
772
|
-
if (
|
|
842
|
+
if (matchId === '/studio') {
|
|
773
843
|
return pathname.includes('/studio');
|
|
774
844
|
}
|
|
775
845
|
|
|
776
|
-
if (
|
|
846
|
+
if (matchId === '/docs/custom') {
|
|
777
847
|
return pathname.includes('/docs/custom');
|
|
778
848
|
}
|
|
779
849
|
|
|
850
|
+
if (matchId === '/settings/general') {
|
|
851
|
+
return pathname.includes('/settings');
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const matches = Array.isArray(item?.match) ? item.match : item?.match ? [item.match] : [];
|
|
855
|
+
if (matches.length > 0) {
|
|
856
|
+
return matches.some((match) => {
|
|
857
|
+
if (/^https?:\/\//.test(match)) return false;
|
|
858
|
+
|
|
859
|
+
return pathname === match || pathname.startsWith(match);
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
if (item?.href) {
|
|
864
|
+
if (/^https?:\/\//.test(item.href)) return false;
|
|
865
|
+
|
|
866
|
+
const targetPath = new URL(item.href, window.location.origin).pathname;
|
|
867
|
+
return pathname === targetPath;
|
|
868
|
+
}
|
|
869
|
+
|
|
780
870
|
return false;
|
|
781
871
|
};
|
|
782
872
|
|
|
783
873
|
const syncNavItemStates = () => {
|
|
784
874
|
const pathname = window.location.pathname;
|
|
785
|
-
const navItems = document.querySelectorAll('[data-role="nav-item"]');
|
|
786
|
-
const secondaryNavItems = document.querySelectorAll('[data-role="secondary-nav-item"]');
|
|
875
|
+
const navItems = document.querySelectorAll('[data-role="vertical-nav-item"]');
|
|
787
876
|
|
|
788
877
|
navItems.forEach((item) => {
|
|
789
878
|
const id = item.getAttribute('id');
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
if (isCurrent) {
|
|
793
|
-
item.classList.remove(...INACTIVE_NAV_CLASSES);
|
|
794
|
-
item.classList.add(...ACTIVE_NAV_CLASSES);
|
|
795
|
-
} else {
|
|
796
|
-
item.classList.remove(...ACTIVE_NAV_CLASSES);
|
|
797
|
-
item.classList.add(...INACTIVE_NAV_CLASSES);
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
|
|
801
|
-
secondaryNavItems.forEach((item) => {
|
|
802
|
-
const id = item.getAttribute('id');
|
|
803
|
-
const href = item.getAttribute('href');
|
|
804
|
-
const targetPath = href ? new URL(href, window.location.origin).pathname : null;
|
|
805
|
-
const isCurrent = id === '/discover' ? isNavItemCurrent(id, pathname) : targetPath ? pathname === targetPath : false;
|
|
879
|
+
const navigationItem = clientNavigationItems.find((navItem) => navItem.id === id);
|
|
880
|
+
const isCurrent = navigationItem ? isNavItemCurrent(navigationItem, pathname) : false;
|
|
806
881
|
|
|
807
882
|
if (isCurrent) {
|
|
808
883
|
item.classList.remove(...INACTIVE_NAV_CLASSES);
|
|
@@ -939,20 +1014,6 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
|
|
|
939
1014
|
|
|
940
1015
|
syncNavItemStates();
|
|
941
1016
|
|
|
942
|
-
const navItems = document.querySelectorAll('[data-role="nav-item"]');
|
|
943
|
-
|
|
944
|
-
// Navigation items simply navigate to their href - no toggle logic
|
|
945
|
-
navItems.forEach((item) => {
|
|
946
|
-
item.onclick = (e) => {
|
|
947
|
-
const id = item.getAttribute('id');
|
|
948
|
-
const navItem = navigationItems.find((navItem) => navItem.id === id);
|
|
949
|
-
|
|
950
|
-
if (navItem && navItem.href) {
|
|
951
|
-
window.location.href = navItem.href;
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
});
|
|
955
|
-
|
|
956
1017
|
if (verticalNavToggle) {
|
|
957
1018
|
verticalNavToggle.onclick = () => {
|
|
958
1019
|
const isCollapsed = verticalNavRail?.getAttribute('data-collapsed') === 'true';
|