@eventcatalog/core 3.48.4 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/catalog-to-astro-content-directory.cjs +1 -1
- package/dist/chunk-BWN544LB.js +73 -0
- package/dist/{chunk-XNVSSL4W.js → chunk-JTZT2SDF.js} +1 -1
- package/dist/{chunk-JY4H7A4S.js → chunk-M2ZRT7KQ.js} +1 -1
- package/dist/{chunk-SY4XL6OQ.js → chunk-MBVTS76Q.js} +1 -1
- package/dist/{chunk-KDLSBQRP.js → chunk-TZTPGQGL.js} +1 -1
- package/dist/{chunk-FNDSHOV2.js → chunk-U5OTNDVQ.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/core-node-modules.cjs +108 -0
- package/dist/core-node-modules.d.cts +7 -0
- package/dist/core-node-modules.d.ts +7 -0
- package/dist/core-node-modules.js +8 -0
- package/dist/docs/development/components/components/15-prompt.md +5 -1
- package/dist/eventcatalog.cjs +124 -48
- package/dist/eventcatalog.js +26 -15
- 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/astro.config.mjs +27 -23
- package/eventcatalog/public/icons/languages/java.svg +1 -0
- package/eventcatalog/public/icons/payments/stripe.svg +1 -0
- package/eventcatalog/src/components/Badge.astro +10 -10
- package/eventcatalog/src/components/CopyAsMarkdown.tsx +154 -0
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +207 -44
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +0 -20
- package/eventcatalog/src/components/Grids/SystemGrid.tsx +185 -0
- package/eventcatalog/src/components/MDX/ADRTable/ADRTable.astro +99 -0
- package/eventcatalog/src/components/MDX/ADRTable/ADRTable.client.tsx +400 -0
- package/eventcatalog/src/components/MDX/ContextDiagram/ContextDiagramPortal.tsx +21 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +1 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +42 -6
- package/eventcatalog/src/components/MDX/Prompt/Prompt.astro +62 -9
- package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +8 -1
- package/eventcatalog/src/components/MDX/SystemContextMap/SystemContextMapPortal.tsx +22 -0
- package/eventcatalog/src/components/MDX/components.tsx +7 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -1
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +67 -37
- package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +47 -0
- package/eventcatalog/src/components/Tables/Discover/FilterComponents.tsx +10 -2
- package/eventcatalog/src/components/Tables/Discover/columns.tsx +115 -27
- package/eventcatalog/src/components/Tables/Discover/index.ts +7 -1
- package/eventcatalog/src/components/Tables/SystemResources/SystemResourcesTable.tsx +267 -0
- package/eventcatalog/src/content.config.ts +96 -8
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +4 -1
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +12 -13
- package/eventcatalog/src/enterprise/custom-documentation/utils/custom-docs.ts +6 -0
- package/eventcatalog/src/enterprise/feature.ts +3 -1
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +96 -140
- package/eventcatalog/src/layouts/VisualiserLayout.astro +66 -0
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +4 -2
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +2 -0
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +15 -15
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +1 -0
- package/eventcatalog/src/pages/discover/[type]/index.astro +47 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +15 -14
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +13 -14
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +11 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +81 -26
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +89 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +85 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +2 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version].mdx.ts +2 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +1 -0
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +24 -1
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +24 -1
- package/eventcatalog/src/pages/index.astro +30 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +3 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +94 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +51 -0
- package/eventcatalog/src/pages/visualiser/system-context-map/index.astro +41 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +91 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +51 -0
- package/eventcatalog/src/stores/sidebar-store/builders/adr.ts +3 -1
- package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +3 -1
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +127 -49
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +4 -2
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +2 -1
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +166 -0
- package/eventcatalog/src/stores/sidebar-store/state.ts +99 -6
- package/eventcatalog/src/types/index.ts +2 -0
- package/eventcatalog/src/utils/collection-colors.ts +6 -1
- package/eventcatalog/src/utils/collections/domains.ts +35 -0
- package/eventcatalog/src/utils/collections/icons.ts +4 -5
- package/eventcatalog/src/utils/collections/systems.ts +110 -0
- package/eventcatalog/src/utils/collections/teams.ts +15 -10
- package/eventcatalog/src/utils/collections/users.ts +7 -4
- package/eventcatalog/src/utils/collections/util.ts +2 -0
- package/eventcatalog/src/utils/icon-map.ts +20 -0
- package/eventcatalog/src/utils/icon.ts +11 -0
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -2
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +0 -170
- package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +400 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +208 -0
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +12 -0
- package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
- package/package.json +17 -14
- package/eventcatalog/src/pages/visualiser/context-map/index.astro +0 -30
|
@@ -143,6 +143,72 @@ const getColor = (collection: string) => {
|
|
|
143
143
|
document.addEventListener('astro:page-load', setupSidebarToggle);
|
|
144
144
|
</script>
|
|
145
145
|
|
|
146
|
+
<!--
|
|
147
|
+
Bridge Astro's view-transition router onto `window` so the standalone
|
|
148
|
+
visualiser package (which can't import `astro:*`) can trigger soft, animated
|
|
149
|
+
client navigations instead of hard page reloads. Used by node "drill-in"
|
|
150
|
+
clicks (e.g. a system node on the System Diagram -> that system's Map).
|
|
151
|
+
-->
|
|
152
|
+
<script>
|
|
153
|
+
import { navigate } from 'astro:transitions/client';
|
|
154
|
+
|
|
155
|
+
function bridgeNavigate() {
|
|
156
|
+
// @ts-ignore - intentional global bridge for the decoupled visualiser island
|
|
157
|
+
window.__ecNavigate = (url: string) => navigate(url);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bridgeNavigate();
|
|
161
|
+
document.addEventListener('astro:page-load', bridgeNavigate);
|
|
162
|
+
</script>
|
|
163
|
+
|
|
164
|
+
<style is:global>
|
|
165
|
+
/*
|
|
166
|
+
* "Drill into detail" transition for the visualiser graph container.
|
|
167
|
+
*
|
|
168
|
+
* Both the System Diagram and a system's Map render their graph inside
|
|
169
|
+
* a portal tagged with `transition:name="visualiser-graph"`. When navigating
|
|
170
|
+
* between them, Astro morphs that shared container: the outgoing graph fades
|
|
171
|
+
* and scales back, the incoming graph fades and scales up into place — reading
|
|
172
|
+
* as descending one level deeper rather than a flat cross-fade.
|
|
173
|
+
*/
|
|
174
|
+
@keyframes ec-visualiser-drill-out {
|
|
175
|
+
from {
|
|
176
|
+
opacity: 1;
|
|
177
|
+
transform: scale(1);
|
|
178
|
+
}
|
|
179
|
+
to {
|
|
180
|
+
opacity: 0;
|
|
181
|
+
transform: scale(1.04);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@keyframes ec-visualiser-drill-in {
|
|
186
|
+
from {
|
|
187
|
+
opacity: 0;
|
|
188
|
+
transform: scale(0.96);
|
|
189
|
+
}
|
|
190
|
+
to {
|
|
191
|
+
opacity: 1;
|
|
192
|
+
transform: scale(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
::view-transition-old(visualiser-graph) {
|
|
197
|
+
animation: ec-visualiser-drill-out 0.28s ease both;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
::view-transition-new(visualiser-graph) {
|
|
201
|
+
animation: ec-visualiser-drill-in 0.28s ease both;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@media (prefers-reduced-motion: reduce) {
|
|
205
|
+
::view-transition-old(visualiser-graph),
|
|
206
|
+
::view-transition-new(visualiser-graph) {
|
|
207
|
+
animation-duration: 0.01ms;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
</style>
|
|
211
|
+
|
|
146
212
|
<style>
|
|
147
213
|
.visualiser-full-bleed {
|
|
148
214
|
margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1);
|
|
@@ -4,8 +4,9 @@ import type { PageTypes } from '@types';
|
|
|
4
4
|
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
5
5
|
import { getDomains } from '@utils/collections/domains';
|
|
6
6
|
import { getServices } from '@utils/collections/services';
|
|
7
|
+
import { getSystems } from '@utils/collections/systems';
|
|
7
8
|
|
|
8
|
-
const architecturePageTypes: PageTypes[] = ['services', 'domains'];
|
|
9
|
+
const architecturePageTypes: PageTypes[] = ['services', 'domains', 'systems'];
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Documentation page class for all collection types with versioning
|
|
@@ -18,8 +19,9 @@ export class Page extends HybridPage {
|
|
|
18
19
|
|
|
19
20
|
const domains = await getDomains({ enrichServices: true });
|
|
20
21
|
const services = await getServices();
|
|
22
|
+
const systems = await getSystems();
|
|
21
23
|
|
|
22
|
-
const pageData = [services, domains];
|
|
24
|
+
const pageData = [services, domains, systems];
|
|
23
25
|
|
|
24
26
|
return pageData.flatMap((items, index) =>
|
|
25
27
|
items.map((item) => ({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import DomainGrid from '@components/Grids/DomainGrid';
|
|
3
|
+
import SystemGrid from '@components/Grids/SystemGrid';
|
|
3
4
|
import MessageGrid from '@components/Grids/MessageGrid';
|
|
4
5
|
import { getSpecificationsForService } from '@utils/collections/services';
|
|
5
6
|
|
|
@@ -25,6 +26,7 @@ const specifications = type === 'services' ? getSpecificationsForService(props)
|
|
|
25
26
|
<div class="flex docs-layout w-full">
|
|
26
27
|
<div class="w-full lg:mr-2 pr-24 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
27
28
|
{type === 'domains' && <DomainGrid domain={domain} client:load />}
|
|
29
|
+
{type === 'systems' && <SystemGrid system={props} client:load />}
|
|
28
30
|
{
|
|
29
31
|
(type === 'agents' || type === 'services') && (
|
|
30
32
|
<MessageGrid service={props} specifications={specifications} client:load />
|
|
@@ -35,7 +35,7 @@ const chatQuery = `Tell me about the "${props.data.name}" diagram (version ${pro
|
|
|
35
35
|
>
|
|
36
36
|
<main class="diagram-content w-full lg:mr-2 pr-24 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
37
37
|
<div class="border-b border-[rgb(var(--ec-page-border))] md:pb-2">
|
|
38
|
-
<div class="flex items-start
|
|
38
|
+
<div class="flex items-start gap-4">
|
|
39
39
|
<div class="min-w-0">
|
|
40
40
|
<h1 class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))] truncate">
|
|
41
41
|
{props.data.name}
|
|
@@ -45,20 +45,20 @@ const chatQuery = `Tell me about the "${props.data.name}" diagram (version ${pro
|
|
|
45
45
|
<p class="pt-2 text-base font-light text-[rgb(var(--ec-page-text-muted))]">{props.data.summary}</p>
|
|
46
46
|
)
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
<div class="pt-4">
|
|
49
|
+
<CopyAsMarkdown
|
|
50
|
+
client:only="react"
|
|
51
|
+
variant="toolbar"
|
|
52
|
+
schemas={[]}
|
|
53
|
+
chatQuery={chatQuery}
|
|
54
|
+
chatEnabled={chatEnabled}
|
|
55
|
+
editUrl=""
|
|
56
|
+
markdownDownloadEnabled={markdownDownloadEnabled}
|
|
57
|
+
rssFeedEnabled={false}
|
|
58
|
+
preferChatAsDefault={chatEnabled}
|
|
59
|
+
chatButtonText="Ask about this diagram"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
@@ -8,12 +8,20 @@ import { getServices } from '@utils/collections/services';
|
|
|
8
8
|
import { getQueries } from '@utils/collections/queries';
|
|
9
9
|
import { getContainers } from '@utils/collections/containers';
|
|
10
10
|
import { getDataProducts } from '@utils/collections/data-products';
|
|
11
|
+
import { getFlows } from '@utils/collections/flows';
|
|
11
12
|
import { getUsers } from '@utils/collections/users';
|
|
12
13
|
import { getTeams } from '@utils/collections/teams';
|
|
13
14
|
import { getChannels } from '@utils/collections/channels';
|
|
15
|
+
import { getSystems } from '@utils/collections/systems';
|
|
14
16
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
15
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
DiscoverTable,
|
|
19
|
+
type CollectionKindOption,
|
|
20
|
+
type DiscoverTableData,
|
|
21
|
+
type CollectionType,
|
|
22
|
+
} from '@components/Tables/Discover';
|
|
16
23
|
import config from '@config';
|
|
24
|
+
import { buildUrl } from '@utils/url-builder';
|
|
17
25
|
import { Page } from './_index.data';
|
|
18
26
|
|
|
19
27
|
export const prerender = Page.prerender;
|
|
@@ -28,8 +36,10 @@ const agents = await getAgents();
|
|
|
28
36
|
const adrs = await getAdrs();
|
|
29
37
|
const services = await getServices();
|
|
30
38
|
const domains = await getDomains({ getAllVersions: false });
|
|
39
|
+
const systems = await getSystems({ getAllVersions: false });
|
|
31
40
|
const containers = await getContainers();
|
|
32
41
|
const dataProducts = await getDataProducts();
|
|
42
|
+
const flows = await getFlows();
|
|
33
43
|
const channels = await getChannels();
|
|
34
44
|
const users = await getUsers();
|
|
35
45
|
const teams = await getTeams();
|
|
@@ -87,6 +97,16 @@ const typeConfig: Record<
|
|
|
87
97
|
{ id: 'isDeprecated', label: 'Is Deprecated' },
|
|
88
98
|
],
|
|
89
99
|
},
|
|
100
|
+
systems: {
|
|
101
|
+
label: 'Systems',
|
|
102
|
+
description: 'Explore the systems that group services and flows across your architecture, independently of domains.',
|
|
103
|
+
propertyOptions: [
|
|
104
|
+
{ id: 'hasServices', label: 'Has Services' },
|
|
105
|
+
{ id: 'hasFlows', label: 'Has Flows' },
|
|
106
|
+
{ id: 'hasOwners', label: 'Has Owners' },
|
|
107
|
+
{ id: 'isDeprecated', label: 'Is Deprecated' },
|
|
108
|
+
],
|
|
109
|
+
},
|
|
90
110
|
services: {
|
|
91
111
|
label: 'Services',
|
|
92
112
|
description: 'Browse the internal services in your catalog and inspect the capabilities they expose.',
|
|
@@ -161,6 +181,28 @@ const typeConfig: Record<
|
|
|
161
181
|
};
|
|
162
182
|
|
|
163
183
|
const currentTypeConfig = typeConfig[type] || typeConfig.events;
|
|
184
|
+
const internalServices = services.filter((service) => !service.data.externalSystem);
|
|
185
|
+
const externalSystems = services.filter((service) => service.data.externalSystem);
|
|
186
|
+
|
|
187
|
+
const collectionKinds = [
|
|
188
|
+
{ id: 'domains', label: typeConfig.domains.label, count: domains.length },
|
|
189
|
+
{ id: 'systems', label: typeConfig.systems.label, count: systems.length },
|
|
190
|
+
{ id: 'services', label: typeConfig.services.label, count: internalServices.length },
|
|
191
|
+
{ id: 'external-systems', label: typeConfig['external-systems'].label, count: externalSystems.length },
|
|
192
|
+
{ id: 'agents', label: typeConfig.agents.label, count: agents.length },
|
|
193
|
+
{ id: 'adrs', label: typeConfig.adrs.label, count: adrs.length },
|
|
194
|
+
{ id: 'data-products', label: typeConfig['data-products'].label, count: dataProducts.length },
|
|
195
|
+
{ id: 'containers', label: typeConfig.containers.label, count: containers.length },
|
|
196
|
+
{ id: 'events', label: typeConfig.events.label, count: events.length },
|
|
197
|
+
{ id: 'commands', label: typeConfig.commands.label, count: commands.length },
|
|
198
|
+
{ id: 'queries', label: typeConfig.queries.label, count: queries.length },
|
|
199
|
+
{ id: 'flows', label: typeConfig.flows.label, count: flows.length },
|
|
200
|
+
]
|
|
201
|
+
.filter((kind) => kind.count > 0)
|
|
202
|
+
.map((kind) => ({
|
|
203
|
+
...kind,
|
|
204
|
+
href: buildUrl(`/discover/${kind.id}`),
|
|
205
|
+
})) as CollectionKindOption[];
|
|
164
206
|
|
|
165
207
|
// External systems reuse the user's `services.tableConfiguration` so customisations apply to both tabs
|
|
166
208
|
const tableConfigurationKey = type === 'external-systems' ? 'services' : type;
|
|
@@ -269,7 +311,8 @@ const tableData = enrichedData.map((d: any) => ({
|
|
|
269
311
|
collection: d.collection,
|
|
270
312
|
owners: (d.data?.owners || []).map(mapOwner).filter(Boolean),
|
|
271
313
|
hasOwners: (d.data?.owners || []).length > 0,
|
|
272
|
-
hasServices: type === 'domains' ? (d.data?.services || []).length > 0 : false,
|
|
314
|
+
hasServices: type === 'domains' || type === 'systems' ? (d.data?.services || []).length > 0 : false,
|
|
315
|
+
hasFlows: type === 'systems' ? (d.data?.flows || []).length > 0 : false,
|
|
273
316
|
isSubdomain: type === 'domains' ? allSubdomainIds.has(d.data.id) : false,
|
|
274
317
|
// Service-specific properties
|
|
275
318
|
domains: isServiceOrAgentLike ? d.enrichedDomains : undefined,
|
|
@@ -304,6 +347,7 @@ const tableData = enrichedData.map((d: any) => ({
|
|
|
304
347
|
tools: d.data?.tools ?? [],
|
|
305
348
|
agents: d.data?.agents?.map(mapToItem) ?? [],
|
|
306
349
|
services: d.data?.services?.map(mapToItem) ?? [],
|
|
350
|
+
flows: d.data?.flows?.map(mapToItem) ?? [],
|
|
307
351
|
servicesThatWriteToContainer: d.data?.servicesThatWriteToContainer?.map(mapToItem) ?? [],
|
|
308
352
|
servicesThatReadFromContainer: d.data?.servicesThatReadFromContainer?.map(mapToItem) ?? [],
|
|
309
353
|
inputs: d.data?.inputs?.map(resolvePointer).filter(Boolean) ?? [],
|
|
@@ -395,6 +439,7 @@ const title = `${currentTypeConfig.label} (${data.length})`;
|
|
|
395
439
|
collectionType={type as CollectionType}
|
|
396
440
|
collectionLabel={currentTypeConfig.label}
|
|
397
441
|
collectionDescription={currentTypeConfig.description}
|
|
442
|
+
collectionKinds={collectionKinds}
|
|
398
443
|
domains={uniqueDomains}
|
|
399
444
|
owners={uniqueOwners as Array<{ id: string; name: string; type?: 'user' | 'team' }>}
|
|
400
445
|
producers={uniqueProducers}
|
package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro
CHANGED
|
@@ -54,22 +54,10 @@ const pagefindAttributes =
|
|
|
54
54
|
<div class="w-full lg:mr-2 pr-24 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
55
55
|
<div class="border-b border-[rgb(var(--ec-page-border))] md:pb-2">
|
|
56
56
|
<div>
|
|
57
|
-
<div class="flex
|
|
57
|
+
<div class="flex items-center">
|
|
58
58
|
<div class="flex items-center gap-2">
|
|
59
59
|
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{title}</h2>
|
|
60
60
|
</div>
|
|
61
|
-
<div class="hidden lg:block">
|
|
62
|
-
<CopyAsMarkdown
|
|
63
|
-
client:only="react"
|
|
64
|
-
schemas={[]}
|
|
65
|
-
chatQuery={chatQuery}
|
|
66
|
-
chatEnabled={chatEnabled}
|
|
67
|
-
editUrl=""
|
|
68
|
-
markdownDownloadEnabled={true}
|
|
69
|
-
rssFeedEnabled={false}
|
|
70
|
-
preferChatAsDefault={false}
|
|
71
|
-
/>
|
|
72
|
-
</div>
|
|
73
61
|
</div>
|
|
74
62
|
</div>
|
|
75
63
|
{
|
|
@@ -79,11 +67,24 @@ const pagefindAttributes =
|
|
|
79
67
|
}
|
|
80
68
|
{
|
|
81
69
|
badges.length > 0 && (
|
|
82
|
-
<div class="flex flex-wrap gap-
|
|
70
|
+
<div class="flex flex-wrap gap-1.5 py-3">
|
|
83
71
|
{badges.map((badge: any) => <Badge badge={badge} />)}
|
|
84
72
|
</div>
|
|
85
73
|
)
|
|
86
74
|
}
|
|
75
|
+
<div class="pt-4">
|
|
76
|
+
<CopyAsMarkdown
|
|
77
|
+
client:only="react"
|
|
78
|
+
variant="toolbar"
|
|
79
|
+
schemas={[]}
|
|
80
|
+
chatQuery={chatQuery}
|
|
81
|
+
chatEnabled={chatEnabled}
|
|
82
|
+
editUrl=""
|
|
83
|
+
markdownDownloadEnabled={true}
|
|
84
|
+
rssFeedEnabled={false}
|
|
85
|
+
preferChatAsDefault={false}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
87
88
|
</div>
|
|
88
89
|
<div data-pagefind-ignore>
|
|
89
90
|
{
|
|
@@ -54,29 +54,28 @@ const pagefindAttributes =
|
|
|
54
54
|
<div class="w-full lg:mr-2 pr-24 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
55
55
|
<div class="border-b border-[rgb(var(--ec-page-border))] md:pb-2">
|
|
56
56
|
<div class="flex flex-col gap-4">
|
|
57
|
-
<div class="flex
|
|
57
|
+
<div class="flex items-center gap-4">
|
|
58
58
|
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{title}</h2>
|
|
59
|
-
<div class="hidden lg:block shrink-0">
|
|
60
|
-
<CopyAsMarkdown
|
|
61
|
-
client:only="react"
|
|
62
|
-
schemas={[]}
|
|
63
|
-
chatQuery={chatQuery}
|
|
64
|
-
chatEnabled={chatEnabled}
|
|
65
|
-
editUrl=""
|
|
66
|
-
markdownDownloadEnabled={true}
|
|
67
|
-
rssFeedEnabled={false}
|
|
68
|
-
preferChatAsDefault={false}
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
59
|
</div>
|
|
72
60
|
{props.data.summary && <p class="text-base text-[rgb(var(--ec-page-text-muted))] font-light">{props.data.summary}</p>}
|
|
73
61
|
{
|
|
74
62
|
badges.length > 0 && (
|
|
75
|
-
<div class="flex flex-wrap gap-
|
|
63
|
+
<div class="flex flex-wrap gap-1.5 py-1">
|
|
76
64
|
{badges.map((badge: any) => <Badge badge={badge} />)}
|
|
77
65
|
</div>
|
|
78
66
|
)
|
|
79
67
|
}
|
|
68
|
+
<CopyAsMarkdown
|
|
69
|
+
client:only="react"
|
|
70
|
+
variant="toolbar"
|
|
71
|
+
schemas={[]}
|
|
72
|
+
chatQuery={chatQuery}
|
|
73
|
+
chatEnabled={chatEnabled}
|
|
74
|
+
editUrl=""
|
|
75
|
+
markdownDownloadEnabled={true}
|
|
76
|
+
rssFeedEnabled={false}
|
|
77
|
+
preferChatAsDefault={false}
|
|
78
|
+
/>
|
|
80
79
|
</div>
|
|
81
80
|
</div>
|
|
82
81
|
<div data-pagefind-ignore>
|
|
@@ -14,7 +14,17 @@ export class Page extends HybridPage {
|
|
|
14
14
|
|
|
15
15
|
const { pageDataLoader } = await import('@utils/page-loaders/page-data-loader');
|
|
16
16
|
|
|
17
|
-
const itemTypes: PageTypes[] = [
|
|
17
|
+
const itemTypes: PageTypes[] = [
|
|
18
|
+
'agents',
|
|
19
|
+
'events',
|
|
20
|
+
'commands',
|
|
21
|
+
'queries',
|
|
22
|
+
'services',
|
|
23
|
+
'domains',
|
|
24
|
+
'systems',
|
|
25
|
+
'flows',
|
|
26
|
+
'containers',
|
|
27
|
+
];
|
|
18
28
|
const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
|
|
19
29
|
|
|
20
30
|
return allItems.flatMap((items, index) =>
|
|
@@ -33,13 +33,14 @@ import {
|
|
|
33
33
|
Bot,
|
|
34
34
|
Box,
|
|
35
35
|
Boxes,
|
|
36
|
+
Group,
|
|
36
37
|
SquarePenIcon,
|
|
37
38
|
DatabaseIcon,
|
|
38
39
|
DatabaseZapIcon,
|
|
39
40
|
ShieldCheckIcon,
|
|
40
41
|
AlignLeft,
|
|
41
42
|
Package,
|
|
42
|
-
|
|
43
|
+
ClipboardList,
|
|
43
44
|
CalendarDays,
|
|
44
45
|
} from 'lucide-react';
|
|
45
46
|
|
|
@@ -148,7 +149,7 @@ const getBadge = () => {
|
|
|
148
149
|
|
|
149
150
|
if (isAdrPage) {
|
|
150
151
|
return [
|
|
151
|
-
createResourceBadge('Decision Record',
|
|
152
|
+
createResourceBadge('Decision Record', ClipboardList),
|
|
152
153
|
createResourceBadge(formatAdrDate(props.data.date), CalendarDays),
|
|
153
154
|
createAdrStatusBadge(props.data.status),
|
|
154
155
|
];
|
|
@@ -170,6 +171,10 @@ const getBadge = () => {
|
|
|
170
171
|
return [createResourceBadge('Domain', RectangleGroupIcon)];
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
if (props.collection === 'systems') {
|
|
175
|
+
return [createResourceBadge('System', Group)];
|
|
176
|
+
}
|
|
177
|
+
|
|
173
178
|
if (props.collection === 'flows') {
|
|
174
179
|
return [createResourceBadge('Flow', QueueListIcon)];
|
|
175
180
|
}
|
|
@@ -326,6 +331,33 @@ let nodeGraphs =
|
|
|
326
331
|
}) || [];
|
|
327
332
|
const flowEmbeds = getMDXComponentsByName(props.body || '', 'Flow') || [];
|
|
328
333
|
|
|
334
|
+
// Context Diagrams embedded via <ContextDiagram />. When no id is passed we assume
|
|
335
|
+
// the current page. Valid on system pages (renders the system's context) and domain
|
|
336
|
+
// pages (renders the context across the domain's systems). Each renders into its own
|
|
337
|
+
// portal so it doesn't collide with the page's default diagram.
|
|
338
|
+
//
|
|
339
|
+
// The underlying graph + visualiser link differ per page type:
|
|
340
|
+
// - systems → `systems-context`, links to /visualiser/systems/:id/:version/context
|
|
341
|
+
// - domains → `domains-systems-context`, links to /visualiser/domains/:id/:version/systems-context
|
|
342
|
+
const contextDiagramSupported = props.collection === 'systems' || props.collection === 'domains';
|
|
343
|
+
const contextDiagrams = contextDiagramSupported
|
|
344
|
+
? (getMDXComponentsByName(props.body || '', 'ContextDiagram') || []).map((diagram: any) => {
|
|
345
|
+
const id = diagram.id ?? props.data.id;
|
|
346
|
+
const version = diagram.version ?? props.data.version;
|
|
347
|
+
return {
|
|
348
|
+
id,
|
|
349
|
+
version,
|
|
350
|
+
search: parseMdxBooleanProp(diagram.search, true),
|
|
351
|
+
legend: parseMdxBooleanProp(diagram.legend, true),
|
|
352
|
+
graphCollection: props.collection === 'domains' ? 'domains-systems-context' : 'systems-context',
|
|
353
|
+
visualiserUrl:
|
|
354
|
+
props.collection === 'domains'
|
|
355
|
+
? buildUrl(`/visualiser/domains/${id}/${version}/systems-context`)
|
|
356
|
+
: buildUrl(`/visualiser/systems/${id}/${version}/context`),
|
|
357
|
+
};
|
|
358
|
+
})
|
|
359
|
+
: [];
|
|
360
|
+
|
|
329
361
|
// Get props for the node graph (when no id is passed, we assume its the current page)
|
|
330
362
|
const hasCurrentFlowEmbed =
|
|
331
363
|
props.collection === 'flows' &&
|
|
@@ -376,7 +408,7 @@ if (!isAdrPage && !hasCurrentFlowEmbed && !hasCurrentPageNodeGraph) {
|
|
|
376
408
|
<div class="w-full lg:mr-2 pr-24 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
377
409
|
<div class="border-b border-[rgb(var(--ec-page-border))] md:pb-6 pt-4">
|
|
378
410
|
<div>
|
|
379
|
-
<div
|
|
411
|
+
<div>
|
|
380
412
|
<div class="flex flex-col gap-4">
|
|
381
413
|
<span class="text-xs md:text-sm font-semibold text-[rgb(var(--ec-accent))] capitalize">
|
|
382
414
|
{friendlyCollectionName}
|
|
@@ -410,22 +442,32 @@ if (!isAdrPage && !hasCurrentFlowEmbed && !hasCurrentPageNodeGraph) {
|
|
|
410
442
|
</div>
|
|
411
443
|
</div>
|
|
412
444
|
</div>
|
|
413
|
-
<div class="hidden lg:block mb-2">
|
|
414
|
-
<CopyAsMarkdown
|
|
415
|
-
client:only="react"
|
|
416
|
-
schemas={schemasForResource}
|
|
417
|
-
chatQuery={generatePromptForResource(props)}
|
|
418
|
-
chatEnabled={isEventCatalogChatEnabled()}
|
|
419
|
-
markdownDownloadEnabled={isMarkdownDownloadEnabled()}
|
|
420
|
-
rssFeedEnabled={isRSSEnabled()}
|
|
421
|
-
editUrl={editUrl}
|
|
422
|
-
preferChatAsDefault={isEventCatalogChatEnabled()}
|
|
423
|
-
printUrl={printUrl}
|
|
424
|
-
/>
|
|
425
|
-
</div>
|
|
426
445
|
</div>
|
|
427
446
|
|
|
428
447
|
<h2 class="text-base pt-4 text-[rgb(var(--ec-page-text-muted))] font-light">{props.data.summary}</h2>
|
|
448
|
+
{
|
|
449
|
+
badges && (
|
|
450
|
+
<div class="flex flex-wrap gap-1.5 pt-4">
|
|
451
|
+
{badges.map((badge: any) => {
|
|
452
|
+
return <Badge badge={badge} />;
|
|
453
|
+
})}
|
|
454
|
+
</div>
|
|
455
|
+
)
|
|
456
|
+
}
|
|
457
|
+
<div class="pt-5">
|
|
458
|
+
<CopyAsMarkdown
|
|
459
|
+
client:only="react"
|
|
460
|
+
variant="toolbar"
|
|
461
|
+
schemas={schemasForResource}
|
|
462
|
+
chatQuery={generatePromptForResource(props)}
|
|
463
|
+
chatEnabled={isEventCatalogChatEnabled()}
|
|
464
|
+
markdownDownloadEnabled={isMarkdownDownloadEnabled()}
|
|
465
|
+
rssFeedEnabled={isRSSEnabled()}
|
|
466
|
+
editUrl={editUrl}
|
|
467
|
+
preferChatAsDefault={isEventCatalogChatEnabled()}
|
|
468
|
+
printUrl={printUrl}
|
|
469
|
+
/>
|
|
470
|
+
</div>
|
|
429
471
|
{
|
|
430
472
|
httpOperation && (
|
|
431
473
|
<div class="pt-4">
|
|
@@ -446,16 +488,6 @@ if (!isAdrPage && !hasCurrentFlowEmbed && !hasCurrentPageNodeGraph) {
|
|
|
446
488
|
</div>
|
|
447
489
|
)
|
|
448
490
|
}
|
|
449
|
-
{
|
|
450
|
-
badges && (
|
|
451
|
-
<div class="flex flex-wrap gap-3 pt-6 pb-2">
|
|
452
|
-
{badges.map((badge: any) => {
|
|
453
|
-
return <Badge badge={badge} />;
|
|
454
|
-
})}
|
|
455
|
-
</div>
|
|
456
|
-
)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
491
|
{
|
|
460
492
|
isSupersededAdr(props) && (
|
|
461
493
|
<Admonition type="warning" title="This architecture decision has been superseded">
|
|
@@ -593,6 +625,29 @@ if (!isAdrPage && !hasCurrentFlowEmbed && !hasCurrentPageNodeGraph) {
|
|
|
593
625
|
);
|
|
594
626
|
})
|
|
595
627
|
}
|
|
628
|
+
{
|
|
629
|
+
contextDiagrams.length > 0 &&
|
|
630
|
+
contextDiagrams.map((diagram: any) => (
|
|
631
|
+
<NodeGraph
|
|
632
|
+
id={diagram.id}
|
|
633
|
+
version={diagram.version}
|
|
634
|
+
collection={diagram.graphCollection}
|
|
635
|
+
mode="simple"
|
|
636
|
+
linksToVisualiser={true}
|
|
637
|
+
showSearch={diagram.search ?? true}
|
|
638
|
+
showLegend={diagram.legend ?? true}
|
|
639
|
+
portalId={`${diagram.id}-context-diagram-portal`}
|
|
640
|
+
href={
|
|
641
|
+
isVisualiserEnabled()
|
|
642
|
+
? {
|
|
643
|
+
label: 'Open Context Diagram',
|
|
644
|
+
url: diagram.visualiserUrl,
|
|
645
|
+
}
|
|
646
|
+
: undefined
|
|
647
|
+
}
|
|
648
|
+
/>
|
|
649
|
+
))
|
|
650
|
+
}
|
|
596
651
|
</div>
|
|
597
652
|
<Footer />
|
|
598
653
|
<!-- Add edit this page button with icon and text-->
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { isSSR } from '@utils/feature';
|
|
2
|
+
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
+
|
|
4
|
+
// The Resources page lists the top-level resources (services, flows, entities and
|
|
5
|
+
// data stores) attached to a single system or domain. It is only available for
|
|
6
|
+
// systems and domains — every other resource type 404s.
|
|
7
|
+
const SUPPORTED_TYPES = ['systems', 'domains'] as const;
|
|
8
|
+
type SupportedType = (typeof SUPPORTED_TYPES)[number];
|
|
9
|
+
|
|
10
|
+
const isSupportedType = (type: string): type is SupportedType => SUPPORTED_TYPES.includes(type as SupportedType);
|
|
11
|
+
|
|
12
|
+
const loadResourceOwner = async (type: SupportedType) => {
|
|
13
|
+
if (type === 'systems') {
|
|
14
|
+
const { getSystems } = await import('@utils/collections/systems');
|
|
15
|
+
return getSystems();
|
|
16
|
+
}
|
|
17
|
+
const { getDomains } = await import('@utils/collections/domains');
|
|
18
|
+
return getDomains();
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// A system/domain only gets a Resources page when it actually has resources attached.
|
|
22
|
+
// Mirrors what the page renders: services, flows, entities, data stores and (domains
|
|
23
|
+
// only) the domain's own messages.
|
|
24
|
+
const hasResources = (owner: any): boolean => {
|
|
25
|
+
const data = owner?.data ?? {};
|
|
26
|
+
return (
|
|
27
|
+
(data.services || []).length > 0 ||
|
|
28
|
+
(data.flows || []).length > 0 ||
|
|
29
|
+
(data.entities || []).length > 0 ||
|
|
30
|
+
(data.containers || []).length > 0 ||
|
|
31
|
+
(data.sends || []).length > 0 ||
|
|
32
|
+
(data.receives || []).length > 0
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export class Page extends HybridPage {
|
|
37
|
+
static get prerender(): boolean {
|
|
38
|
+
return !isSSR();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
|
|
42
|
+
if (isSSR()) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const owners = await Promise.all(SUPPORTED_TYPES.map((type) => loadResourceOwner(type)));
|
|
47
|
+
|
|
48
|
+
return SUPPORTED_TYPES.flatMap((type, index) =>
|
|
49
|
+
owners[index]
|
|
50
|
+
.filter((owner) => hasResources(owner))
|
|
51
|
+
.map((owner) => ({
|
|
52
|
+
params: {
|
|
53
|
+
type,
|
|
54
|
+
id: owner.data.id,
|
|
55
|
+
version: owner.data.version,
|
|
56
|
+
},
|
|
57
|
+
props: {
|
|
58
|
+
...owner,
|
|
59
|
+
},
|
|
60
|
+
}))
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected static async fetchData(params: any) {
|
|
65
|
+
const { type, id, version } = params;
|
|
66
|
+
|
|
67
|
+
if (!type || !id || !version || !isSupportedType(type)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const owners = await loadResourceOwner(type);
|
|
72
|
+
const owner = owners.find((o) => o.data.id === id && o.data.version === version);
|
|
73
|
+
|
|
74
|
+
if (!owner || !hasResources(owner)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
...owner,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected static createNotFoundResponse(): Response {
|
|
84
|
+
return new Response(null, {
|
|
85
|
+
status: 404,
|
|
86
|
+
statusText: 'Resources not found',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|