@eventcatalog/core 3.17.5 → 3.18.0
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/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-MJVOXKKM.js → chunk-3XKMODP4.js} +1 -1
- package/dist/{chunk-VWSQYMKF.js → chunk-52VBVLRT.js} +1 -1
- package/dist/{chunk-LLGEQ4MZ.js → chunk-7CZBLKHQ.js} +1 -1
- package/dist/{chunk-O6SVMZR3.js → chunk-GSHSX7NU.js} +1 -1
- package/dist/{chunk-6LCHHROP.js → chunk-OQ6UFIEN.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- 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/EnvironmentDropdown.tsx +1 -1
- package/eventcatalog/src/components/Header.astro +5 -5
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +10 -6
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraphPortal.tsx +1 -1
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +10 -10
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +15 -13
- package/eventcatalog/src/components/Search/Search.astro +2 -2
- package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +1 -1
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +5 -6
- package/eventcatalog/src/content.config.ts +18 -3
- package/eventcatalog/src/enterprise/mcp/mcp-server.ts +11 -17
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +2 -26
- package/eventcatalog/src/pages/_index.astro +138 -113
- package/eventcatalog/src/pages/index.astro +17 -5
- package/eventcatalog/src/styles/theme.css +7 -2
- package/eventcatalog/src/styles/themes/forest.css +7 -7
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +5 -1
- package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +3 -1
- package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +8 -2
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +1 -1
- package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +2 -2
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +13 -4
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +4 -1
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +80 -17
- package/eventcatalog/tailwind.config.mjs +11 -2
- package/package.json +4 -4
|
@@ -299,7 +299,7 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
299
299
|
<div class="flex">
|
|
300
300
|
<aside class="flex" id="eventcatalog-vertical-nav">
|
|
301
301
|
<div
|
|
302
|
-
class="fixed flex flex-col items-center w-14 h-screen py-3 bg-[rgb(var(--ec-sidebar-bg))] bg-gradient-to-
|
|
302
|
+
class="fixed flex flex-col items-center w-14 h-screen py-3 bg-[rgb(var(--ec-sidebar-bg))] bg-gradient-to-t from-[rgb(var(--ec-accent)/0.08)] to-[rgb(var(--ec-sidebar-bg))] border-r border-[rgb(var(--ec-sidebar-border))] z-20 shadow-md justify-between"
|
|
303
303
|
>
|
|
304
304
|
<nav class="flex flex-col h-[calc(100vh-70px)] justify-between">
|
|
305
305
|
<div class="flex flex-col items-center flex-1 space-y-6">
|
|
@@ -333,30 +333,6 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
333
333
|
|
|
334
334
|
<hr class="w-8 border-t border-[rgb(var(--ec-sidebar-border))]" />
|
|
335
335
|
|
|
336
|
-
{
|
|
337
|
-
studioNavigationItem.length > 0 && (
|
|
338
|
-
<a
|
|
339
|
-
id={studioNavigationItem[0].id}
|
|
340
|
-
data-role="nav-item"
|
|
341
|
-
href={studioNavigationItem[0].href}
|
|
342
|
-
aria-label={studioNavigationItem[0].label}
|
|
343
|
-
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-[rgb(var(--ec-sidebar-active-text))] bg-[rgb(var(--ec-sidebar-active-bg))]' : 'hover:bg-[rgb(var(--ec-sidebar-hover-bg))] hover:text-[rgb(var(--ec-sidebar-active-text))] text-[rgb(var(--ec-sidebar-text))]'}`}
|
|
344
|
-
>
|
|
345
|
-
<div class="has-tooltip">
|
|
346
|
-
<span
|
|
347
|
-
class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap"
|
|
348
|
-
aria-hidden="true"
|
|
349
|
-
>
|
|
350
|
-
{studioNavigationItem[0].label}
|
|
351
|
-
</span>
|
|
352
|
-
<SquareDashedMousePointerIcon className="h-6 w-6" aria-hidden="true" />
|
|
353
|
-
</div>
|
|
354
|
-
</a>
|
|
355
|
-
)
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
{studioNavigationItem.length > 0 && <hr class="w-8 border-t border-[rgb(var(--ec-sidebar-border))]" />}
|
|
359
|
-
|
|
360
336
|
{
|
|
361
337
|
premiumFeatures.map((item) => (
|
|
362
338
|
<a
|
|
@@ -420,7 +396,7 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
420
396
|
showNestedSideBar && (
|
|
421
397
|
<SideNav
|
|
422
398
|
id="sidebar"
|
|
423
|
-
class={`sidebar-transition h-content bg-[rgb(var(--ec-sidebar-bg))] border-r border-[rgb(var(--ec-sidebar-border))] w-[320px] ml-14`}
|
|
399
|
+
class={`sidebar-transition h-content bg-[rgb(var(--ec-sidebar-bg))] bg-gradient-to-bl from-[rgb(var(--ec-sidebar-bg))] via-[rgb(var(--ec-sidebar-bg))] to-[rgb(var(--ec-accent)/0.08)] border-r border-[rgb(var(--ec-sidebar-border))] w-[320px] ml-14`}
|
|
424
400
|
/>
|
|
425
401
|
)
|
|
426
402
|
}
|
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { buildUrl } from '@utils/url-builder';
|
|
3
|
-
import {
|
|
4
|
-
ChatBubbleLeftIcon,
|
|
5
|
-
RectangleGroupIcon,
|
|
6
|
-
ServerIcon,
|
|
7
|
-
CodeBracketIcon,
|
|
8
|
-
DocumentTextIcon,
|
|
9
|
-
ArrowRightIcon,
|
|
10
|
-
PlusIcon,
|
|
11
|
-
} from '@heroicons/react/24/outline';
|
|
3
|
+
import { ArrowRightIcon, PlusIcon } from '@heroicons/react/24/outline';
|
|
12
4
|
import config from '@config';
|
|
13
5
|
|
|
14
|
-
import {
|
|
15
|
-
import { getDomains } from '@utils/collections/domains';
|
|
16
|
-
import { getServices } from '@utils/collections/services';
|
|
17
|
-
import { getFlows } from '@utils/collections/flows';
|
|
6
|
+
import { getCollection } from 'astro:content';
|
|
18
7
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
19
|
-
import { BookOpenText, Workflow, TableProperties, BookUser,
|
|
8
|
+
import { BookOpenText, Workflow, TableProperties, BookUser, Code2, FileJson } from 'lucide-react';
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
// Lightweight data fetch: only raw collections, no hydration.
|
|
11
|
+
// The homepage only needs counts + one item per type for default URLs.
|
|
12
|
+
const [allDomains, allServices, allEvents, allCommands, allQueries, allFlows] = await Promise.all([
|
|
13
|
+
getCollection('domains'),
|
|
14
|
+
getCollection('services'),
|
|
15
|
+
getCollection('events'),
|
|
16
|
+
getCollection('commands'),
|
|
17
|
+
getCollection('queries'),
|
|
18
|
+
getCollection('flows'),
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const isCurrentVersion = (item: { data: { hidden?: boolean }; filePath?: string }) =>
|
|
22
|
+
item.data.hidden !== true && !item.filePath?.includes('versioned');
|
|
23
|
+
|
|
24
|
+
const domains = allDomains.filter(isCurrentVersion);
|
|
25
|
+
const services = allServices.filter(isCurrentVersion);
|
|
26
|
+
const messages = [...allEvents, ...allCommands, ...allQueries].filter(isCurrentVersion);
|
|
27
|
+
const flows = allFlows.filter(isCurrentVersion);
|
|
26
28
|
|
|
27
29
|
// Check if catalog has content
|
|
28
30
|
const hasContent = domains.length > 0 || services.length > 0 || messages.length > 0 || flows.length > 0;
|
|
29
31
|
|
|
30
32
|
const getDefaultUrl = (route: string, defaultValue: string) => {
|
|
31
|
-
if (domains.length > 0) return buildUrl(`/${route}/domains/${domains[0].data.id}/${domains[0].data.
|
|
32
|
-
if (services.length > 0) return buildUrl(`/${route}/services/${services[0].data.id}/${services[0].data.
|
|
33
|
-
if (flows.length > 0) return buildUrl(`/${route}/flows/${flows[0].data.id}/${flows[0].data.
|
|
33
|
+
if (domains.length > 0) return buildUrl(`/${route}/domains/${domains[0].data.id}/${domains[0].data.version}`);
|
|
34
|
+
if (services.length > 0) return buildUrl(`/${route}/services/${services[0].data.id}/${services[0].data.version}`);
|
|
35
|
+
if (flows.length > 0) return buildUrl(`/${route}/flows/${flows[0].data.id}/${flows[0].data.version}`);
|
|
34
36
|
return buildUrl(defaultValue);
|
|
35
37
|
};
|
|
36
38
|
|
|
@@ -40,10 +42,9 @@ const topTiles = [
|
|
|
40
42
|
count: domains.length,
|
|
41
43
|
description: 'Business domains',
|
|
42
44
|
href: buildUrl('/discover/domains'),
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
textColor: 'text-yellow-600',
|
|
45
|
+
badgeBg: 'bg-[rgb(var(--ec-badge-domain-bg))]',
|
|
46
|
+
badgeText: 'text-[rgb(var(--ec-badge-domain-text))]',
|
|
47
|
+
glowColor: 'var(--ec-badge-domain-text)',
|
|
47
48
|
emptyText: 'No domains yet',
|
|
48
49
|
addHref: 'https://www.eventcatalog.dev/docs/domains',
|
|
49
50
|
},
|
|
@@ -52,10 +53,9 @@ const topTiles = [
|
|
|
52
53
|
count: services.length,
|
|
53
54
|
description: 'Documented services',
|
|
54
55
|
href: buildUrl('/discover/services'),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
textColor: 'text-pink-600',
|
|
56
|
+
badgeBg: 'bg-[rgb(var(--ec-badge-service-bg))]',
|
|
57
|
+
badgeText: 'text-[rgb(var(--ec-badge-service-text))]',
|
|
58
|
+
glowColor: 'var(--ec-badge-service-text)',
|
|
59
59
|
emptyText: 'No services yet',
|
|
60
60
|
addHref: 'https://www.eventcatalog.dev/docs/services',
|
|
61
61
|
},
|
|
@@ -64,10 +64,9 @@ const topTiles = [
|
|
|
64
64
|
count: messages.length,
|
|
65
65
|
description: 'Events, commands & queries',
|
|
66
66
|
href: buildUrl('/discover/events'),
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
textColor: 'text-blue-600',
|
|
67
|
+
badgeBg: 'bg-[rgb(var(--ec-badge-message-bg))]',
|
|
68
|
+
badgeText: 'text-[rgb(var(--ec-badge-message-text))]',
|
|
69
|
+
glowColor: 'var(--ec-badge-message-text)',
|
|
71
70
|
emptyText: 'No messages yet',
|
|
72
71
|
addHref: 'https://www.eventcatalog.dev/docs/messages',
|
|
73
72
|
},
|
|
@@ -76,10 +75,9 @@ const topTiles = [
|
|
|
76
75
|
count: flows.length,
|
|
77
76
|
description: 'Business flows',
|
|
78
77
|
href: buildUrl('/discover/flows'),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
textColor: 'text-[rgb(var(--ec-accent))]',
|
|
78
|
+
badgeBg: 'bg-[rgb(var(--ec-badge-query-bg))]',
|
|
79
|
+
badgeText: 'text-[rgb(var(--ec-badge-query-text))]',
|
|
80
|
+
glowColor: 'var(--ec-badge-query-text)',
|
|
83
81
|
emptyText: 'No flows yet',
|
|
84
82
|
addHref: 'https://www.eventcatalog.dev/docs/flows',
|
|
85
83
|
},
|
|
@@ -88,52 +86,58 @@ const topTiles = [
|
|
|
88
86
|
const quickActions = [
|
|
89
87
|
{
|
|
90
88
|
title: 'Documentation',
|
|
91
|
-
description: '
|
|
89
|
+
description: 'Explore all your events, commands, queries, and services in one place.',
|
|
92
90
|
icon: BookOpenText,
|
|
93
91
|
href: getDefaultUrl('docs', 'domains'),
|
|
94
92
|
iconBg: 'bg-blue-50 dark:bg-blue-500/10',
|
|
95
93
|
iconColor: 'text-blue-600 dark:text-blue-400',
|
|
94
|
+
span: 'lg:col-span-2',
|
|
96
95
|
},
|
|
97
96
|
{
|
|
98
97
|
title: 'Visualizer',
|
|
99
|
-
description: '
|
|
98
|
+
description: 'Visualize service relationships and message flows across your architecture.',
|
|
100
99
|
icon: Workflow,
|
|
101
100
|
href: getDefaultUrl('visualiser', 'domains'),
|
|
102
101
|
iconBg: 'bg-[rgb(var(--ec-accent-subtle))]',
|
|
103
102
|
iconColor: 'text-[rgb(var(--ec-accent))]',
|
|
103
|
+
span: '',
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
title: 'Discover',
|
|
107
|
-
description: '
|
|
107
|
+
description: 'Quickly find any event, service, or team across your entire catalog.',
|
|
108
108
|
icon: TableProperties,
|
|
109
109
|
href: buildUrl('/discover/events'),
|
|
110
110
|
iconBg: 'bg-teal-50 dark:bg-teal-500/10',
|
|
111
111
|
iconColor: 'text-teal-600 dark:text-teal-400',
|
|
112
|
+
span: '',
|
|
112
113
|
},
|
|
113
114
|
{
|
|
114
115
|
title: 'Schema Explorer',
|
|
115
|
-
description: '
|
|
116
|
+
description: 'Track schema evolution, compare versions, and catch breaking changes.',
|
|
116
117
|
icon: FileJson,
|
|
117
118
|
href: buildUrl('/schemas/explorer'),
|
|
118
119
|
iconBg: 'bg-amber-50 dark:bg-amber-500/10',
|
|
119
120
|
iconColor: 'text-amber-600 dark:text-amber-400',
|
|
121
|
+
span: '',
|
|
120
122
|
},
|
|
121
123
|
{
|
|
122
124
|
title: 'Team Directory',
|
|
123
|
-
description: '
|
|
125
|
+
description: 'See who owns what — find team contacts and service ownership at a glance.',
|
|
124
126
|
icon: BookUser,
|
|
125
127
|
href: buildUrl('/directory/users'),
|
|
126
128
|
iconBg: 'bg-orange-50 dark:bg-orange-500/10',
|
|
127
129
|
iconColor: 'text-orange-600 dark:text-orange-400',
|
|
130
|
+
span: '',
|
|
128
131
|
},
|
|
129
132
|
{
|
|
130
133
|
title: 'API & SDK',
|
|
131
|
-
description: '
|
|
134
|
+
description: 'Query and manage your catalog programmatically with a fully-typed SDK.',
|
|
132
135
|
icon: Code2,
|
|
133
136
|
href: 'https://www.eventcatalog.dev/docs/sdk',
|
|
134
137
|
iconBg: 'bg-indigo-50 dark:bg-indigo-500/10',
|
|
135
138
|
iconColor: 'text-indigo-600 dark:text-indigo-400',
|
|
136
139
|
external: true,
|
|
140
|
+
span: 'lg:col-span-2',
|
|
137
141
|
},
|
|
138
142
|
];
|
|
139
143
|
---
|
|
@@ -141,83 +145,50 @@ const quickActions = [
|
|
|
141
145
|
<VerticalSideBarLayout title="EventCatalog">
|
|
142
146
|
<div class="min-h-screen font-inter">
|
|
143
147
|
<!-- Hero Section -->
|
|
144
|
-
<div class="relative
|
|
145
|
-
<main class="
|
|
146
|
-
<div class="
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
config.tagline ||
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
</p>
|
|
156
|
-
|
|
157
|
-
<!-- Primary CTAs -->
|
|
158
|
-
<div class="flex flex-wrap items-center gap-3">
|
|
159
|
-
<a
|
|
160
|
-
href={getDefaultUrl('docs', 'domains')}
|
|
161
|
-
class="inline-flex items-center gap-2 px-5 py-2.5 bg-[rgb(var(--ec-button-bg))] text-[rgb(var(--ec-button-text))] rounded-lg font-medium hover:bg-[rgb(var(--ec-button-bg-hover))] transition-colors"
|
|
162
|
-
>
|
|
163
|
-
<BookOpenText className="w-4 h-4" />
|
|
164
|
-
Explore Docs
|
|
165
|
-
</a>
|
|
166
|
-
<a
|
|
167
|
-
href={getDefaultUrl('visualiser', 'domains')}
|
|
168
|
-
class="inline-flex items-center gap-2 px-5 py-2.5 bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] text-[rgb(var(--ec-page-text))] border border-[rgb(var(--ec-page-border))] rounded-lg font-medium hover:bg-[rgb(var(--ec-content-hover))] hover:border-[rgb(var(--ec-accent))] transition-colors"
|
|
169
|
-
>
|
|
170
|
-
<Workflow className="w-4 h-4" />
|
|
171
|
-
View Architecture
|
|
172
|
-
</a>
|
|
148
|
+
<div class="relative">
|
|
149
|
+
<main class="px-6 lg:px-8 pt-10 pb-8 max-w-[85em]">
|
|
150
|
+
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
|
151
|
+
<div>
|
|
152
|
+
<h1 class="text-2xl md:text-3xl font-bold mb-1 text-[rgb(var(--ec-page-text))] tracking-tight">
|
|
153
|
+
Welcome to <span class="italic text-[rgb(var(--ec-accent))]">{config?.organizationName || 'EventCatalog'}</span>
|
|
154
|
+
</h1>
|
|
155
|
+
<p class="text-sm text-[rgb(var(--ec-page-text-muted))] leading-relaxed">
|
|
156
|
+
{config.tagline || 'Explore and understand your event-driven architecture'}
|
|
157
|
+
</p>
|
|
173
158
|
</div>
|
|
174
159
|
</div>
|
|
175
160
|
</main>
|
|
176
161
|
</div>
|
|
177
162
|
|
|
178
163
|
<!-- Main Content -->
|
|
179
|
-
<main class="
|
|
180
|
-
<!--
|
|
164
|
+
<main class="px-6 lg:px-8 pb-8 max-w-[85em]">
|
|
165
|
+
<!-- Stat Cards -->
|
|
181
166
|
<section class="mb-10">
|
|
182
|
-
<div class="flex items-center justify-between mb-4">
|
|
183
|
-
<h2 class="text-sm font-semibold uppercase tracking-wider text-[rgb(var(--ec-page-text-muted))]">Your Catalog</h2>
|
|
184
|
-
{
|
|
185
|
-
hasContent && (
|
|
186
|
-
<a
|
|
187
|
-
href={buildUrl('/discover/events')}
|
|
188
|
-
class="text-sm text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] flex items-center gap-1"
|
|
189
|
-
>
|
|
190
|
-
View all
|
|
191
|
-
<ArrowRightIcon className="w-3 h-3" />
|
|
192
|
-
</a>
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
</div>
|
|
196
167
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
197
168
|
{
|
|
198
169
|
topTiles.map((tile: any) =>
|
|
199
170
|
tile.count > 0 ? (
|
|
200
171
|
<a
|
|
201
172
|
href={tile.href}
|
|
202
|
-
class=
|
|
173
|
+
class="ec-stat-card group relative overflow-hidden bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] p-5 rounded-xl border transition-all"
|
|
174
|
+
style={`--glow-color: rgb(${tile.glowColor}); border-color: rgb(${tile.glowColor} / 0.2);`}
|
|
203
175
|
>
|
|
204
|
-
<div class=
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
176
|
+
<div class="flex items-center justify-between mb-4">
|
|
177
|
+
<span
|
|
178
|
+
class={`inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-semibold ${tile.badgeBg} ${tile.badgeText}`}
|
|
179
|
+
>
|
|
180
|
+
{tile.title}
|
|
181
|
+
</span>
|
|
210
182
|
</div>
|
|
211
|
-
<div class="text-
|
|
183
|
+
<div class="text-3xl font-bold text-[rgb(var(--ec-page-text))] mb-1">{tile.count}</div>
|
|
212
184
|
<div class="text-sm text-[rgb(var(--ec-page-text-muted))]">{tile.description}</div>
|
|
213
185
|
</a>
|
|
214
186
|
) : (
|
|
215
|
-
<div class="relative bg-[rgb(var(--ec-content-hover))] p-5 rounded-xl border border-dashed border-[rgb(var(--ec-page-border))]">
|
|
216
|
-
<div class=
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
</div>
|
|
187
|
+
<div class="relative overflow-hidden bg-[rgb(var(--ec-content-hover))] p-5 rounded-xl border border-dashed border-[rgb(var(--ec-page-border))]">
|
|
188
|
+
<div class="flex items-center justify-between mb-4">
|
|
189
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-semibold bg-[rgb(var(--ec-badge-default-bg))] text-[rgb(var(--ec-badge-default-text))]">
|
|
190
|
+
{tile.title}
|
|
191
|
+
</span>
|
|
221
192
|
</div>
|
|
222
193
|
<div class="text-sm font-medium text-[rgb(var(--ec-page-text-muted))] mb-2">{tile.emptyText}</div>
|
|
223
194
|
<a
|
|
@@ -237,20 +208,26 @@ const quickActions = [
|
|
|
237
208
|
|
|
238
209
|
<!-- Explore Section - Full Width -->
|
|
239
210
|
<section class="mb-10">
|
|
240
|
-
<
|
|
241
|
-
|
|
211
|
+
<div class="flex items-center gap-4 mb-4">
|
|
212
|
+
<h2 class="text-sm font-semibold uppercase tracking-wider text-[rgb(var(--ec-page-text-muted))] flex-shrink-0">
|
|
213
|
+
Explore
|
|
214
|
+
</h2>
|
|
215
|
+
<div class="flex-1 h-px bg-[rgb(var(--ec-page-border))]"></div>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
242
218
|
{
|
|
243
219
|
quickActions.map((action: any) => (
|
|
244
220
|
<a
|
|
245
221
|
href={action.href}
|
|
246
222
|
target={action.external ? '_blank' : undefined}
|
|
247
|
-
class=
|
|
223
|
+
class={`ec-stat-card group flex flex-col bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] p-6 rounded-xl border border-[rgb(var(--ec-page-border))] hover:border-[rgb(var(--ec-accent)/0.5)] transition-all min-h-[160px] ${action.span}`}
|
|
224
|
+
style="--glow-color: rgb(var(--ec-accent));"
|
|
248
225
|
>
|
|
249
|
-
<div class=
|
|
250
|
-
<action.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
<
|
|
226
|
+
<div class="flex items-center gap-3 mb-3">
|
|
227
|
+
<div class={`${action.iconBg} p-2.5 rounded-lg`}>
|
|
228
|
+
<action.icon className={`w-5 h-5 ${action.iconColor}`} />
|
|
229
|
+
</div>
|
|
230
|
+
<span class="font-semibold text-[rgb(var(--ec-page-text))] flex items-center gap-1.5">
|
|
254
231
|
{action.title}
|
|
255
232
|
{action.external && (
|
|
256
233
|
<svg
|
|
@@ -267,9 +244,9 @@ const quickActions = [
|
|
|
267
244
|
/>
|
|
268
245
|
</svg>
|
|
269
246
|
)}
|
|
270
|
-
</
|
|
271
|
-
<div class="text-sm text-[rgb(var(--ec-page-text-muted))] leading-relaxed">{action.description}</div>
|
|
247
|
+
</span>
|
|
272
248
|
</div>
|
|
249
|
+
<p class="text-sm text-[rgb(var(--ec-page-text-muted))] leading-relaxed">{action.description}</p>
|
|
273
250
|
</a>
|
|
274
251
|
))
|
|
275
252
|
}
|
|
@@ -336,3 +313,51 @@ const quickActions = [
|
|
|
336
313
|
</main>
|
|
337
314
|
</div>
|
|
338
315
|
</VerticalSideBarLayout>
|
|
316
|
+
|
|
317
|
+
<style is:global>
|
|
318
|
+
.ec-stat-card {
|
|
319
|
+
position: relative;
|
|
320
|
+
}
|
|
321
|
+
.ec-stat-card::before {
|
|
322
|
+
content: '';
|
|
323
|
+
position: absolute;
|
|
324
|
+
inset: 0;
|
|
325
|
+
border-radius: inherit;
|
|
326
|
+
transition: opacity 0.3s ease;
|
|
327
|
+
opacity: 0;
|
|
328
|
+
pointer-events: none;
|
|
329
|
+
z-index: 0;
|
|
330
|
+
}
|
|
331
|
+
/* Dark mode: radial glow that follows cursor */
|
|
332
|
+
:root[data-theme='dark'] .ec-stat-card::before {
|
|
333
|
+
background: radial-gradient(400px circle at var(--mouse-x, 50%) var(--mouse-y, 50%), var(--glow-color) 0%, transparent 70%);
|
|
334
|
+
}
|
|
335
|
+
:root[data-theme='dark'] .ec-stat-card:hover::before {
|
|
336
|
+
opacity: 0.15;
|
|
337
|
+
}
|
|
338
|
+
/* Light mode: subtle solid background */
|
|
339
|
+
:root:not([data-theme='dark']) .ec-stat-card::before,
|
|
340
|
+
:root[data-theme='light'] .ec-stat-card::before {
|
|
341
|
+
background: rgb(var(--ec-content-hover));
|
|
342
|
+
}
|
|
343
|
+
:root:not([data-theme='dark']) .ec-stat-card:hover::before,
|
|
344
|
+
:root[data-theme='light'] .ec-stat-card:hover::before {
|
|
345
|
+
opacity: 1;
|
|
346
|
+
}
|
|
347
|
+
.ec-stat-card > * {
|
|
348
|
+
position: relative;
|
|
349
|
+
z-index: 1;
|
|
350
|
+
}
|
|
351
|
+
</style>
|
|
352
|
+
|
|
353
|
+
<script>
|
|
354
|
+
document.querySelectorAll('.ec-stat-card').forEach((card) => {
|
|
355
|
+
card.addEventListener('mousemove', (e) => {
|
|
356
|
+
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
357
|
+
const x = (e as MouseEvent).clientX - rect.left;
|
|
358
|
+
const y = (e as MouseEvent).clientY - rect.top;
|
|
359
|
+
(e.currentTarget as HTMLElement).style.setProperty('--mouse-x', `${x}px`);
|
|
360
|
+
(e.currentTarget as HTMLElement).style.setProperty('--mouse-y', `${y}px`);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
</script>
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Footer from '@layouts/Footer.astro';
|
|
3
3
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
4
|
-
import components from '@components/MDX/page-components';
|
|
5
|
-
import mdxComponents from '@components/MDX/components';
|
|
6
|
-
import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
|
|
7
4
|
import { getMDXComponentsByName } from '@utils/markdown';
|
|
8
5
|
import { resourceToCollectionMap } from '@utils/collections/util';
|
|
9
6
|
import { buildUrl } from '@utils/url-builder';
|
|
@@ -13,6 +10,8 @@ import config from '@config';
|
|
|
13
10
|
|
|
14
11
|
let nodeGraphs: any[] = [];
|
|
15
12
|
let CustomContent = null;
|
|
13
|
+
let NodeGraph = null;
|
|
14
|
+
let customHomepageComponents: Record<string, any> = {};
|
|
16
15
|
|
|
17
16
|
import path from 'path';
|
|
18
17
|
import { existsSync, readFileSync } from 'fs';
|
|
@@ -26,8 +25,20 @@ if (existsSync(pathToUserDefinedLandingPage) && isCustomLandingPageEnabled()) {
|
|
|
26
25
|
// @ts-ignore
|
|
27
26
|
CustomContent = Object.values(customPages)[0]?.default || null;
|
|
28
27
|
|
|
28
|
+
const [{ default: pageComponents }, { default: mdxComponents }] = await Promise.all([
|
|
29
|
+
import('@components/MDX/page-components'),
|
|
30
|
+
import('@components/MDX/components'),
|
|
31
|
+
]);
|
|
32
|
+
customHomepageComponents = { ...pageComponents, ...mdxComponents(props) };
|
|
33
|
+
|
|
29
34
|
const rawContent = readFileSync(pathToUserDefinedLandingPage, 'utf-8');
|
|
30
35
|
nodeGraphs = getMDXComponentsByName(rawContent, 'NodeGraph') || [];
|
|
36
|
+
|
|
37
|
+
// Avoid pulling visualizer CSS into the default homepage bundle.
|
|
38
|
+
// Only load the NodeGraph component when the custom homepage actually uses it.
|
|
39
|
+
if (nodeGraphs.length > 0) {
|
|
40
|
+
NodeGraph = (await import('@components/MDX/NodeGraph/NodeGraph.astro')).default;
|
|
41
|
+
}
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
if (config.landingPage) {
|
|
@@ -42,12 +53,13 @@ if (config.landingPage) {
|
|
|
42
53
|
<div class="flex docs-layout w-full">
|
|
43
54
|
<div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
|
|
44
55
|
<div class="w-full !max-w-none">
|
|
45
|
-
<CustomContent components={
|
|
56
|
+
<CustomContent components={customHomepageComponents} />
|
|
46
57
|
</div>
|
|
47
58
|
<Footer />
|
|
48
59
|
</div>
|
|
49
60
|
</div>
|
|
50
|
-
{
|
|
61
|
+
{NodeGraph &&
|
|
62
|
+
nodeGraphs.length > 0 &&
|
|
51
63
|
nodeGraphs.map((nodeGraph: any) => {
|
|
52
64
|
const collection = resourceToCollectionMap[nodeGraph.type as keyof typeof resourceToCollectionMap];
|
|
53
65
|
return (
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
--ec-content-bg: 13 17 23; /* #0d1117 */
|
|
158
158
|
--ec-content-text: 201 209 217; /* #c9d1d9 - softer than pure white */
|
|
159
159
|
--ec-content-text-muted: 139 148 158; /* #8b949e */
|
|
160
|
-
--ec-content-text-secondary:
|
|
160
|
+
--ec-content-text-secondary: 170 178 186; /* #aab2ba - sidebar children text */
|
|
161
161
|
--ec-content-border: 33 38 45; /* #21262d */
|
|
162
162
|
--ec-content-hover: 22 27 34; /* #161b22 */
|
|
163
163
|
--ec-content-active: 33 38 45; /* #21262d */
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
/* Main content/docs area - base dark surface */
|
|
176
176
|
--ec-page-bg: 13 17 23; /* #0d1117 */
|
|
177
177
|
--ec-page-text: 240 246 252; /* #f0f6fc */
|
|
178
|
-
--ec-page-text-muted:
|
|
178
|
+
--ec-page-text-muted: 163 172 182; /* #a3acb6 */
|
|
179
179
|
--ec-page-border: 33 38 45; /* #21262d */
|
|
180
180
|
|
|
181
181
|
/* Card/elevated surfaces - for depth */
|
|
@@ -257,3 +257,8 @@
|
|
|
257
257
|
:root[data-theme="dark"] .prose table td {
|
|
258
258
|
border-color: rgb(33 38 45); /* #21262d */
|
|
259
259
|
}
|
|
260
|
+
|
|
261
|
+
/* Invert dark SVG icons in dark mode so they stay visible */
|
|
262
|
+
:root[data-theme="dark"] .ec-themed-icon {
|
|
263
|
+
filter: invert(1);
|
|
264
|
+
}
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
/* Forest Dark Mode */
|
|
107
107
|
:root[data-catalog-theme="forest"][data-theme="dark"] {
|
|
108
108
|
/* Header - deep forest dark */
|
|
109
|
-
--ec-header-bg:
|
|
109
|
+
--ec-header-bg: 3 7 18; /* #030712 gray-950 */
|
|
110
110
|
--ec-header-text: 243 244 246; /* #f3f4f6 gray-100 */
|
|
111
|
-
--ec-header-border:
|
|
111
|
+
--ec-header-border: 17 24 39; /* #111827 gray-900 */
|
|
112
112
|
|
|
113
113
|
/* Accent colors - muted forest green for dark */
|
|
114
114
|
--ec-accent: 74 222 128; /* #4ade80 (green-400) */
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
--ec-dropdown-bg: 17 24 39; /* #111827 */
|
|
128
128
|
--ec-dropdown-text: 209 213 219; /* #d1d5db */
|
|
129
129
|
--ec-dropdown-hover: 31 41 55; /* #1f2937 */
|
|
130
|
-
--ec-dropdown-border:
|
|
130
|
+
--ec-dropdown-border: 31 41 55; /* #1f2937 gray-800 */
|
|
131
131
|
|
|
132
132
|
/* Icons */
|
|
133
133
|
--ec-icon-color: 156 163 175; /* #9ca3af */
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
/* Sidebar / Vertical Nav */
|
|
137
137
|
--ec-sidebar-bg: 3 7 18; /* #030712 gray-950 */
|
|
138
138
|
--ec-sidebar-bg-gradient: 3 7 18; /* #030712 */
|
|
139
|
-
--ec-sidebar-border:
|
|
139
|
+
--ec-sidebar-border: 17 24 39; /* #111827 gray-900 */
|
|
140
140
|
--ec-sidebar-text: 156 163 175; /* #9ca3af */
|
|
141
141
|
--ec-sidebar-active-bg: 22 101 52; /* #166534 green-800 */
|
|
142
142
|
--ec-sidebar-active-text: 255 255 255; /* #ffffff */
|
|
@@ -147,13 +147,13 @@
|
|
|
147
147
|
--ec-content-text: 243 244 246; /* #f3f4f6 */
|
|
148
148
|
--ec-content-text-muted: 156 163 175; /* #9ca3af */
|
|
149
149
|
--ec-content-text-secondary: 156 163 175; /* #9ca3af */
|
|
150
|
-
--ec-content-border:
|
|
150
|
+
--ec-content-border: 17 24 39; /* #111827 gray-900 */
|
|
151
151
|
--ec-content-hover: 17 24 39; /* #111827 */
|
|
152
152
|
--ec-content-active: 31 41 55; /* #1f2937 */
|
|
153
153
|
|
|
154
154
|
/* Input fields */
|
|
155
155
|
--ec-input-bg: 17 24 39; /* #111827 */
|
|
156
|
-
--ec-input-border:
|
|
156
|
+
--ec-input-border: 31 41 55; /* #1f2937 gray-800 */
|
|
157
157
|
--ec-input-text: 243 244 246; /* #f3f4f6 */
|
|
158
158
|
--ec-input-placeholder: 107 114 128; /* #6b7280 */
|
|
159
159
|
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
--ec-page-bg: 3 7 18; /* #030712 */
|
|
166
166
|
--ec-page-text: 243 244 246; /* #f3f4f6 */
|
|
167
167
|
--ec-page-text-muted: 156 163 175; /* #9ca3af */
|
|
168
|
-
--ec-page-border:
|
|
168
|
+
--ec-page-border: 17 24 39; /* #111827 gray-900 */
|
|
169
169
|
|
|
170
170
|
/* Card/elevated surfaces */
|
|
171
171
|
--ec-card-bg: 3 7 18; /* #030712 */
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
generateIdForNode,
|
|
9
9
|
buildContextMenuForService,
|
|
10
10
|
buildContextMenuForResource,
|
|
11
|
+
DEFAULT_NODE_WIDTH,
|
|
12
|
+
DEFAULT_NODE_HEIGHT,
|
|
11
13
|
} from './utils/utils';
|
|
12
14
|
import { MarkerType } from '@xyflow/react';
|
|
13
15
|
import { findMatchingNodes } from '@utils/collections/util';
|
|
@@ -84,6 +86,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
84
86
|
type: 'default',
|
|
85
87
|
style: {
|
|
86
88
|
strokeWidth: 1,
|
|
89
|
+
stroke: 'var(--ec-edge-stroke, #6b7280)',
|
|
87
90
|
},
|
|
88
91
|
});
|
|
89
92
|
}
|
|
@@ -119,6 +122,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
119
122
|
type: 'default',
|
|
120
123
|
style: {
|
|
121
124
|
strokeWidth: 1,
|
|
125
|
+
stroke: 'var(--ec-edge-stroke, #6b7280)',
|
|
122
126
|
},
|
|
123
127
|
});
|
|
124
128
|
}
|
|
@@ -277,7 +281,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
277
281
|
});
|
|
278
282
|
|
|
279
283
|
nodes.forEach((node: any) => {
|
|
280
|
-
flow.setNode(node.id, { width:
|
|
284
|
+
flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
|
|
281
285
|
});
|
|
282
286
|
|
|
283
287
|
edges.forEach((edge: any) => {
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
createEdge,
|
|
9
9
|
getColorFromString,
|
|
10
10
|
buildContextMenuForResource,
|
|
11
|
+
DEFAULT_NODE_WIDTH,
|
|
12
|
+
DEFAULT_NODE_HEIGHT,
|
|
11
13
|
} from '@utils/node-graphs/utils/utils';
|
|
12
14
|
|
|
13
15
|
import { findInMap, createVersionedMap, mergeMaps, collectionToResourceMap } from '@utils/collections/util';
|
|
@@ -208,7 +210,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
208
210
|
});
|
|
209
211
|
|
|
210
212
|
nodes.forEach((node: any) => {
|
|
211
|
-
flow.setNode(node.id, { width:
|
|
213
|
+
flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
|
|
212
214
|
});
|
|
213
215
|
|
|
214
216
|
edges.forEach((edge: any) => {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
2
2
|
import dagre from 'dagre';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
generateIdForNode,
|
|
5
|
+
createDagreGraph,
|
|
6
|
+
calculatedNodes,
|
|
7
|
+
createEdge,
|
|
8
|
+
getOperationFields,
|
|
9
|
+
} from '@utils/node-graphs/utils/utils';
|
|
4
10
|
import { findInMap, createVersionedMap } from '@utils/collections/util';
|
|
5
11
|
import type { Node, Edge } from '@xyflow/react';
|
|
6
12
|
import { getDomains } from '@utils/collections/domains';
|
|
@@ -170,7 +176,7 @@ export const getDomainsCanvasData = async (): Promise<DomainCanvasData> => {
|
|
|
170
176
|
position: { x: 0, y: 0 }, // Temporary position, will be calculated by dagre
|
|
171
177
|
data: {
|
|
172
178
|
mode: 'simple',
|
|
173
|
-
message: { ...messageObject.data },
|
|
179
|
+
message: { ...messageObject.data, ...getOperationFields(messageObject.data) },
|
|
174
180
|
},
|
|
175
181
|
sourcePosition: 'right',
|
|
176
182
|
targetPosition: 'left',
|