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