@eventcatalog/core 2.65.0 → 3.0.0-beta.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.
Files changed (130) hide show
  1. package/README.md +1 -26
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +1 -1
  5. package/dist/analytics/log-build.js +3 -3
  6. package/dist/{chunk-NK6OYMRD.js → chunk-JB4YT5JY.js} +1 -1
  7. package/dist/{chunk-BMDTX5IN.js → chunk-TQ4HZREX.js} +1 -1
  8. package/dist/{chunk-IJRFYF4B.js → chunk-X4W4YC3U.js} +1 -1
  9. package/dist/constants.cjs +1 -1
  10. package/dist/constants.js +1 -1
  11. package/dist/eventcatalog.cjs +1 -21
  12. package/dist/eventcatalog.config.d.cts +10 -0
  13. package/dist/eventcatalog.config.d.ts +10 -0
  14. package/dist/eventcatalog.js +3 -20
  15. package/eventcatalog/src/components/CopyAsMarkdown.tsx +19 -1
  16. package/eventcatalog/src/components/FavoriteButton.tsx +54 -0
  17. package/eventcatalog/src/components/Grids/DomainGrid.tsx +386 -362
  18. package/eventcatalog/src/components/Grids/MessageGrid.tsx +166 -518
  19. package/eventcatalog/src/components/Header.astro +48 -23
  20. package/eventcatalog/src/components/Lists/VersionList.astro +2 -2
  21. package/eventcatalog/src/components/MDX/Design/Design.astro +4 -1
  22. package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -1
  23. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +3 -3
  24. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +8 -2
  25. package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +37 -0
  26. package/eventcatalog/src/components/Search/Search.astro +48 -28
  27. package/eventcatalog/src/components/Search/SearchModal.tsx +393 -702
  28. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +298 -0
  29. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/container.ts +66 -0
  30. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/domain.ts +101 -0
  31. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/flow.ts +29 -0
  32. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/message.ts +84 -0
  33. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/service.ts +147 -0
  34. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/shared.ts +146 -0
  35. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +1073 -0
  36. package/eventcatalog/src/components/SideNav/NestedSideBar/sidebar-builder.ts +365 -0
  37. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +90 -0
  38. package/eventcatalog/src/components/SideNav/SideNav.astro +18 -28
  39. package/eventcatalog/src/content.config.ts +2 -0
  40. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +10 -4
  41. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +3 -3
  42. package/eventcatalog/src/layouts/DirectoryLayout.astro +2 -2
  43. package/eventcatalog/src/layouts/DiscoverLayout.astro +3 -3
  44. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +85 -63
  45. package/eventcatalog/src/layouts/VisualiserLayout.astro +3 -3
  46. package/eventcatalog/src/pages/_index.astro +530 -110
  47. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +64 -0
  48. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +29 -0
  49. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +4 -4
  50. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -4
  51. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +3 -3
  52. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -5
  53. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +362 -190
  54. package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +1 -1
  55. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +4 -4
  56. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +1 -4
  57. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +3 -27
  58. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +2 -2
  59. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +2 -2
  60. package/eventcatalog/src/pages/index.astro +14 -5
  61. package/eventcatalog/src/pages/nav-index.json.ts +30 -0
  62. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +77 -0
  63. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +90 -0
  64. package/eventcatalog/src/pages/schemas/{index.astro → explorer/index.astro} +3 -3
  65. package/eventcatalog/src/pages/studio.astro +3 -3
  66. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +4 -3
  67. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +2 -2
  68. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +4 -3
  69. package/eventcatalog/src/stores/favorites-store.ts +83 -0
  70. package/eventcatalog/src/stores/sidebar-store.ts +8 -0
  71. package/eventcatalog/src/utils/collections/changelogs.ts +7 -4
  72. package/eventcatalog/src/utils/{channels.ts → collections/channels.ts} +81 -31
  73. package/eventcatalog/src/utils/collections/commands.ts +134 -0
  74. package/eventcatalog/src/utils/collections/containers.ts +44 -33
  75. package/eventcatalog/src/utils/collections/domains.ts +204 -62
  76. package/eventcatalog/src/utils/{entities.ts → collections/entities.ts} +44 -24
  77. package/eventcatalog/src/utils/collections/events.ts +136 -0
  78. package/eventcatalog/src/utils/collections/flows.ts +59 -25
  79. package/eventcatalog/src/utils/{messages.ts → collections/messages.ts} +13 -4
  80. package/eventcatalog/src/utils/{queries.ts → collections/queries.ts} +49 -28
  81. package/eventcatalog/src/utils/collections/services.ts +100 -68
  82. package/eventcatalog/src/utils/collections/teams.ts +94 -0
  83. package/eventcatalog/src/utils/collections/users.ts +122 -0
  84. package/eventcatalog/src/utils/collections/util.ts +57 -1
  85. package/eventcatalog/src/utils/feature.ts +3 -1
  86. package/eventcatalog/src/utils/{collections/file-diffs.ts → file-diffs.ts} +1 -1
  87. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +2 -0
  88. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +16 -6
  89. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +14 -10
  90. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +36 -64
  91. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +23 -19
  92. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +36 -49
  93. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +22 -18
  94. package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +4 -4
  95. package/eventcatalog/tailwind.config.mjs +14 -0
  96. package/eventcatalog/tsconfig.json +2 -1
  97. package/package.json +7 -4
  98. package/eventcatalog/public/logo_old.png +0 -0
  99. package/eventcatalog/src/components/DiscoverInsight.astro +0 -61
  100. package/eventcatalog/src/components/Grids/ServiceGrid.tsx +0 -534
  101. package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +0 -55
  102. package/eventcatalog/src/components/Lists/ProtocolList.tsx +0 -74
  103. package/eventcatalog/src/components/Lists/RepositoryList.astro +0 -37
  104. package/eventcatalog/src/components/Lists/SpecificationsList.astro +0 -67
  105. package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +0 -204
  106. package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +0 -180
  107. package/eventcatalog/src/components/SideBars/DomainSideBar.astro +0 -273
  108. package/eventcatalog/src/components/SideBars/EntitySideBar.astro +0 -139
  109. package/eventcatalog/src/components/SideBars/FlowSideBar.astro +0 -128
  110. package/eventcatalog/src/components/SideBars/MessageSideBar.astro +0 -248
  111. package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +0 -294
  112. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/CollapsibleGroup.tsx +0 -46
  113. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +0 -78
  114. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/SpecificationList.tsx +0 -83
  115. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +0 -1250
  116. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +0 -91
  117. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +0 -201
  118. package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +0 -190
  119. package/eventcatalog/src/components/SideNav/TreeView/index.tsx +0 -94
  120. package/eventcatalog/src/components/TreeView/index.tsx +0 -328
  121. package/eventcatalog/src/components/TreeView/styles.module.css +0 -264
  122. package/eventcatalog/src/components/TreeView/useSlots.ts +0 -95
  123. package/eventcatalog/src/pages/architecture/[type]/index.astro +0 -14
  124. package/eventcatalog/src/pages/architecture/architecture.astro +0 -101
  125. package/eventcatalog/src/pages/architecture/docs/[type]/index.astro +0 -14
  126. package/eventcatalog/src/utils/commands.ts +0 -112
  127. package/eventcatalog/src/utils/events.ts +0 -108
  128. package/eventcatalog/src/utils/generators/index.ts +0 -10
  129. package/eventcatalog/src/utils/teams.ts +0 -72
  130. package/eventcatalog/src/utils/users.ts +0 -72
