@eventcatalog/core 2.58.1 → 2.59.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-X4GKQ2ZE.js → chunk-F5WMB6Q5.js} +1 -1
- package/dist/{chunk-N7MEYFUO.js → chunk-SCDNNFXH.js} +1 -1
- package/dist/{chunk-F3YDLMMR.js → chunk-T3QXQPTB.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 +3 -3
- package/eventcatalog/astro.config.mjs +13 -7
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +67 -2
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +157 -41
- package/eventcatalog/src/components/Grids/ServiceGrid.tsx +78 -14
- package/eventcatalog/src/components/MDX/NodeGraph/Edges/MultilineEdgeLabel.tsx +52 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +13 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +4 -1
- package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Data.tsx +55 -16
- package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +180 -0
- package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +41 -0
- package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +1 -1
- package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +250 -59
- package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +3 -0
- package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +35 -1
- package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +2 -2
- package/eventcatalog/src/components/Tables/Table.tsx +22 -2
- package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +152 -0
- package/eventcatalog/src/components/Tables/columns/index.tsx +3 -0
- package/eventcatalog/src/content.config.ts +57 -1
- package/eventcatalog/src/layouts/DiscoverLayout.astro +11 -1
- package/eventcatalog/src/pages/architecture/architecture.astro +9 -1
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +1 -1
- package/eventcatalog/src/pages/discover/[type]/index.astro +11 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +11 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +50 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +2 -0
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -1
- package/eventcatalog/src/pages/docs/llm/llms-services.txt.ts +19 -1
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +3 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +80 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +52 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +9 -2
- package/eventcatalog/src/types/index.ts +20 -2
- package/eventcatalog/src/utils/collections/containers.ts +94 -0
- package/eventcatalog/src/utils/collections/icons.ts +3 -1
- package/eventcatalog/src/utils/collections/services.ts +15 -1
- package/eventcatalog/src/utils/collections/util.ts +4 -2
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +155 -0
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +188 -82
- package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
- package/package.json +3 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type EdgeProps, getBezierPath } from '@xyflow/react';
|
|
2
|
+
|
|
3
|
+
export default function MultilineEdgeLabel(props: EdgeProps) {
|
|
4
|
+
const {
|
|
5
|
+
id,
|
|
6
|
+
sourceX,
|
|
7
|
+
sourceY,
|
|
8
|
+
targetX,
|
|
9
|
+
targetY,
|
|
10
|
+
sourcePosition,
|
|
11
|
+
targetPosition,
|
|
12
|
+
label,
|
|
13
|
+
markerStart, // <-- forward these
|
|
14
|
+
markerEnd,
|
|
15
|
+
style,
|
|
16
|
+
selected,
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const [edgePath, labelX, labelY] = getBezierPath({
|
|
20
|
+
sourceX,
|
|
21
|
+
sourceY,
|
|
22
|
+
targetX,
|
|
23
|
+
targetY,
|
|
24
|
+
sourcePosition,
|
|
25
|
+
targetPosition,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const lines = String(label ?? '').split('\n');
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<path
|
|
33
|
+
id={id}
|
|
34
|
+
d={edgePath}
|
|
35
|
+
className={`react-flow__edge-path${selected ? ' selected' : ''}`}
|
|
36
|
+
markerStart={markerStart}
|
|
37
|
+
markerEnd={markerEnd}
|
|
38
|
+
style={style}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
{/* Optional: bigger hitbox for hover/selection */}
|
|
42
|
+
|
|
43
|
+
<text x={labelX} y={labelY} textAnchor="middle" dominantBaseline="middle" fontSize="10px" pointerEvents="none">
|
|
44
|
+
{lines.map((line, i) => (
|
|
45
|
+
<tspan key={i} x={labelX} dy={i === 0 ? 0 : '1.2em'} style={{ fontStyle: i === 0 ? 'normal' : 'italic' }}>
|
|
46
|
+
{line}
|
|
47
|
+
</tspan>
|
|
48
|
+
))}
|
|
49
|
+
</text>
|
|
50
|
+
</>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -16,6 +16,7 @@ import { getNodesAndEdges as getNodesAndEdgesForFlows } from '@utils/node-graphs
|
|
|
16
16
|
import { buildUrl } from '@utils/url-builder';
|
|
17
17
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
18
18
|
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
19
|
+
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
|
|
19
20
|
import config from '@config';
|
|
20
21
|
|
|
21
22
|
interface Props {
|
|
@@ -59,6 +60,7 @@ const getNodesAndEdgesFunctions = {
|
|
|
59
60
|
queries: getNodesAndEdgesForQueries,
|
|
60
61
|
domains: getNodesAndEdgesForDomain,
|
|
61
62
|
flows: getNodesAndEdgesForFlows,
|
|
63
|
+
containers: getNodesAndEdgesForContainer,
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
let links: { label: string; url: string }[] = [];
|
|
@@ -121,6 +123,17 @@ if (collection === 'domains-entities') {
|
|
|
121
123
|
nodes = fetchedNodes;
|
|
122
124
|
edges = fetchedEdges;
|
|
123
125
|
}
|
|
126
|
+
|
|
127
|
+
if (collection === 'services-containers') {
|
|
128
|
+
const { nodes: fetchedNodes, edges: fetchedEdges } = await getNodesAndEdgesForService({
|
|
129
|
+
id,
|
|
130
|
+
version,
|
|
131
|
+
renderMessages: false,
|
|
132
|
+
mode: 'full',
|
|
133
|
+
});
|
|
134
|
+
nodes = fetchedNodes;
|
|
135
|
+
edges = fetchedEdges;
|
|
136
|
+
}
|
|
124
137
|
---
|
|
125
138
|
|
|
126
139
|
<div>
|
|
@@ -32,6 +32,7 @@ import CommandNode from './Nodes/Command';
|
|
|
32
32
|
import ExternalSystemNode from './Nodes/ExternalSystem';
|
|
33
33
|
import DomainNode from './Nodes/Domain';
|
|
34
34
|
import AnimatedMessageEdge from './Edges/AnimatedMessageEdge';
|
|
35
|
+
import MultilineEdgeLabel from './Edges/MultilineEdgeLabel';
|
|
35
36
|
import FlowEdge from './Edges/FlowEdge';
|
|
36
37
|
import CustomNode from './Nodes/Custom';
|
|
37
38
|
import DataNode from './Nodes/Data';
|
|
@@ -124,6 +125,7 @@ const NodeGraphBuilder = ({
|
|
|
124
125
|
const edgeTypes = useMemo(
|
|
125
126
|
() => ({
|
|
126
127
|
animated: AnimatedMessageEdge,
|
|
128
|
+
multiline: MultilineEdgeLabel,
|
|
127
129
|
'flow-edge': FlowEdge,
|
|
128
130
|
}),
|
|
129
131
|
[]
|
|
@@ -241,7 +243,7 @@ const NodeGraphBuilder = ({
|
|
|
241
243
|
eds.map((edge) => ({
|
|
242
244
|
...edge,
|
|
243
245
|
animated: animateMessages,
|
|
244
|
-
type: edge.type === 'flow-edge'
|
|
246
|
+
type: edge.type === 'flow-edge' || edge.type === 'multiline' ? edge.type : animateMessages ? 'animated' : 'default',
|
|
245
247
|
data: { ...edge.data, animateMessages, animated: animateMessages },
|
|
246
248
|
}))
|
|
247
249
|
);
|
|
@@ -423,6 +425,7 @@ const NodeGraphBuilder = ({
|
|
|
423
425
|
externalSystem: 'bg-pink-600',
|
|
424
426
|
actor: 'bg-yellow-500',
|
|
425
427
|
step: 'bg-gray-700',
|
|
428
|
+
data: 'bg-blue-600',
|
|
426
429
|
};
|
|
427
430
|
|
|
428
431
|
let legendForDomains: { [key: string]: { count: number; colorClass: string; groupId: string } } = {};
|
|
@@ -1,24 +1,63 @@
|
|
|
1
1
|
import { Handle, Position } from '@xyflow/react';
|
|
2
2
|
|
|
3
3
|
import { nodeComponents, type DataNode } from '@eventcatalog/visualizer';
|
|
4
|
+
import * as ContextMenu from '@radix-ui/react-context-menu';
|
|
5
|
+
import { buildUrl } from '@utils/url-builder';
|
|
4
6
|
const DataComponent = nodeComponents.data;
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
interface Data {
|
|
9
|
+
data: {
|
|
10
|
+
data: {
|
|
11
|
+
id: string;
|
|
12
|
+
version: string;
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function DataNode(props: Data) {
|
|
19
|
+
const { id, version, name } = props.data.data;
|
|
20
|
+
|
|
7
21
|
return (
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
<ContextMenu.Root>
|
|
23
|
+
<ContextMenu.Trigger>
|
|
24
|
+
<div className="relative">
|
|
25
|
+
<Handle
|
|
26
|
+
type="target"
|
|
27
|
+
position={Position.Left}
|
|
28
|
+
style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
|
|
29
|
+
className="bg-gray-500"
|
|
30
|
+
/>
|
|
31
|
+
<Handle
|
|
32
|
+
type="source"
|
|
33
|
+
position={Position.Right}
|
|
34
|
+
style={{ width: 10, height: 10, background: 'blue', zIndex: 10 }}
|
|
35
|
+
className="bg-gray-500"
|
|
36
|
+
/>
|
|
37
|
+
<DataComponent {...(props as any)} />
|
|
38
|
+
</div>
|
|
39
|
+
</ContextMenu.Trigger>
|
|
40
|
+
<ContextMenu.Portal>
|
|
41
|
+
<ContextMenu.Content className="min-w-[220px] bg-white rounded-md p-1 shadow-md border border-gray-200">
|
|
42
|
+
<ContextMenu.Item
|
|
43
|
+
asChild
|
|
44
|
+
className="text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center"
|
|
45
|
+
>
|
|
46
|
+
<a href={buildUrl(`/docs/containers/${id}/${version}`)}>Read documentation</a>
|
|
47
|
+
</ContextMenu.Item>
|
|
48
|
+
<ContextMenu.Separator className="h-[1px] bg-gray-200 m-1" />
|
|
49
|
+
<ContextMenu.Item asChild>
|
|
50
|
+
<a
|
|
51
|
+
href={buildUrl(`/docs/containers/${id}/${version}/changelog`)}
|
|
52
|
+
className="text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center"
|
|
53
|
+
target="_blank"
|
|
54
|
+
rel="noopener noreferrer"
|
|
55
|
+
>
|
|
56
|
+
Read changelog
|
|
57
|
+
</a>
|
|
58
|
+
</ContextMenu.Item>
|
|
59
|
+
</ContextMenu.Content>
|
|
60
|
+
</ContextMenu.Portal>
|
|
61
|
+
</ContextMenu.Root>
|
|
23
62
|
);
|
|
24
63
|
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { CollectionEntry } from 'astro:content';
|
|
3
|
+
import PillListFlat from '@components/Lists/PillListFlat';
|
|
4
|
+
import OwnersList from '@components/Lists/OwnersList';
|
|
5
|
+
import VersionList from '@components/Lists/VersionList.astro';
|
|
6
|
+
import { buildUrl } from '@utils/url-builder';
|
|
7
|
+
import { ScrollText, Workflow, RssIcon } from 'lucide-react';
|
|
8
|
+
import RepositoryList from '@components/Lists/RepositoryList.astro';
|
|
9
|
+
import { getOwner } from '@utils/collections/owners';
|
|
10
|
+
import CustomSideBarSectionList from '@components/Lists/CustomSideBarSectionList.astro';
|
|
11
|
+
import { isChangelogEnabled } from '@utils/feature';
|
|
12
|
+
import config from '@config';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
container: CollectionEntry<'containers'>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { container } = Astro.props;
|
|
19
|
+
|
|
20
|
+
const servicesThatWriteToContainer = (container.data.servicesThatWriteToContainer as CollectionEntry<'services'>[]) || [];
|
|
21
|
+
const servicesThatReadFromContainer = (container.data.servicesThatReadFromContainer as CollectionEntry<'services'>[]) || [];
|
|
22
|
+
const ownersRaw = container.data?.owners || [];
|
|
23
|
+
|
|
24
|
+
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
|
|
25
|
+
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
26
|
+
const resourceGroups = container.data?.resourceGroups || [];
|
|
27
|
+
const attachments = container.data.attachments || [];
|
|
28
|
+
|
|
29
|
+
const attachmentsList = attachments.map((a) => {
|
|
30
|
+
const attachmentIsURL = typeof a === 'string';
|
|
31
|
+
return {
|
|
32
|
+
label: attachmentIsURL ? a : (a.title ?? a.url),
|
|
33
|
+
href: attachmentIsURL ? a : a.url,
|
|
34
|
+
icon: attachmentIsURL ? 'ExternalLinkIcon' : (a.icon ?? 'ExternalLinkIcon'),
|
|
35
|
+
target: '_blank' as const,
|
|
36
|
+
subgroup: attachmentIsURL ? undefined : (a.type ?? ''),
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const writesToList = servicesThatWriteToContainer?.map((p) => ({
|
|
41
|
+
label: p.data.name,
|
|
42
|
+
tag: `v${p.data.version}`,
|
|
43
|
+
collection: p.collection,
|
|
44
|
+
href: buildUrl(`/docs/services/${p.data.id}/${p.data.version}`),
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const readsFromList = servicesThatReadFromContainer?.map((p) => ({
|
|
48
|
+
label: p.data.name,
|
|
49
|
+
tag: `v${p.data.version}`,
|
|
50
|
+
collection: p.collection,
|
|
51
|
+
href: buildUrl(`/docs/services/${p.data.id}/${p.data.version}`),
|
|
52
|
+
}));
|
|
53
|
+
|
|
54
|
+
const ownersList = filteredOwners.map((o) => ({
|
|
55
|
+
label: o.data.name,
|
|
56
|
+
type: o.collection,
|
|
57
|
+
badge: o.collection === 'users' ? o.data.role : 'Team',
|
|
58
|
+
avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
|
|
59
|
+
href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
const shouldRenderSideBarSection = (section: string) => {
|
|
63
|
+
if (!container.data.detailsPanel) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
return container.data.detailsPanel[section]?.visible ?? true;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const isRSSEnabled = config.rss?.enabled;
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
<aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
|
|
74
|
+
<div class="">
|
|
75
|
+
{
|
|
76
|
+
resourceGroups
|
|
77
|
+
.filter((section) => section.items.length > 0 && section.sidebar)
|
|
78
|
+
.map((section) => <CustomSideBarSectionList section={section} />)
|
|
79
|
+
}
|
|
80
|
+
{
|
|
81
|
+
writesToList.length > 0 && shouldRenderSideBarSection('services') && (
|
|
82
|
+
<PillListFlat
|
|
83
|
+
color="pink"
|
|
84
|
+
title={`Services (writes) (${writesToList.length})`}
|
|
85
|
+
pills={writesToList}
|
|
86
|
+
emptyMessage={'No services are using this resource.'}
|
|
87
|
+
client:load
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
{
|
|
92
|
+
readsFromList.length > 0 && shouldRenderSideBarSection('services') && (
|
|
93
|
+
<PillListFlat
|
|
94
|
+
color="pink"
|
|
95
|
+
title={`Services (reads) (${readsFromList.length})`}
|
|
96
|
+
pills={readsFromList}
|
|
97
|
+
emptyMessage={'No services are using this resource.'}
|
|
98
|
+
client:load
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
{
|
|
104
|
+
container.data.versions && shouldRenderSideBarSection('versions') && (
|
|
105
|
+
<VersionList
|
|
106
|
+
title={`Versions (${container.data.versions?.length})`}
|
|
107
|
+
versions={container.data.versions}
|
|
108
|
+
collectionItem={container}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
container.data.attachments && shouldRenderSideBarSection('attachments') && (
|
|
115
|
+
<PillListFlat
|
|
116
|
+
title={`Attachments (${attachmentsList.length})`}
|
|
117
|
+
pills={attachmentsList}
|
|
118
|
+
emptyMessage={`This resource does not have any attachments.`}
|
|
119
|
+
color="pink"
|
|
120
|
+
client:load
|
|
121
|
+
/>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
{
|
|
126
|
+
ownersList.length > 0 && shouldRenderSideBarSection('owners') && (
|
|
127
|
+
<OwnersList
|
|
128
|
+
title={`Owners (${ownersList.length})`}
|
|
129
|
+
owners={ownersList}
|
|
130
|
+
emptyMessage={`This resource does not have any documented owners.`}
|
|
131
|
+
client:load
|
|
132
|
+
/>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
{
|
|
137
|
+
container.data.repository && shouldRenderSideBarSection('repository') && (
|
|
138
|
+
<RepositoryList repository={container.data.repository?.url} language={container.data.repository?.language} />
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
{
|
|
143
|
+
isRSSEnabled && (
|
|
144
|
+
<div class="mx-auto pb-8 w-full max-w-lg divide-y divide-white/5 rounded-xl bg-white/5">
|
|
145
|
+
<span class="text-sm text-black font-semibold group-data-[hover]:text-black/80 capitalize">Container RSS Feed</span>
|
|
146
|
+
<ul role="list" class="space-y-2 mt-2">
|
|
147
|
+
<li class="has-tooltip rounded-md text-gray-600 group px-1 w-full hover:bg-gradient-to-l hover:from-purple-500 hover:to-purple-700 hover:text-white hover:font-normal ">
|
|
148
|
+
<a class={`flex items-center space-x-2`} target="_blank" href={buildUrl(`/rss/${container.collection}/rss.xml`)}>
|
|
149
|
+
<RssIcon className="h-4 w-4 text-gray-800 group-hover:text-white" strokeWidth={1} />
|
|
150
|
+
<span class="font-light text-sm truncate">RSS Feed</span>
|
|
151
|
+
</a>
|
|
152
|
+
</li>
|
|
153
|
+
</ul>
|
|
154
|
+
</div>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
<div class="space-y-2">
|
|
159
|
+
<a
|
|
160
|
+
href={buildUrl(`/visualiser/${container.collection}/${container.data.id}/${container.data.version}`)}
|
|
161
|
+
class="flex items-center justify-center space-x-2 text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
|
|
162
|
+
>
|
|
163
|
+
<Workflow strokeWidth={2} size={16} />
|
|
164
|
+
<span class="block">View in visualiser</span>
|
|
165
|
+
</a>
|
|
166
|
+
|
|
167
|
+
{
|
|
168
|
+
isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
|
|
169
|
+
<a
|
|
170
|
+
href={buildUrl(`/docs/${container.collection}/${container.data.id}/${container.data.latestVersion}/changelog`)}
|
|
171
|
+
class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
|
|
172
|
+
>
|
|
173
|
+
<ScrollText strokeWidth={2} size={16} />
|
|
174
|
+
<span class="block">Read changelog</span>
|
|
175
|
+
</a>
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</aside>
|
|
@@ -24,6 +24,11 @@ const sends = (service.data.sends as CollectionEntry<'events'>[]) || [];
|
|
|
24
24
|
// @ts-ignore
|
|
25
25
|
const receives = (service.data.receives as CollectionEntry<'events'>[]) || [];
|
|
26
26
|
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
const writesTo = (service.data.writesTo as CollectionEntry<'containers'>[]) || [];
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
const readsFrom = (service.data.readsFrom as CollectionEntry<'containers'>[]) || [];
|
|
31
|
+
|
|
27
32
|
// @ts-ignore
|
|
28
33
|
const entities = (service.data.entities as CollectionEntry<'entities'>[]) || [];
|
|
29
34
|
|
|
@@ -70,6 +75,24 @@ const receivesList = receives
|
|
|
70
75
|
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
71
76
|
}));
|
|
72
77
|
|
|
78
|
+
const writesToList = writesTo.map((p) => ({
|
|
79
|
+
label: p.data.name,
|
|
80
|
+
badge: p.collection,
|
|
81
|
+
color: p.collection === 'containers' ? 'green' : 'blue',
|
|
82
|
+
collection: p.collection,
|
|
83
|
+
tag: `v${p.data.version}`,
|
|
84
|
+
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
const readsFromList = readsFrom.map((p) => ({
|
|
88
|
+
label: p.data.name,
|
|
89
|
+
badge: p.collection,
|
|
90
|
+
color: p.collection === 'containers' ? 'green' : 'blue',
|
|
91
|
+
collection: p.collection,
|
|
92
|
+
tag: `v${p.data.version}`,
|
|
93
|
+
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
94
|
+
}));
|
|
95
|
+
|
|
73
96
|
const ownersList = filteredOwners.map((o) => ({
|
|
74
97
|
label: o.data.name,
|
|
75
98
|
type: o.collection,
|
|
@@ -148,6 +171,24 @@ const shouldRenderSideBarSection = (section: string) => {
|
|
|
148
171
|
</>
|
|
149
172
|
)
|
|
150
173
|
}
|
|
174
|
+
<>
|
|
175
|
+
<PillListFlat
|
|
176
|
+
title={`Writes to (${writesToList.length})`}
|
|
177
|
+
pills={writesToList}
|
|
178
|
+
emptyMessage={`This service does not receive any messages.`}
|
|
179
|
+
color="orange"
|
|
180
|
+
client:load
|
|
181
|
+
/>
|
|
182
|
+
</>
|
|
183
|
+
<>
|
|
184
|
+
<PillListFlat
|
|
185
|
+
title={`Reads from (${readsFromList.length})`}
|
|
186
|
+
pills={readsFromList}
|
|
187
|
+
emptyMessage={`This service does not read from any containers.`}
|
|
188
|
+
color="orange"
|
|
189
|
+
client:load
|
|
190
|
+
/>
|
|
191
|
+
</>
|
|
151
192
|
{
|
|
152
193
|
service.data.versions && shouldRenderSideBarSection('versions') && (
|
|
153
194
|
<VersionList versions={service.data.versions} collectionItem={service} />
|
|
@@ -64,7 +64,7 @@ const MessageList: React.FC<MessageListProps> = ({ messages, decodedCurrentPath,
|
|
|
64
64
|
<span className="text-xs text-gray-400">{message.data.draft ? ' (DRAFT)' : ''}</span>
|
|
65
65
|
</span>
|
|
66
66
|
<span
|
|
67
|
-
className={`ml-2 text-[10px] flex items-center gap-1 font-medium px-2 uppercase py-0.5 rounded ${getMessageColorByLabelOrCollection(message.collection, message.data?.sidebar?.badge)}`}
|
|
67
|
+
className={`ml-2 text-[10px] flex items-center gap-1 font-medium px-2 uppercase py-0.5 rounded ${getMessageColorByLabelOrCollection(message.collection, message.data?.sidebar?.badge)} ${message.data?.sidebar?.backgroundColor}`}
|
|
68
68
|
>
|
|
69
69
|
{message.data?.sidebar?.badge || getMessageCollectionName(message.collection, message)}
|
|
70
70
|
</span>
|