@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,196 +1,25 @@
1
- import { useState, useMemo, useEffect } from 'react';
2
- import { EnvelopeIcon, ChevronRightIcon, ServerIcon, CircleStackIcon } from '@heroicons/react/24/outline';
3
- import { RectangleGroupIcon } from '@heroicons/react/24/outline';
4
- import { buildUrl, buildUrlWithParams } from '@utils/url-builder';
1
+ import { ServerIcon, CircleStackIcon } from '@heroicons/react/24/outline';
2
+ import { buildUrl } from '@utils/url-builder';
5
3
  import type { CollectionEntry } from 'astro:content';
6
- import type { CollectionMessageTypes } from '@types';
7
4
  import { getCollectionStyles } from './utils';
8
- import { SearchBar, TypeFilters, Pagination } from './components';
9
5
 
10
- interface MessageGridProps {
11
- messages: CollectionEntry<CollectionMessageTypes>[];
12
- containers?: CollectionEntry<'containers'>[];
13
- embeded: boolean;
6
+ interface MessageGridV2Props {
7
+ service: CollectionEntry<'services'>;
8
+ embeded?: boolean;
14
9
  }
15
10
 
16
- interface GroupedMessages {
17
- all?: CollectionEntry<CollectionMessageTypes>[];
18
- sends?: CollectionEntry<CollectionMessageTypes>[];
19
- receives?: CollectionEntry<CollectionMessageTypes>[];
20
- }
21
-
22
- export default function MessageGrid({ messages, embeded, containers }: MessageGridProps) {
23
- const [searchQuery, setSearchQuery] = useState('');
24
- const [urlParams, setUrlParams] = useState<{
25
- serviceId?: string;
26
- serviceName?: string;
27
- domainId?: string;
28
- domainName?: string;
29
- } | null>(null);
30
- const [currentPage, setCurrentPage] = useState(1);
31
- const [selectedTypes, setSelectedTypes] = useState<CollectionMessageTypes[]>([]);
32
- const [producerConsumerFilter, setProducerConsumerFilter] = useState<'all' | 'no-producers' | 'no-consumers'>('all');
33
- const ITEMS_PER_PAGE = 15;
34
-
35
- // Effect to sync URL params with state
36
- useEffect(() => {
37
- const params = new URLSearchParams(window.location.search);
38
- const serviceId = params.get('serviceId') || undefined;
39
- const serviceName = params.get('serviceName') ? decodeURIComponent(params.get('serviceName')!) : undefined;
40
- const domainId = params.get('domainId') || undefined;
41
- const domainName = params.get('domainName') || undefined;
42
- setUrlParams({
43
- serviceId,
44
- serviceName,
45
- domainId,
46
- domainName,
47
- });
48
- }, []);
49
-
50
- const filteredAndSortedMessages = useMemo(() => {
51
- if (urlParams === null) return [];
52
-
53
- let result = [...messages];
54
-
55
- // Filter by message type
56
- if (selectedTypes.length > 0) {
57
- result = result.filter((message) => selectedTypes.includes(message.collection));
58
- }
59
-
60
- // Apply producer/consumer filters
61
- if (producerConsumerFilter === 'no-producers') {
62
- result = result.filter((message) => !message.data.producers || message.data.producers.length === 0);
63
- } else if (producerConsumerFilter === 'no-consumers') {
64
- result = result.filter((message) => !message.data.consumers || message.data.consumers.length === 0);
65
- }
66
-
67
- // Filter by service ID or name if present
68
- if (urlParams.serviceId) {
69
- result = result.filter(
70
- (message) =>
71
- message.data.producers?.some(
72
- (producer: any) => producer.id === urlParams.serviceId && !producer.id.includes('/versioned/')
73
- ) ||
74
- message.data.consumers?.some(
75
- (consumer: any) => consumer.id === urlParams.serviceId && !consumer.id.includes('/versioned/')
76
- )
77
- );
78
- }
79
-
80
- // Filter by search query
81
- if (searchQuery) {
82
- const query = searchQuery.toLowerCase();
83
- result = result.filter(
84
- (message) =>
85
- message.data.name?.toLowerCase().includes(query) ||
86
- message.data.summary?.toLowerCase().includes(query) ||
87
- message.data.producers?.some((producer: any) => producer.data.id?.toLowerCase().includes(query)) ||
88
- message.data.consumers?.some((consumer: any) => consumer.data.id?.toLowerCase().includes(query))
89
- );
90
- }
91
-
92
- // Sort by name by default
93
- result.sort((a, b) => a.data.name.localeCompare(b.data.name));
94
-
95
- return result;
96
- }, [messages, searchQuery, urlParams, selectedTypes, producerConsumerFilter]);
97
-
98
- // Add totalPages calculation
99
- const totalPages = useMemo(() => {
100
- if (urlParams?.serviceId || urlParams?.domainId) return 1;
101
- return Math.ceil(filteredAndSortedMessages.length / ITEMS_PER_PAGE);
102
- }, [filteredAndSortedMessages.length, urlParams]);
103
-
104
- // Add paginatedMessages calculation
105
- const paginatedMessages = useMemo(() => {
106
- if (urlParams?.serviceId || urlParams?.domainId) {
107
- return filteredAndSortedMessages;
108
- }
109
-
110
- const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
111
- return filteredAndSortedMessages.slice(startIndex, startIndex + ITEMS_PER_PAGE);
112
- }, [filteredAndSortedMessages, currentPage, urlParams]);
113
-
114
- // Reset pagination when search query or filters change
115
- useEffect(() => {
116
- setCurrentPage(1);
117
- }, [searchQuery, selectedTypes]);
118
-
119
- // Group messages by sends/receives when a service is selected
120
- const groupedMessages = useMemo<GroupedMessages>(() => {
121
- if (!urlParams?.serviceId) return { all: filteredAndSortedMessages };
122
-
123
- const serviceIdentifier = urlParams.serviceId;
124
- const sends = filteredAndSortedMessages.filter((message) =>
125
- message.data.producers?.some((producer: any) => producer.id === serviceIdentifier)
126
- );
127
- const receives = filteredAndSortedMessages.filter((message) =>
128
- message.data.consumers?.some((consumer: any) => consumer.id === serviceIdentifier)
129
- );
130
-
131
- return { sends, receives };
132
- }, [filteredAndSortedMessages, urlParams]);
133
-
134
- // Get the containers that are referenced by the service
135
- const serviceContainersReferenced = useMemo(() => {
136
- if (!urlParams?.serviceId || !containers) return { writesTo: [], readsFrom: [] };
137
- return {
138
- writesTo: containers.filter((container) =>
139
- container.data.servicesThatWriteToContainer?.some((service: any) => service.data.id === urlParams.serviceId)
140
- ),
141
- readsFrom: containers.filter((container) =>
142
- container.data.servicesThatReadFromContainer?.some((service: any) => service.data.id === urlParams.serviceId)
143
- ),
144
- };
145
- }, [containers, urlParams]);
146
-
147
- const renderTypeFilters = () => {
148
- return (
149
- <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
150
- <div className="flex items-center gap-2">
151
- <TypeFilters
152
- selectedTypes={selectedTypes}
153
- onTypeChange={setSelectedTypes}
154
- filteredCount={filteredAndSortedMessages.filter((m) => selectedTypes.includes(m.collection)).length}
155
- />
156
- </div>
157
-
158
- <div className="flex items-center gap-2 border-l border-gray-200 pl-4">
159
- <div className="flex items-center gap-2">
160
- <select
161
- value={producerConsumerFilter}
162
- onChange={(e) => setProducerConsumerFilter(e.target.value as typeof producerConsumerFilter)}
163
- className="block rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-primary sm:text-sm sm:leading-6"
164
- >
165
- <option value="all">All Messages</option>
166
- <option value="no-producers">Without Producers</option>
167
- <option value="no-consumers">Without Consumers</option>
168
- </select>
169
- {producerConsumerFilter !== 'all' && (
170
- <button
171
- onClick={() => setProducerConsumerFilter('all')}
172
- className="text-xs text-gray-500 hover:text-gray-700 hover:underline"
173
- >
174
- Clear
175
- </button>
176
- )}
177
- </div>
178
- </div>
179
- </div>
180
- );
181
- };
11
+ export default function MessageGridV2({ service, embeded = false }: MessageGridV2Props) {
12
+ const { sends = [], receives = [], writesTo = [], readsFrom = [] } = service.data;
182
13
 
183
- const renderMessageGrid = (messages: CollectionEntry<CollectionMessageTypes>[]) => (
184
- <div
185
- className={`grid ${urlParams?.serviceName ? 'grid-cols-1' : 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3'} gap-6`}
186
- >
14
+ const renderMessageGrid = (messages: any[]) => (
15
+ <div className="grid grid-cols-1 gap-6">
187
16
  {messages.map((message) => {
188
17
  const { color, Icon } = getCollectionStyles(message.collection);
189
18
  return (
190
19
  <a
191
20
  key={message.data.name}
192
21
  href={buildUrl(`/docs/${message.collection}/${message.data.id}/${message.data.version}`)}
193
- className={`group bg-white border hover:bg-${color}-100 rounded-lg shadow-sm hover:shadow-lg transition-all duration-200 overflow-hidden border-${color}-500 `}
22
+ className={`group bg-white border hover:bg-${color}-100 rounded-lg shadow-sm hover:shadow-lg transition-all duration-200 overflow-hidden border-${color}-500`}
194
23
  >
195
24
  <div className="p-4 py-2 flex-1">
196
25
  <div className="flex items-center justify-between mb-3">
@@ -203,30 +32,7 @@ export default function MessageGrid({ messages, embeded, containers }: MessageGr
203
32
  </h3>
204
33
  </div>
205
34
  </div>
206
-
207
35
  {message.data.summary && <p className="text-gray-600 text-xs line-clamp-2 mb-4">{message.data.summary}</p>}
208
-
209
- {/* Only show stats in non-service view */}
210
- {!urlParams?.serviceName && (
211
- <div className="space-y-4">
212
- <div className="grid grid-cols-2 gap-2 p-3 bg-gray-50 rounded-lg">
213
- <div className="text-center">
214
- <div className="flex items-center justify-center mb-1">
215
- <ServerIcon className={`h-5 w-5 text-pink-500`} />
216
- </div>
217
- <div className="text-sm font-medium text-gray-900">{message.data.producers?.length ?? 0}</div>
218
- <div className="text-xs text-gray-500">Producers</div>
219
- </div>
220
- <div className="text-center border-l border-gray-200">
221
- <div className="flex items-center justify-center mb-1">
222
- <ServerIcon className={`h-5 w-5 text-pink-500`} />
223
- </div>
224
- <div className="text-sm font-medium text-gray-900">{message.data.consumers?.length ?? 0}</div>
225
- <div className="text-xs text-gray-500">Consumers</div>
226
- </div>
227
- </div>
228
- </div>
229
- )}
230
36
  </div>
231
37
  </a>
232
38
  );
@@ -234,339 +40,181 @@ export default function MessageGrid({ messages, embeded, containers }: MessageGr
234
40
  </div>
235
41
  );
236
42
 
237
- const renderPaginationControls = () => {
238
- if (totalPages <= 1 || urlParams?.serviceName || urlParams?.domainId) return null;
239
-
240
- return (
241
- <Pagination
242
- currentPage={currentPage}
243
- totalPages={totalPages}
244
- totalItems={filteredAndSortedMessages.length}
245
- itemsPerPage={ITEMS_PER_PAGE}
246
- onPageChange={setCurrentPage}
247
- />
248
- );
249
- };
250
-
251
43
  return (
252
- <div>
253
- {/* Breadcrumb */}
254
- <nav className="mb-4 flex items-center space-x-2 text-sm text-gray-500">
255
- <a href={buildUrl('/architecture/domains')} className="hover:text-gray-700 hover:underline flex items-center gap-2">
256
- <RectangleGroupIcon className="h-4 w-4" />
257
- Domains
258
- </a>
259
- <ChevronRightIcon className="h-4 w-4" />
260
- <a href={buildUrl('/architecture/services')} className="hover:text-gray-700 hover:underline flex items-center gap-2">
261
- <ServerIcon className="h-4 w-4" />
262
- Services
263
- </a>
264
- <ChevronRightIcon className="h-4 w-4" />
265
- <a href={buildUrl('/architecture/messages')} className="hover:text-gray-700 hover:underline flex items-center gap-2">
266
- <EnvelopeIcon className="h-4 w-4" />
267
- Messages
268
- </a>
269
- {urlParams?.domainId && (
270
- <>
271
- <ChevronRightIcon className="h-4 w-4" />
272
- <a
273
- href={buildUrlWithParams(`/architecture/services`, {
274
- domainName: urlParams.domainName,
275
- domainId: urlParams.domainId,
276
- serviceName: urlParams.serviceName,
277
- serviceId: urlParams.serviceId,
278
- })}
279
- className="hover:text-gray-700 hover:underline"
280
- >
281
- {urlParams.domainId}
282
- </a>
283
- </>
284
- )}
285
- {urlParams?.serviceName && (
286
- <>
287
- <ChevronRightIcon className="h-4 w-4" />
288
- <span className="text-gray-900">{urlParams.serviceName}</span>
289
- </>
290
- )}
291
- </nav>
292
-
293
- {/* Title Section */}
294
- <div className="relative border-b border-gray-200 mb-4 pb-4">
295
- <div className="md:flex md:items-start md:justify-between">
296
- <div className="min-w-0 flex-1 max-w-lg">
297
- <div className="flex items-center gap-2">
298
- <h1 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
299
- {urlParams?.domainName ? `Messages in ${urlParams.serviceName}` : 'All Messages'}
300
- </h1>
301
- </div>
302
- <p className="mt-2 text-sm text-gray-500">
303
- {urlParams?.domainName
304
- ? `Browse messages in the ${urlParams.serviceName} service`
305
- : 'Browse and discover messages in your event-driven architecture'}
306
- </p>
307
- </div>
308
-
309
- <div className="mt-6 md:mt-0 md:ml-4 flex-shrink-0">
310
- <SearchBar
311
- searchQuery={searchQuery}
312
- onSearchChange={setSearchQuery}
313
- placeholder="Search messages by name, summary, or services..."
314
- totalResults={filteredAndSortedMessages.length}
315
- totalItems={messages.length}
316
- />
317
- </div>
44
+ <div className={`rounded-xl overflow-hidden bg-pink-50 p-8 border-2 border-dashed border-pink-300`}>
45
+ {/* Service Title */}
46
+ <div className="flex items-center gap-2 mb-8">
47
+ <ServerIcon className="h-6 w-6 text-pink-500" />
48
+ <h2 className="text-2xl font-semibold text-gray-900">{service.data.name}</h2>
49
+ <div className="flex gap-2 ml-auto">
50
+ <a
51
+ href={buildUrl(`/visualiser/services/${service.data.id}`)}
52
+ className="inline-flex items-center px-3 py-2 text-sm font-medium bg-white border border-gray-300 rounded-md transition-colors duration-200 hover:bg-gray-50"
53
+ >
54
+ View in visualizer
55
+ </a>
56
+ <a
57
+ href={buildUrl(`/docs/services/${service.data.id}/${service.data.version}`)}
58
+ className="inline-flex items-center px-3 py-2 text-sm font-medium text-black border border-gray-300 bg-white rounded-md transition-colors duration-200 hover:bg-gray-50"
59
+ >
60
+ Read documentation
61
+ </a>
318
62
  </div>
319
63
  </div>
320
64
 
321
- <div className="mb-8">
322
- {/* Results count and top pagination */}
323
- <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
324
- {renderTypeFilters()}
325
- {renderPaginationControls()}
326
- </div>
327
- </div>
65
+ <div className="grid grid-cols-3 gap-8 relative">
66
+ {/* Left Column - Receives Messages & Reads From Containers */}
67
+ <div className="space-y-6">
68
+ {/* Receives Messages Section */}
69
+ <div className="bg-blue-50 bg-opacity-50 border border-blue-300 border-dashed rounded-lg p-4">
70
+ <div className="mb-6">
71
+ <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
72
+ <ServerIcon className="h-5 w-5 text-blue-500" />
73
+ Receives ({receives.length})
74
+ </h2>
75
+ </div>
76
+ {receives.length > 0 ? (
77
+ renderMessageGrid(receives)
78
+ ) : (
79
+ <div className="text-center py-12">
80
+ <p className="text-gray-500 text-sm">No messages</p>
81
+ </div>
82
+ )}
83
+ </div>
328
84
 
329
- {filteredAndSortedMessages.length > 0 && (
330
- <div className={`rounded-xl overflow-hidden ${urlParams?.domainId ? 'bg-yellow-50 p-8 border-2 border-yellow-300' : ''}`}>
331
- {urlParams?.domainName && (
332
- <>
333
- <div className="mb-6 flex items-center justify-between">
334
- <div className="flex items-center gap-2">
335
- <RectangleGroupIcon className="h-5 w-5 text-yellow-500" />
336
- <a
337
- href={buildUrlWithParams(`/architecture/services`, {
338
- domainName: urlParams.domainName,
339
- domainId: urlParams.domainId,
340
- })}
341
- className="text-2xl font-semibold text-gray-900 hover:underline"
342
- >
343
- {urlParams.domainName}
344
- </a>
345
- </div>
346
- <div className="flex gap-2">
347
- <a
348
- href={buildUrl(`/visualiser/domains/${urlParams.domainId}`)}
349
- className="inline-flex items-center px-3 py-2 text-sm font-medium bg-white border border-gray-300 rounded-md transition-colors duration-200"
350
- >
351
- View in visualizer
352
- </a>
85
+ {/* Reads From Containers */}
86
+ {readsFrom.length > 0 && (
87
+ <div className="bg-orange-50 border border-orange-300 border-dashed rounded-lg p-4 relative">
88
+ <div className="mb-6">
89
+ <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
90
+ <CircleStackIcon className="h-5 w-5 text-orange-500" />
91
+ Reads from ({readsFrom.length})
92
+ </h2>
93
+ </div>
94
+ <div className="space-y-3">
95
+ {readsFrom.map((container: any) => (
353
96
  <a
354
- href={buildUrl(`/docs/domains/${urlParams.domainId}`)}
355
- className="inline-flex items-center px-3 py-2 text-sm font-medium text-black border border-gray-300 bg-white rounded-md transition-colors duration-200"
97
+ key={container.data.id}
98
+ href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
99
+ className="group bg-white border border-orange-200 hover:bg-orange-100 rounded-lg p-3 block transition-all duration-200"
356
100
  >
357
- Read documentation
101
+ <div className="flex items-center gap-2">
102
+ <CircleStackIcon className="h-4 w-4 text-orange-500" />
103
+ <h3 className="font-semibold text-gray-900 text-sm group-hover:text-orange-700">{container.data.name}</h3>
104
+ </div>
105
+ {container.data.summary && (
106
+ <p className="text-xs text-gray-600 mt-1 line-clamp-2">{container.data.summary}</p>
107
+ )}
358
108
  </a>
359
- </div>
109
+ ))}
110
+ </div>
111
+ {/* Arrow from Reads From to Service */}
112
+ <div className="absolute -right-8 top-1/2 -translate-y-1/2 flex items-center justify-center w-16 z-10">
113
+ <div className="absolute left-0 w-4 h-4 border-b-[3px] border-l-[3px] border-orange-200 transform rotate-45 -translate-x-1 translate-y-[-1px] shadow-[-1px_1px_0_1px_rgba(0,0,0,0.1)]"></div>
114
+ <div className="w-full h-[3px] bg-orange-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
360
115
  </div>
361
- </>
116
+ </div>
362
117
  )}
118
+ </div>
363
119
 
364
- <div
365
- className={`rounded-xl overflow-hidden ${urlParams?.serviceName ? 'bg-pink-50 p-8 border-2 border-dashed border-pink-300' : ''}`}
366
- >
367
- {urlParams?.serviceName ? (
368
- <>
369
- {/* <div className="h-2 bg-pink-500 -mx-8 -mt-8 mb-8"></div> */}
370
- {/* Service Title */}
371
- <div className="flex items-center gap-2 mb-8">
372
- <ServerIcon className="h-6 w-6 text-pink-500" />
373
- <h2 className="text-2xl font-semibold text-gray-900">{urlParams.serviceName}</h2>
374
- <div className="flex gap-2 ml-auto">
375
- <a
376
- href={buildUrl(`/visualiser/services/${urlParams.serviceId}`)}
377
- className="inline-flex items-center px-3 py-2 text-sm font-medium bg-white border border-gray-300 rounded-md transition-colors duration-200 hover:bg-gray-50"
378
- >
379
- View in visualizer
380
- </a>
381
- <a
382
- href={buildUrl(`/docs/services/${urlParams.serviceId}`)}
383
- className="inline-flex items-center px-3 py-2 text-sm font-medium text-black border border-gray-300 bg-white rounded-md transition-colors duration-200 hover:bg-gray-50"
384
- >
385
- Read documentation
386
- </a>
387
- </div>
388
- </div>
389
- <div className="grid grid-cols-3 gap-8 relative">
390
- {/* Left Column - Receives Messages & Reads From Containers */}
391
- <div className="space-y-6">
392
- {/* Receives Messages Section */}
393
- <div className="bg-blue-50 bg-opacity-50 border border-blue-300 border-dashed rounded-lg p-4">
394
- <div className="mb-6">
395
- <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
396
- <ServerIcon className="h-5 w-5 text-blue-500" />
397
- Receives ({groupedMessages.receives?.length || 0})
398
- </h2>
399
- </div>
400
- {groupedMessages.receives && groupedMessages.receives.length > 0 ? (
401
- renderMessageGrid(groupedMessages.receives)
402
- ) : (
403
- <div className="text-center py-12">
404
- <p className="text-gray-500 text-sm">No messages</p>
405
- </div>
406
- )}
407
- </div>
408
-
409
- {/* Reads From Containers - Only show if containers exist */}
410
- {serviceContainersReferenced.readsFrom && serviceContainersReferenced.readsFrom.length > 0 && (
411
- <div className="bg-orange-50 border border-orange-300 border-dashed rounded-lg p-4 relative">
412
- <div className="mb-6">
413
- <h2
414
- className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}
415
- >
416
- <CircleStackIcon className="h-5 w-5 text-orange-500" />
417
- Reads from ({serviceContainersReferenced.readsFrom.length})
418
- </h2>
419
- </div>
420
- <div className="space-y-3">
421
- {serviceContainersReferenced.readsFrom.map((container: CollectionEntry<'containers'>) => (
422
- <a
423
- key={container.data.id}
424
- href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
425
- className="group bg-white border border-orange-200 hover:bg-orange-100 rounded-lg p-3 block transition-all duration-200"
426
- >
427
- <div className="flex items-center gap-2">
428
- <CircleStackIcon className="h-4 w-4 text-orange-500" />
429
- <h3 className="font-semibold text-gray-900 text-sm group-hover:text-orange-700">
430
- {container.data.name}
431
- </h3>
432
- </div>
433
- {container.data.summary && (
434
- <p className="text-xs text-gray-600 mt-1 line-clamp-2">{container.data.summary}</p>
435
- )}
436
- </a>
437
- ))}
438
- </div>
439
- {/* Arrow from Reads From to Service */}
440
- <div className="absolute -right-8 top-1/2 -translate-y-1/2 flex items-center justify-center w-16 z-10">
441
- <div className="absolute left-0 w-4 h-4 border-b-[3px] border-l-[3px] border-orange-200 transform rotate-45 -translate-x-1 translate-y-[-1px] shadow-[-1px_1px_0_1px_rgba(0,0,0,0.1)]"></div>
442
- <div className="w-full h-[3px] bg-orange-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
443
- </div>
444
- </div>
445
- )}
446
- </div>
447
-
448
- {/* Arrow from Receives to Service */}
449
- <div className="absolute left-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
450
- <div className="w-full h-[3px] bg-blue-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
451
- <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-blue-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
452
- </div>
453
-
454
- {/* Service Information (Center) */}
455
- <div className="bg-white border-2 border-pink-100 rounded-lg p-6 flex flex-col justify-center">
456
- <div className="flex flex-col items-center gap-4">
457
- <ServerIcon className="h-12 w-12 text-pink-500" />
458
- <p className="text-xl font-semibold text-gray-900 text-center">{urlParams.serviceName}</p>
459
-
460
- {/* Quick Stats Grid */}
461
- <div className="w-full grid grid-cols-2 gap-3 mt-2">
462
- <div className="text-center p-3 bg-blue-50 rounded-lg border border-blue-200">
463
- <div className="text-2xl font-bold text-blue-600">{groupedMessages.receives?.length || 0}</div>
464
- <div className="text-xs text-gray-600 mt-1">Receives</div>
465
- </div>
466
- <div className="text-center p-3 bg-green-50 rounded-lg border border-green-200">
467
- <div className="text-2xl font-bold text-green-600">{groupedMessages.sends?.length || 0}</div>
468
- <div className="text-xs text-gray-600 mt-1">Sends</div>
469
- </div>
470
- {serviceContainersReferenced.readsFrom && serviceContainersReferenced.readsFrom.length > 0 && (
471
- <div className="text-center p-3 bg-orange-50 rounded-lg border border-orange-200">
472
- <div className="text-2xl font-bold text-orange-600">
473
- {serviceContainersReferenced.readsFrom.length}
474
- </div>
475
- <div className="text-xs text-gray-600 mt-1">Reads from</div>
476
- </div>
477
- )}
478
- {serviceContainersReferenced.writesTo && serviceContainersReferenced.writesTo.length > 0 && (
479
- <div className="text-center p-3 bg-purple-50 rounded-lg border border-purple-200">
480
- <div className="text-2xl font-bold text-purple-600">
481
- {serviceContainersReferenced.writesTo.length}
482
- </div>
483
- <div className="text-xs text-gray-600 mt-1">Writes to</div>
484
- </div>
485
- )}
486
- </div>
487
- </div>
488
- </div>
120
+ {/* Arrow from Receives to Service */}
121
+ <div className="absolute left-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
122
+ <div className="w-full h-[3px] bg-blue-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
123
+ <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-blue-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
124
+ </div>
489
125
 
490
- {/* Arrow from Service to Sends */}
491
- <div className="absolute right-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
492
- <div className="w-full h-[3px] bg-green-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
493
- <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-green-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
494
- </div>
126
+ {/* Service Information (Center) */}
127
+ <div className="bg-white border-2 border-pink-100 rounded-lg p-6 flex flex-col justify-center">
128
+ <div className="flex flex-col items-center gap-4">
129
+ <ServerIcon className="h-12 w-12 text-pink-500" />
130
+ <p className="text-xl font-semibold text-gray-900 text-center">{service.data.name}</p>
131
+
132
+ {/* Quick Stats Grid */}
133
+ <div className="w-full grid grid-cols-2 gap-3 mt-2">
134
+ <div className="text-center p-3 bg-blue-50 rounded-lg border border-blue-200">
135
+ <div className="text-2xl font-bold text-blue-600">{receives.length}</div>
136
+ <div className="text-xs text-gray-600 mt-1">Receives</div>
137
+ </div>
138
+ <div className="text-center p-3 bg-green-50 rounded-lg border border-green-200">
139
+ <div className="text-2xl font-bold text-green-600">{sends.length}</div>
140
+ <div className="text-xs text-gray-600 mt-1">Sends</div>
141
+ </div>
142
+ {readsFrom.length > 0 && (
143
+ <div className="text-center p-3 bg-orange-50 rounded-lg border border-orange-200">
144
+ <div className="text-2xl font-bold text-orange-600">{readsFrom.length}</div>
145
+ <div className="text-xs text-gray-600 mt-1">Reads from</div>
146
+ </div>
147
+ )}
148
+ {writesTo.length > 0 && (
149
+ <div className="text-center p-3 bg-purple-50 rounded-lg border border-purple-200">
150
+ <div className="text-2xl font-bold text-purple-600">{writesTo.length}</div>
151
+ <div className="text-xs text-gray-600 mt-1">Writes to</div>
152
+ </div>
153
+ )}
154
+ </div>
155
+ </div>
156
+ </div>
495
157
 
496
- {/* Right Column - Sends Messages & Writes To Containers */}
497
- <div className="space-y-6">
498
- {/* Sends Messages Section */}
499
- <div className="bg-green-50 border border-green-300 border-dashed rounded-lg p-4">
500
- <div className="mb-6">
501
- <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
502
- <ServerIcon className="h-5 w-5 text-emerald-500" />
503
- Sends ({groupedMessages.sends?.length || 0})
504
- </h2>
505
- </div>
506
- {groupedMessages.sends && groupedMessages.sends.length > 0 ? (
507
- renderMessageGrid(groupedMessages.sends)
508
- ) : (
509
- <div className="text-center py-12">
510
- <p className="text-gray-500 text-sm">No messages</p>
511
- </div>
512
- )}
513
- </div>
158
+ {/* Arrow from Service to Sends */}
159
+ <div className="absolute right-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
160
+ <div className="w-full h-[3px] bg-green-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
161
+ <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-green-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
162
+ </div>
514
163
 
515
- {/* Writes To Containers - Only show if containers exist */}
516
- {serviceContainersReferenced.writesTo && serviceContainersReferenced.writesTo.length > 0 && (
517
- <div className="bg-purple-50 border border-purple-300 border-dashed rounded-lg p-4 relative">
518
- {/* Arrow from Service to Writes To */}
519
- <div className="absolute -left-8 top-1/2 -translate-y-1/2 flex items-center justify-center w-16 z-10">
520
- <div className="w-full h-[3px] bg-purple-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
521
- <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-purple-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
522
- </div>
523
- <div className="mb-6">
524
- <h2
525
- className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}
526
- >
527
- <CircleStackIcon className="h-5 w-5 text-purple-500" />
528
- Writes to ({serviceContainersReferenced.writesTo.length})
529
- </h2>
530
- </div>
531
- <div className="space-y-3">
532
- {serviceContainersReferenced.writesTo.map((container: CollectionEntry<'containers'>) => (
533
- <a
534
- key={container.data.id}
535
- href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
536
- className="group bg-white border border-purple-200 hover:bg-purple-100 rounded-lg p-3 block transition-all duration-200"
537
- >
538
- <div className="flex items-center gap-2">
539
- <CircleStackIcon className="h-4 w-4 text-purple-500" />
540
- <h3 className="font-semibold text-gray-900 text-sm group-hover:text-purple-700">
541
- {container.data.name}
542
- </h3>
543
- </div>
544
- {container.data.summary && (
545
- <p className="text-xs text-gray-600 mt-1 line-clamp-2">{container.data.summary}</p>
546
- )}
547
- </a>
548
- ))}
549
- </div>
550
- </div>
551
- )}
552
- </div>
553
- </div>
554
- </>
164
+ {/* Right Column - Sends Messages & Writes To Containers */}
165
+ <div className="space-y-6">
166
+ {/* Sends Messages Section */}
167
+ <div className="bg-green-50 border border-green-300 border-dashed rounded-lg p-4">
168
+ <div className="mb-6">
169
+ <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
170
+ <ServerIcon className="h-5 w-5 text-emerald-500" />
171
+ Sends ({sends.length})
172
+ </h2>
173
+ </div>
174
+ {sends.length > 0 ? (
175
+ renderMessageGrid(sends)
555
176
  ) : (
556
- <>
557
- {renderMessageGrid(paginatedMessages)}
558
- <div className="mt-8 border-t border-gray-200">{renderPaginationControls()}</div>
559
- </>
177
+ <div className="text-center py-12">
178
+ <p className="text-gray-500 text-sm">No messages</p>
179
+ </div>
560
180
  )}
561
181
  </div>
562
- </div>
563
- )}
564
182
 
565
- {filteredAndSortedMessages.length === 0 && (
566
- <div className="text-center py-12">
567
- <p className="text-gray-500 text-lg">No messages found matching your criteria</p>
183
+ {/* Writes To Containers */}
184
+ {writesTo.length > 0 && (
185
+ <div className="bg-purple-50 border border-purple-300 border-dashed rounded-lg p-4 relative">
186
+ {/* Arrow from Service to Writes To */}
187
+ <div className="absolute -left-8 top-1/2 -translate-y-1/2 flex items-center justify-center w-16 z-10">
188
+ <div className="w-full h-[3px] bg-purple-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
189
+ <div className="absolute right-0 w-4 h-4 border-t-[3px] border-r-[3px] border-purple-200 transform rotate-45 translate-x-1 translate-y-[-1px] shadow-[1px_-1px_0_1px_rgba(0,0,0,0.1)]"></div>
190
+ </div>
191
+ <div className="mb-6">
192
+ <h2 className={`font-semibold text-gray-900 flex items-center gap-2 ${embeded ? 'text-sm' : 'text-xl'}`}>
193
+ <CircleStackIcon className="h-5 w-5 text-purple-500" />
194
+ Writes to ({writesTo.length})
195
+ </h2>
196
+ </div>
197
+ <div className="space-y-3">
198
+ {writesTo.map((container: any) => (
199
+ <a
200
+ key={container.data.id}
201
+ href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
202
+ className="group bg-white border border-purple-200 hover:bg-purple-100 rounded-lg p-3 block transition-all duration-200"
203
+ >
204
+ <div className="flex items-center gap-2">
205
+ <CircleStackIcon className="h-4 w-4 text-purple-500" />
206
+ <h3 className="font-semibold text-gray-900 text-sm group-hover:text-purple-700">{container.data.name}</h3>
207
+ </div>
208
+ {container.data.summary && (
209
+ <p className="text-xs text-gray-600 mt-1 line-clamp-2">{container.data.summary}</p>
210
+ )}
211
+ </a>
212
+ ))}
213
+ </div>
214
+ </div>
215
+ )}
568
216
  </div>
569
- )}
217
+ </div>
570
218
  </div>
571
219
  );
572
220
  }