@eventcatalog/core 2.58.2 → 2.59.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-PV4MP6U4.js → chunk-5GNBQGFW.js} +1 -1
- package/dist/{chunk-WK6GQM5P.js → chunk-AREJNU2F.js} +1 -1
- package/dist/{chunk-ZBPULBAC.js → chunk-LAI5QQUI.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +3 -3
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +67 -2
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +157 -41
- package/eventcatalog/src/components/Grids/ServiceGrid.tsx +78 -14
- package/eventcatalog/src/components/MDX/NodeGraph/Edges/MultilineEdgeLabel.tsx +52 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +13 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +4 -1
- package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Data.tsx +55 -16
- package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +180 -0
- package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +41 -0
- package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +1 -1
- package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +250 -59
- package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +3 -0
- package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +35 -1
- package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +2 -2
- package/eventcatalog/src/components/Tables/Table.tsx +22 -2
- package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +152 -0
- package/eventcatalog/src/components/Tables/columns/index.tsx +3 -0
- package/eventcatalog/src/content.config.ts +57 -1
- package/eventcatalog/src/layouts/DiscoverLayout.astro +11 -1
- package/eventcatalog/src/pages/architecture/architecture.astro +9 -1
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +1 -1
- package/eventcatalog/src/pages/discover/[type]/index.astro +11 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +11 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +4 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +50 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +2 -0
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -1
- package/eventcatalog/src/pages/docs/llm/llms-services.txt.ts +19 -1
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +3 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +80 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +52 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +9 -2
- package/eventcatalog/src/types/index.ts +20 -2
- package/eventcatalog/src/utils/collections/containers.ts +94 -0
- package/eventcatalog/src/utils/collections/icons.ts +3 -1
- package/eventcatalog/src/utils/collections/services.ts +15 -1
- package/eventcatalog/src/utils/collections/util.ts +4 -2
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +155 -0
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +188 -82
- package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-5GNBQGFW.js";
|
|
4
|
+
import "../chunk-AREJNU2F.js";
|
|
5
|
+
import "../chunk-LAI5QQUI.js";
|
|
6
6
|
import "../chunk-UPONRQSN.js";
|
|
7
7
|
export {
|
|
8
8
|
log_build_default as default
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
package/dist/eventcatalog.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
} from "./chunk-PLNJC7NZ.js";
|
|
7
7
|
import {
|
|
8
8
|
log_build_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-5GNBQGFW.js";
|
|
10
|
+
import "./chunk-AREJNU2F.js";
|
|
11
11
|
import {
|
|
12
12
|
catalogToAstro,
|
|
13
13
|
checkAndConvertMdToMdx
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import "./chunk-55D645EH.js";
|
|
16
16
|
import {
|
|
17
17
|
VERSION
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LAI5QQUI.js";
|
|
19
19
|
import {
|
|
20
20
|
getProjectOutDir,
|
|
21
21
|
isAuthEnabled,
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
ServerIcon,
|
|
4
|
+
EnvelopeIcon,
|
|
5
|
+
RectangleGroupIcon,
|
|
6
|
+
Squares2X2Icon,
|
|
7
|
+
QueueListIcon,
|
|
8
|
+
CircleStackIcon,
|
|
9
|
+
} from '@heroicons/react/24/outline';
|
|
10
|
+
import { buildUrlWithParams, buildUrl } from '@utils/url-builder';
|
|
4
11
|
import type { CollectionEntry } from 'astro:content';
|
|
5
12
|
import { type CollectionMessageTypes } from '@types';
|
|
6
13
|
import { getCollectionStyles } from './utils';
|
|
@@ -287,6 +294,64 @@ export default function DomainGrid({ domains, embeded }: DomainGridProps) {
|
|
|
287
294
|
</div>
|
|
288
295
|
</div>
|
|
289
296
|
</div>
|
|
297
|
+
|
|
298
|
+
{/* Container lists at the bottom */}
|
|
299
|
+
{((service.data.readsFrom && service.data.readsFrom.length > 0) ||
|
|
300
|
+
(service.data.writesTo && service.data.writesTo.length > 0)) && (
|
|
301
|
+
<div className="mt-3 pt-3 border-t border-gray-200 grid grid-cols-2 gap-4">
|
|
302
|
+
{/* Reads From */}
|
|
303
|
+
{service.data.readsFrom && service.data.readsFrom.length > 0 && (
|
|
304
|
+
<div className="space-y-2">
|
|
305
|
+
<div className="flex items-center gap-2">
|
|
306
|
+
<CircleStackIcon className="h-4 w-4 text-orange-500" />
|
|
307
|
+
<h4 className="text-xs font-semibold text-gray-700">Reads from</h4>
|
|
308
|
+
</div>
|
|
309
|
+
<div className="flex flex-wrap gap-1">
|
|
310
|
+
{service.data.readsFrom.slice(0, 3).map((container: any) => (
|
|
311
|
+
<span
|
|
312
|
+
key={container.id}
|
|
313
|
+
className="group inline-flex items-center gap-1 px-2 py-1 bg-orange-100 border border-orange-300 rounded-md text-[11px] font-medium hover:bg-orange-200 transition-colors duration-200"
|
|
314
|
+
>
|
|
315
|
+
<CircleStackIcon className="h-3 w-3 text-orange-600" />
|
|
316
|
+
<span className="text-orange-800">{container.id}</span>
|
|
317
|
+
</span>
|
|
318
|
+
))}
|
|
319
|
+
{service.data.readsFrom.length > 3 && (
|
|
320
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-500">
|
|
321
|
+
+ {service.data.readsFrom.length - 3} more
|
|
322
|
+
</span>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
)}
|
|
327
|
+
|
|
328
|
+
{/* Writes To */}
|
|
329
|
+
{service.data.writesTo && service.data.writesTo.length > 0 && (
|
|
330
|
+
<div className="space-y-2">
|
|
331
|
+
<div className="flex items-center gap-2">
|
|
332
|
+
<CircleStackIcon className="h-4 w-4 text-purple-500" />
|
|
333
|
+
<h4 className="text-xs font-semibold text-gray-700">Writes to</h4>
|
|
334
|
+
</div>
|
|
335
|
+
<div className="flex flex-wrap gap-1">
|
|
336
|
+
{service.data.writesTo.slice(0, 3).map((container: any) => (
|
|
337
|
+
<span
|
|
338
|
+
key={container.id}
|
|
339
|
+
className="group inline-flex items-center gap-1 px-2 py-1 bg-purple-100 border border-purple-300 rounded-md text-[11px] font-medium hover:bg-purple-200 transition-colors duration-200"
|
|
340
|
+
>
|
|
341
|
+
<CircleStackIcon className="h-3 w-3 text-purple-600" />
|
|
342
|
+
<span className="text-purple-800">{container.id}</span>
|
|
343
|
+
</span>
|
|
344
|
+
))}
|
|
345
|
+
{service.data.writesTo.length > 3 && (
|
|
346
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-500">
|
|
347
|
+
+ {service.data.writesTo.length - 3} more
|
|
348
|
+
</span>
|
|
349
|
+
)}
|
|
350
|
+
</div>
|
|
351
|
+
</div>
|
|
352
|
+
)}
|
|
353
|
+
</div>
|
|
354
|
+
)}
|
|
290
355
|
</div>
|
|
291
356
|
))}
|
|
292
357
|
{domain.data.domains && domain.data.domains.length > 2 && (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect } from 'react';
|
|
2
|
-
import { EnvelopeIcon, ChevronRightIcon, ServerIcon } from '@heroicons/react/24/outline';
|
|
2
|
+
import { EnvelopeIcon, ChevronRightIcon, ServerIcon, CircleStackIcon } from '@heroicons/react/24/outline';
|
|
3
3
|
import { RectangleGroupIcon } from '@heroicons/react/24/outline';
|
|
4
4
|
import { buildUrl, buildUrlWithParams } from '@utils/url-builder';
|
|
5
5
|
import type { CollectionEntry } from 'astro:content';
|
|
@@ -9,6 +9,7 @@ import { SearchBar, TypeFilters, Pagination } from './components';
|
|
|
9
9
|
|
|
10
10
|
interface MessageGridProps {
|
|
11
11
|
messages: CollectionEntry<CollectionMessageTypes>[];
|
|
12
|
+
containers?: CollectionEntry<'containers'>[];
|
|
12
13
|
embeded: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -18,7 +19,7 @@ interface GroupedMessages {
|
|
|
18
19
|
receives?: CollectionEntry<CollectionMessageTypes>[];
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export default function MessageGrid({ messages, embeded }: MessageGridProps) {
|
|
22
|
+
export default function MessageGrid({ messages, embeded, containers }: MessageGridProps) {
|
|
22
23
|
const [searchQuery, setSearchQuery] = useState('');
|
|
23
24
|
const [urlParams, setUrlParams] = useState<{
|
|
24
25
|
serviceId?: string;
|
|
@@ -130,6 +131,19 @@ export default function MessageGrid({ messages, embeded }: MessageGridProps) {
|
|
|
130
131
|
return { sends, receives };
|
|
131
132
|
}, [filteredAndSortedMessages, urlParams]);
|
|
132
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
|
+
|
|
133
147
|
const renderTypeFilters = () => {
|
|
134
148
|
return (
|
|
135
149
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-center">
|
|
@@ -373,64 +387,166 @@ export default function MessageGrid({ messages, embeded }: MessageGridProps) {
|
|
|
373
387
|
</div>
|
|
374
388
|
</div>
|
|
375
389
|
<div className="grid grid-cols-3 gap-8 relative">
|
|
376
|
-
{/* Receives
|
|
377
|
-
<div className="
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
+
)}
|
|
383
407
|
</div>
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
<div className="
|
|
388
|
-
<
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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>
|
|
393
444
|
</div>
|
|
394
445
|
)}
|
|
395
446
|
</div>
|
|
396
447
|
|
|
397
448
|
{/* Arrow from Receives to Service */}
|
|
398
|
-
<div className="absolute left-[30%] top-
|
|
449
|
+
<div className="absolute left-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
|
|
399
450
|
<div className="w-full h-[3px] bg-blue-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
|
|
400
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>
|
|
401
452
|
</div>
|
|
402
453
|
|
|
403
|
-
{/* Service Information */}
|
|
404
|
-
<div className="bg-white border-2 border-pink-100 rounded-lg p-
|
|
405
|
-
<div className="flex flex-col items-center gap-
|
|
406
|
-
<ServerIcon className="h-
|
|
407
|
-
<p className="text-
|
|
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>
|
|
408
487
|
</div>
|
|
409
488
|
</div>
|
|
410
489
|
|
|
411
490
|
{/* Arrow from Service to Sends */}
|
|
412
|
-
<div className="absolute right-[30%] top-
|
|
491
|
+
<div className="absolute right-[30%] top-[25%] -translate-y-1/2 flex items-center justify-center w-16">
|
|
413
492
|
<div className="w-full h-[3px] bg-green-200 shadow-[0_0_0_1px_rgba(0,0,0,0.1)]"></div>
|
|
414
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>
|
|
415
494
|
</div>
|
|
416
495
|
|
|
417
|
-
{/* Sends
|
|
418
|
-
<div className="
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
+
)}
|
|
424
513
|
</div>
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
<div className="
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
</
|
|
514
|
+
|
|
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>
|
|
434
550
|
</div>
|
|
435
551
|
)}
|
|
436
552
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect, memo } from 'react';
|
|
2
|
-
import { ServerIcon, ChevronRightIcon, Squares2X2Icon, QueueListIcon } from '@heroicons/react/24/outline';
|
|
2
|
+
import { ServerIcon, ChevronRightIcon, Squares2X2Icon, QueueListIcon, CircleStackIcon } from '@heroicons/react/24/outline';
|
|
3
3
|
import { RectangleGroupIcon } from '@heroicons/react/24/outline';
|
|
4
4
|
import { buildUrl, buildUrlWithParams } from '@utils/url-builder';
|
|
5
5
|
import type { CollectionEntry } from 'astro:content';
|
|
@@ -110,6 +110,66 @@ const ServiceCard = memo(({ service, urlParams, selectedTypes }: { service: any;
|
|
|
110
110
|
<MessagesContainer messages={service.data.sends} type="sends" selectedTypes={selectedTypes} />
|
|
111
111
|
</div>
|
|
112
112
|
)}
|
|
113
|
+
|
|
114
|
+
{/* Container lists at the bottom */}
|
|
115
|
+
{((service.data.readsFrom && service.data.readsFrom.length > 0) ||
|
|
116
|
+
(service.data.writesTo && service.data.writesTo.length > 0)) && (
|
|
117
|
+
<div className="mt-4 pt-4 border-t border-gray-200 grid grid-cols-2 gap-4">
|
|
118
|
+
{/* Reads From */}
|
|
119
|
+
{service.data.readsFrom && service.data.readsFrom.length > 0 && (
|
|
120
|
+
<div className="space-y-2">
|
|
121
|
+
<div className="flex items-center gap-2">
|
|
122
|
+
<CircleStackIcon className="h-4 w-4 text-orange-500" />
|
|
123
|
+
<h4 className="text-xs font-semibold text-gray-700">Reads from</h4>
|
|
124
|
+
</div>
|
|
125
|
+
<div className="flex flex-wrap gap-1">
|
|
126
|
+
{service.data.readsFrom.slice(0, 3).map((container: any) => (
|
|
127
|
+
<a
|
|
128
|
+
key={container.id}
|
|
129
|
+
href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
|
|
130
|
+
className="group inline-flex items-center gap-1 px-2 py-1 bg-orange-100 border border-orange-300 rounded-md text-[11px] font-medium hover:bg-orange-200 transition-colors duration-200"
|
|
131
|
+
>
|
|
132
|
+
<CircleStackIcon className="h-3 w-3 text-orange-600" />
|
|
133
|
+
<span className="text-orange-800">{container.data.name}</span>
|
|
134
|
+
</a>
|
|
135
|
+
))}
|
|
136
|
+
{service.data.readsFrom.length > 3 && (
|
|
137
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-500">
|
|
138
|
+
+ {service.data.readsFrom.length - 3} more
|
|
139
|
+
</span>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
)}
|
|
144
|
+
|
|
145
|
+
{/* Writes To */}
|
|
146
|
+
{service.data.writesTo && service.data.writesTo.length > 0 && (
|
|
147
|
+
<div className="space-y-2">
|
|
148
|
+
<div className="flex items-center gap-2">
|
|
149
|
+
<CircleStackIcon className="h-4 w-4 text-purple-500" />
|
|
150
|
+
<h4 className="text-xs font-semibold text-gray-700">Writes to</h4>
|
|
151
|
+
</div>
|
|
152
|
+
<div className="flex flex-wrap gap-1">
|
|
153
|
+
{service.data.writesTo.slice(0, 3).map((container: any) => (
|
|
154
|
+
<a
|
|
155
|
+
key={container.id}
|
|
156
|
+
href={buildUrl(`/docs/containers/${container.data.id}/${container.data.version}`)}
|
|
157
|
+
className="group inline-flex items-center gap-1 px-2 py-1 bg-purple-100 border border-purple-300 rounded-md text-[11px] font-medium hover:bg-purple-200 transition-colors duration-200"
|
|
158
|
+
>
|
|
159
|
+
<CircleStackIcon className="h-3 w-3 text-purple-600" />
|
|
160
|
+
<span className="text-purple-800">{container.data.name}</span>
|
|
161
|
+
</a>
|
|
162
|
+
))}
|
|
163
|
+
{service.data.writesTo.length > 3 && (
|
|
164
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-500">
|
|
165
|
+
+ {service.data.writesTo.length - 3} more
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
)}
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
113
173
|
</div>
|
|
114
174
|
</a>
|
|
115
175
|
);
|
|
@@ -184,19 +244,23 @@ const DomainSection = memo(
|
|
|
184
244
|
|
|
185
245
|
{/* Entities */}
|
|
186
246
|
{subdomain.data.entities && subdomain.data.entities.length > 0 && (
|
|
187
|
-
<div className="
|
|
188
|
-
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
<
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
247
|
+
<div className="space-y-2">
|
|
248
|
+
<div className="flex items-center gap-2">
|
|
249
|
+
<BoxIcon className="h-4 w-4 text-purple-500" />
|
|
250
|
+
<h4 className="text-xs font-semibold text-gray-700">Entities</h4>
|
|
251
|
+
</div>
|
|
252
|
+
<div className="flex flex-wrap gap-1">
|
|
253
|
+
{subdomain.data.entities.map((entity: any) => (
|
|
254
|
+
<a
|
|
255
|
+
key={entity.id}
|
|
256
|
+
href={buildUrl(`/docs/entities/${entity.id}`)}
|
|
257
|
+
className="group inline-flex items-center gap-1 px-2 py-1 bg-purple-100 border border-purple-300 rounded-md text-[11px] font-medium hover:bg-purple-200 transition-colors duration-200"
|
|
258
|
+
>
|
|
259
|
+
<BoxIcon className="h-3 w-3 text-purple-600" />
|
|
260
|
+
<span className="text-purple-800">{entity.id}</span>
|
|
261
|
+
</a>
|
|
262
|
+
))}
|
|
263
|
+
</div>
|
|
200
264
|
</div>
|
|
201
265
|
)}
|
|
202
266
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type EdgeProps, getBezierPath } from '@xyflow/react';
|
|
2
|
+
|
|
3
|
+
export default function MultilineEdgeLabel(props: EdgeProps) {
|
|
4
|
+
const {
|
|
5
|
+
id,
|
|
6
|
+
sourceX,
|
|
7
|
+
sourceY,
|
|
8
|
+
targetX,
|
|
9
|
+
targetY,
|
|
10
|
+
sourcePosition,
|
|
11
|
+
targetPosition,
|
|
12
|
+
label,
|
|
13
|
+
markerStart, // <-- forward these
|
|
14
|
+
markerEnd,
|
|
15
|
+
style,
|
|
16
|
+
selected,
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const [edgePath, labelX, labelY] = getBezierPath({
|
|
20
|
+
sourceX,
|
|
21
|
+
sourceY,
|
|
22
|
+
targetX,
|
|
23
|
+
targetY,
|
|
24
|
+
sourcePosition,
|
|
25
|
+
targetPosition,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const lines = String(label ?? '').split('\n');
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<path
|
|
33
|
+
id={id}
|
|
34
|
+
d={edgePath}
|
|
35
|
+
className={`react-flow__edge-path${selected ? ' selected' : ''}`}
|
|
36
|
+
markerStart={markerStart}
|
|
37
|
+
markerEnd={markerEnd}
|
|
38
|
+
style={style}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
{/* Optional: bigger hitbox for hover/selection */}
|
|
42
|
+
|
|
43
|
+
<text x={labelX} y={labelY} textAnchor="middle" dominantBaseline="middle" fontSize="10px" pointerEvents="none">
|
|
44
|
+
{lines.map((line, i) => (
|
|
45
|
+
<tspan key={i} x={labelX} dy={i === 0 ? 0 : '1.2em'} style={{ fontStyle: i === 0 ? 'normal' : 'italic' }}>
|
|
46
|
+
{line}
|
|
47
|
+
</tspan>
|
|
48
|
+
))}
|
|
49
|
+
</text>
|
|
50
|
+
</>
|
|
51
|
+
);
|
|
52
|
+
}
|