@@ -1,248 +0,0 @@
1
- ---
2
- import type { CollectionEntry } from 'astro:content';
3
- import PillListFlat from '@components/Lists/PillListFlat';
4
- import OwnersList from '@components/Lists/OwnersList';
5
- import type { CollectionMessageTypes } from '@types';
6
- import * as path from 'path';
7
- import VersionList from '@components/Lists/VersionList.astro';
8
- import { buildUrl } from '@utils/url-builder';
9
- import { FileDownIcon, ScrollText, Workflow, RssIcon } from 'lucide-react';
10
- import RepositoryList from '@components/Lists/RepositoryList.astro';
11
- import { getOwner } from '@utils/collections/owners';
12
- import CustomSideBarSectionList from '@components/Lists/CustomSideBarSectionList.astro';
13
- import config from '@config';
14
- import { getSchemaFormatFromURL } from '@utils/collections/schemas';
15
- import { isChangelogEnabled } from '@utils/feature';
16
- interface Props {
17
- message: CollectionEntry<CollectionMessageTypes>;
18
- }
19
-
20
- const { message } = Astro.props;
21
-
22
- const producers = (message.data.producers as CollectionEntry<'services'>[]) || [];
23
- const consumers = (message.data.consumers as CollectionEntry<'services'>[]) || [];
24
- const channels = (message.data.messageChannels as CollectionEntry<'channels'>[]) || [];
25
-
26
- const ownersRaw = message.data?.owners || [];
27
- const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
28
- const filteredOwners = owners.filter((o) => o !== undefined);
29
-
30
- const resourceGroups = message.data?.resourceGroups || [];
31
-
32
- const attachments = message.data.attachments || [];
33
-
34
- const attachmentsList = attachments.map((a) => {
35
- const attachmentIsURL = typeof a === 'string';
36
- return {
37
- label: attachmentIsURL ? a : (a.title ?? a.url),
38
- href: attachmentIsURL ? a : a.url,
39
- icon: attachmentIsURL ? 'ExternalLinkIcon' : (a.icon ?? 'ExternalLinkIcon'),
40
- target: '_blank' as const,
41
- subgroup: attachmentIsURL ? undefined : (a.type ?? ''),
42
- };
43
- });
44
-
45
- const producerList = producers.map((p) => ({
46
- label: `${p.data.name}`,
47
- tag: `v${p.data.version}`,
48
- collection: p.collection,
49
- href: buildUrl(`/docs/services/${p.data.id}/${p.data.version}`),
50
- }));
51
-
52
- const consumerList = consumers.map((p) => ({
53
- label: `${p.data.name}`,
54
- tag: `v${p.data.version}`,
55
- collection: p.collection,
56
- href: buildUrl(`/docs/services/${p.data.id}/${p.data.version}`),
57
- }));
58
-
59
- const ownersList = filteredOwners.map((o) => ({
60
- label: o.data.name,
61
- type: o.collection,
62
- badge: o.collection === 'users' ? o.data.role : 'Team',
63
- avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
64
- href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
65
- }));
66
-
67
- const channelList = channels.map((c) => ({
68
- label: `${c.data.name}`,
69
- tag: `v${c.data.version}`,
70
- collection: c.collection,
71
- href: buildUrl(`/docs/channels/${c.data.id}/${c.data.version}`),
72
- }));
73
-
74
- const getType = (type: string) => {
75
- switch (type) {
76
- case 'queries':
77
- return 'Query';
78
- default:
79
- return message.collection.slice(0, -1);
80
- }
81
- };
82
-
83
- const getProducerEmptyMessage = (type: string) => {
84
- const value = type.toLowerCase();
85
- switch (value) {
86
- case 'query':
87
- case 'command':
88
- return `This ${value} does not get invoked by any services.`;
89
- default:
90
- return `This ${value} does not get produced by any services.`;
91
- }
92
- };
93
-
94
- const getConsumerEmptyMessage = (type: string) => {
95
- const value = type.toLowerCase();
96
- switch (value) {
97
- case 'query':
98
- case 'command':
99
- return `This ${value} does not invoke any service.`;
100
- default:
101
- return `This ${value} does not get consumed by any services.`;
102
- }
103
- };
104
-
105
- const type = getType(message.collection);
106
-
107
- const isRSSEnabled = config.rss?.enabled;
108
-
109
- // @ts-ignore
110
- const publicPath = message?.catalog?.publicPath;
111
-
112
- const schemaFilePath = message?.data?.schemaPath;
113
- const schemaURL = path.join(publicPath, schemaFilePath || '');
114
-
115
- const shouldRenderSideBarSection = (section: string) => {
116
- if (!message.data.detailsPanel) {
117
- return true;
118
- }
119
- // @ts-ignore
120
- return message.data.detailsPanel[section]?.visible ?? true;
121
- };
122
- ---
123
-
124
- <aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
125
- <div class="">
126
- {
127
- resourceGroups
128
- .filter((section) => section.items.length > 0 && section.sidebar)
129
- .map((section) => <CustomSideBarSectionList section={section} />)
130
- }
131
- {
132
- producerList.length > 0 && shouldRenderSideBarSection('producers') && (
133
- <PillListFlat
134
- color="pink"
135
- title={`Producers (${producerList.length})`}
136
- pills={producerList}
137
- emptyMessage={getProducerEmptyMessage(type)}
138
- client:load
139
- />
140
- )
141
- }
142
- {
143
- consumerList.length > 0 && shouldRenderSideBarSection('consumers') && (
144
- <PillListFlat
145
- color="pink"
146
- title={`Consumers (${consumerList.length})`}
147
- pills={consumerList}
148
- emptyMessage={getConsumerEmptyMessage(type)}
149
- client:load
150
- />
151
- )
152
- }
153
- {
154
- channelList.length > 0 && shouldRenderSideBarSection('channels') && (
155
- <PillListFlat color="pink" title={`Channels (${channelList.length})`} pills={channelList} client:load />
156
- )
157
- }
158
-
159
- {
160
- message.data.versions && shouldRenderSideBarSection('versions') && (
161
- <VersionList
162
- title={`Versions (${message.data.versions?.length})`}
163
- versions={message.data.versions}
164
- collectionItem={message}
165
- />
166
- )
167
- }
168
-
169
- {
170
- message.data.attachments && shouldRenderSideBarSection('attachments') && (
171
- <PillListFlat
172
- title={`Attachments (${attachmentsList.length})`}
173
- pills={attachmentsList}
174
- emptyMessage={`This ${type} does not have any attachments.`}
175
- color="pink"
176
- client:load
177
- />
178
- )
179
- }
180
-
181
- {
182
- ownersList.length > 0 && shouldRenderSideBarSection('owners') && (
183
- <OwnersList
184
- title={`Owners (${ownersList.length})`}
185
- owners={ownersList}
186
- emptyMessage={`This ${type} does not have any documented owners.`}
187
- client:load
188
- />
189
- )
190
- }
191
-
192
- {
193
- message.data.repository && shouldRenderSideBarSection('repository') && (
194
- <RepositoryList repository={message.data.repository?.url} language={message.data.repository?.language} />
195
- )
196
- }
197
-
198
- {
199
- isRSSEnabled && (
200
- <div class="mx-auto pb-8 w-full max-w-lg divide-y divide-white/5 rounded-xl bg-white/5">
201
- <span class="text-sm text-black font-semibold group-data-[hover]:text-black/80 capitalize">{type} RSS Feed</span>
202
- <ul role="list" class="space-y-2 mt-2">
203
- <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 ">
204
- <a class={`flex items-center space-x-2`} target="_blank" href={buildUrl(`/rss/${message.collection}/rss.xml`)}>
205
- <RssIcon className="h-4 w-4 text-gray-800 group-hover:text-white" strokeWidth={1} />
206
- <span class="font-light text-sm truncate">RSS Feed</span>
207
- </a>
208
- </li>
209
- </ul>
210
- </div>
211
- )
212
- }
213
-
214
- <div class="space-y-2">
215
- {
216
- message?.data?.schemaPath && (
217
- <a
218
- href={buildUrl(schemaURL, true)}
219
- download={`${message.data.name}(${message.data.version})-${schemaFilePath}`}
220
- 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"
221
- >
222
- <FileDownIcon strokeWidth={2} size={16} />
223
- <span>Download {getSchemaFormatFromURL(schemaURL)?.toUpperCase()} schema</span>
224
- </a>
225
- )
226
- }
227
- <a
228
- href={buildUrl(`/visualiser/${message.collection}/${message.data.id}/${message.data.version}`)}
229
- 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"
230
- >
231
- <Workflow strokeWidth={2} size={16} />
232
- <span class="block">View in visualiser</span>
233
- </a>
234
-
235
- {
236
- isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
237
- <a
238
- href={buildUrl(`/docs/${message.collection}/${message.data.id}/${message.data.latestVersion}/changelog`)}
239
- 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"
240
- >
241
- <ScrollText strokeWidth={2} size={16} />
242
- <span class="block">Read changelog</span>
243
- </a>
244
- )
245
- }
246
- </div>
247
- </div>
248
- </aside>
@@ -1,294 +0,0 @@
1
- ---
2
- import OwnersList from '@components/Lists/OwnersList';
3
- import PillListFlat from '@components/Lists/PillListFlat';
4
- import RepositoryList from '@components/Lists/RepositoryList.astro';
5
- import SpecificationsList from '@components/Lists/SpecificationsList.astro';
6
- import CustomSideBarSectionList from '@components/Lists/CustomSideBarSectionList.astro';
7
- import VersionList from '@components/Lists/VersionList.astro';
8
- import { buildUrl } from '@utils/url-builder';
9
- import { getOwner } from '@utils/collections/owners';
10
- import type { CollectionEntry } from 'astro:content';
11
- import { ScrollText, Workflow, FileDownIcon, Code, Link, RssIcon } from 'lucide-react';
12
- import { join } from 'node:path';
13
- import config from '@config';
14
- import { getDomainsForService } from '@utils/collections/domains';
15
- import { isChangelogEnabled } from '@utils/feature';
16
- interface Props {
17
- service: CollectionEntry<'services'>;
18
- }
19
-
20
- const { service } = Astro.props;
21
-
22
- // @ts-ignore
23
- const sends = (service.data.sends as CollectionEntry<'events'>[]) || [];
24
- // @ts-ignore
25
- const receives = (service.data.receives as CollectionEntry<'events'>[]) || [];
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
-
32
- // @ts-ignore
33
- const entities = (service.data.entities as CollectionEntry<'entities'>[]) || [];
34
-
35
- const ownersRaw = service.data?.owners || [];
36
- const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
37
- const filteredOwners = owners.filter((o) => o !== undefined);
38
-
39
- const resourceGroups = service.data?.resourceGroups || [];
40
-
41
- const domainsServiceBelongsTo = await getDomainsForService(service);
42
-
43
- const attachments = service.data.attachments || [];
44
-
45
- const attachmentsList = attachments.map((a) => {
46
- const attachmentIsURL = typeof a === 'string';
47
- return {
48
- label: attachmentIsURL ? a : (a.title ?? a.url),
49
- href: attachmentIsURL ? a : a.url,
50
- icon: attachmentIsURL ? 'ExternalLinkIcon' : (a.icon ?? 'ExternalLinkIcon'),
51
- target: '_blank' as const,
52
- subgroup: attachmentIsURL ? undefined : (a.type ?? ''),
53
- };
54
- });
55
-
56
- const sendsList = sends
57
- .sort((a, b) => a.collection.localeCompare(b.collection))
58
- .map((p) => ({
59
- label: p.data.name,
60
- badge: p.collection,
61
- color: p.collection === 'events' ? 'orange' : 'blue',
62
- collection: p.collection,
63
- tag: `v${p.data.version}`,
64
- href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
65
- }));
66
-
67
- const receivesList = receives
68
- .sort((a, b) => a.collection.localeCompare(b.collection))
69
- .map((p) => ({
70
- label: p.data.name,
71
- badge: p.collection,
72
- color: p.collection === 'events' ? 'orange' : 'blue',
73
- tag: `v${p.data.version}`,
74
- collection: p.collection,
75
- href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
76
- }));
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
-
96
- const ownersList = filteredOwners.map((o) => ({
97
- label: o.data.name,
98
- type: o.collection,
99
- badge: o.collection === 'users' ? o.data.role : 'Team',
100
- avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
101
- href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
102
- }));
103
-
104
- const domainList = domainsServiceBelongsTo.map((d) => ({
105
- label: d.data.name,
106
- badge: d.collection,
107
- tag: `v${d.data.version}`,
108
- collection: d.collection,
109
- href: buildUrl(`/docs/${d.collection}/${d.data.id}/${d.data.version}`),
110
- }));
111
-
112
- const entityList = entities.map((p) => ({
113
- label: p.data.name,
114
- badge: p.collection,
115
- tag: `v${p.data.version}`,
116
- collection: p.collection,
117
- href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
118
- }));
119
-
120
- const isRSSEnabled = config.rss?.enabled;
121
-
122
- // @ts-ignore
123
- const publicPath = service?.catalog?.publicPath;
124
- const schemaFilePath = service?.data?.schemaPath;
125
- const schemaURL = join(publicPath, schemaFilePath || '');
126
-
127
- const shouldRenderSideBarSection = (section: string) => {
128
- if (!service.data.detailsPanel) {
129
- return true;
130
- }
131
- // @ts-ignore
132
- return service.data.detailsPanel[section]?.visible ?? true;
133
- };
134
- ---
135
-
136
- <aside class="sticky top-28 left-0 h-full overflow-y-auto pr-6 py-4">
137
- <div id="sidebar-cta-portal" class="">
138
- {
139
- resourceGroups
140
- .filter((section) => section.items.length > 0 && section.sidebar)
141
- .map((section) => <CustomSideBarSectionList section={section} />)
142
- }
143
- {
144
- domainList.length > 0 && shouldRenderSideBarSection('domains') && (
145
- <PillListFlat
146
- title={`Domains (${domainList.length})`}
147
- pills={domainList}
148
- emptyMessage={`This service does not belong to any domains.`}
149
- color="orange"
150
- client:load
151
- />
152
- )
153
- }
154
- {
155
- shouldRenderSideBarSection('messages') && (
156
- <>
157
- <PillListFlat
158
- title={`Receives Messages (${receivesList.length})`}
159
- pills={receivesList}
160
- emptyMessage={`This service does not receive any messages.`}
161
- color="orange"
162
- client:load
163
- />
164
- <PillListFlat
165
- title={`Sends Messages (${sendsList.length})`}
166
- pills={sendsList}
167
- emptyMessage={`This service does not send any messages.`}
168
- color="orange"
169
- client:load
170
- />
171
- </>
172
- )
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
- </>
192
- {
193
- service.data.versions && shouldRenderSideBarSection('versions') && (
194
- <VersionList versions={service.data.versions} collectionItem={service} />
195
- )
196
- }
197
-
198
- {
199
- service.data.attachments && shouldRenderSideBarSection('attachments') && (
200
- <PillListFlat
201
- title={`Attachments (${attachmentsList.length})`}
202
- pills={attachmentsList}
203
- emptyMessage={`This service does not have any attachments.`}
204
- color="pink"
205
- client:load
206
- />
207
- )
208
- }
209
-
210
- {
211
- service.data.specifications && shouldRenderSideBarSection('specifications') && (
212
- <SpecificationsList collectionItem={service} />
213
- )
214
- }
215
-
216
- {
217
- entities.length > 0 && shouldRenderSideBarSection('entities') && (
218
- <PillListFlat
219
- title={`Entities (${entities.length})`}
220
- pills={entityList}
221
- emptyMessage={`This service does not contain any entities.`}
222
- color="pink"
223
- client:load
224
- />
225
- )
226
- }
227
-
228
- {
229
- shouldRenderSideBarSection('owners') && (
230
- <OwnersList
231
- title={`Owners (${ownersList.length})`}
232
- owners={ownersList}
233
- emptyMessage={`This service does not have any documented owners.`}
234
- client:load
235
- />
236
- )
237
- }
238
-
239
- {
240
- service.data.repository && shouldRenderSideBarSection('repository') && (
241
- <RepositoryList repository={service.data.repository?.url} language={service.data.repository?.language} />
242
- )
243
- }
244
-
245
- {
246
- isRSSEnabled && (
247
- <div class="mx-auto pb-4 w-full max-w-lg divide-y divide-white/5 rounded-xl bg-white/5 border-b border-gray-100 mb-4">
248
- <span class="text-sm text-black font-semibold group-data-[hover]:text-black/80 capitalize">Services RSS Feed</span>
249
- <ul role="list" class="space-y-2 mt-2">
250
- <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 ">
251
- <a class={`flex items-center space-x-2`} target="_blank" href={buildUrl(`/rss/services/rss.xml`)}>
252
- <RssIcon className="h-4 w-4 text-gray-800 group-hover:text-white" strokeWidth={1} />
253
- <span class="font-light text-sm truncate">RSS</span>
254
- </a>
255
- </li>
256
- </ul>
257
- </div>
258
- )
259
- }
260
-
261
- <div class="space-y-2">
262
- {
263
- service?.data?.schemaPath && (
264
- <a
265
- href={buildUrl(schemaURL, true)}
266
- download={`${service.data.name}(${service.data.version})-${schemaFilePath}`}
267
- 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"
268
- >
269
- <FileDownIcon strokeWidth={2} size={16} />
270
- <span>Download schema</span>
271
- </a>
272
- )
273
- }
274
- <a
275
- href={buildUrl(`/visualiser/${service.collection}/${service.data.id}/${service.data.version}`)}
276
- 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"
277
- >
278
- <Workflow strokeWidth={2} size={16} />
279
- <span class="block">View in visualiser</span>
280
- </a>
281
- {
282
- isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
283
- <a
284
- href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.latestVersion}/changelog`)}
285
- 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"
286
- >
287
- <ScrollText strokeWidth={2} size={16} />
288
- <span class="block">Read changelog</span>
289
- </a>
290
- )
291
- }
292
- </div>
293
- </div>
294
- </aside>
@@ -1,46 +0,0 @@
1
- import React from 'react';
2
- import { ChevronDownIcon } from '@heroicons/react/24/outline';
3
-
4
- interface CollapsibleGroupProps {
5
- isCollapsed: boolean;
6
- onToggle: () => void;
7
- title: React.ReactNode;
8
- children: React.ReactNode;
9
- className?: string;
10
- }
11
-
12
- const CollapsibleGroup: React.FC<CollapsibleGroupProps> = ({ isCollapsed, onToggle, title, children, className = '' }) => (
13
- <div className={className}>
14
- <div className="flex items-center">
15
- <button
16
- onClick={(e) => {
17
- e.stopPropagation();
18
- onToggle();
19
- }}
20
- className="p-1 hover:bg-gray-100 rounded-md"
21
- >
22
- <div className={`transition-transform duration-150 ${isCollapsed ? '' : 'rotate-180'}`}>
23
- <ChevronDownIcon className="h-3 w-3 text-gray-500" />
24
- </div>
25
- </button>
26
- {typeof title === 'string' ? (
27
- <button
28
- onClick={(e) => {
29
- e.stopPropagation();
30
- onToggle();
31
- }}
32
- className="flex-grow flex items-center justify-between px-2 py-0.5 text-xs font-bold rounded-md"
33
- >
34
- {title}
35
- </button>
36
- ) : (
37
- title
38
- )}
39
- </div>
40
- <div className={`overflow-hidden transition-[height] duration-150 ease-out ${isCollapsed ? 'h-0' : 'h-auto'}`}>
41
- {children}
42
- </div>
43
- </div>
44
- );
45
-
46
- export default CollapsibleGroup;
@@ -1,78 +0,0 @@
1
- import React from 'react';
2
- import { getMessageColorByCollection, getMessageCollectionName } from '../index';
3
-
4
- interface MessageListProps {
5
- messages: any[];
6
- decodedCurrentPath: string;
7
- searchTerm?: string;
8
- }
9
-
10
- const HighlightedText = React.memo(({ text, searchTerm }: { text: string; searchTerm?: string }) => {
11
- if (!searchTerm) return <>{text}</>;
12
-
13
- const regex = new RegExp(`(${searchTerm})`, 'gi');
14
- const parts = text.split(regex);
15
-
16
- return (
17
- <>
18
- {parts.map((part, index) =>
19
- regex.test(part) ? (
20
- <span key={index} className="bg-yellow-200 text-gray-900 font-semibold">
21
- {part}
22
- </span>
23
- ) : (
24
- <span key={index}>{part}</span>
25
- )
26
- )}
27
- </>
28
- );
29
- });
30
-
31
- const getMessageColorByLabelOrCollection = (collection: string, badge?: string) => {
32
- if (!badge) {
33
- return getMessageColorByCollection(collection);
34
- }
35
-
36
- // Will try and match the label against HTTP verbs
37
- const httpVerbs = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'];
38
- if (badge && httpVerbs.includes(badge.toUpperCase())) {
39
- if (badge.toUpperCase() === 'GET') return 'bg-blue-50 text-blue-600';
40
- if (badge.toUpperCase() === 'POST') return 'bg-green-50 text-green-600';
41
- if (badge.toUpperCase() === 'PUT') return 'bg-yellow-50 text-yellow-600';
42
- if (badge.toUpperCase() === 'DELETE') return 'bg-red-50 text-red-600';
43
- if (badge.toUpperCase() === 'PATCH') return 'bg-purple-50 text-purple-600';
44
- if (badge.toUpperCase() === 'HEAD') return 'bg-gray-50 text-gray-600';
45
- if (badge.toUpperCase() === 'OPTIONS') return 'bg-orange-50 text-orange-600';
46
- }
47
-
48
- return getMessageColorByCollection(collection);
49
- };
50
-
51
- const MessageList: React.FC<MessageListProps> = ({ messages, decodedCurrentPath, searchTerm }) => (
52
- <ul className="space-y-0.5 border-l border-gray-200/80 ml-[9px] pl-4">
53
- {messages.map((message: any) => (
54
- <li key={message.id} data-active={decodedCurrentPath === message.href}>
55
- <a
56
- href={message.href}
57
- data-active={decodedCurrentPath === message.href}
58
- className={`flex items-center justify-between px-2 py-1.5 text-xs text-gray-600 hover:bg-purple-100 rounded-md ${
59
- decodedCurrentPath.includes(message.href) ? 'bg-purple-100 ' : 'hover:bg-purple-100'
60
- }`}
61
- title={message.data?.sidebar?.label || message.data.name}
62
- >
63
- <span className="truncate">
64
- <HighlightedText text={message.data?.sidebar?.label || message.data.name} searchTerm={searchTerm} />
65
- <span className="text-xs text-gray-400">{message.data.draft ? ' (DRAFT)' : ''}</span>
66
- </span>
67
- <span
68
- 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}`}
69
- >
70
- {message.data?.sidebar?.badge || getMessageCollectionName(message.collection, message)}
71
- </span>
72
- </a>
73
- </li>
74
- ))}
75
- </ul>
76
- );
77
-
78
- export default MessageList;