@eventcatalog/core 3.29.2 → 3.30.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 (79) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-36IA4UE4.js → chunk-6UG4JMUV.js} +1 -1
  6. package/dist/{chunk-MEJOYC5Z.js → chunk-ATRBVTJ6.js} +1 -1
  7. package/dist/{chunk-VEUNSJ6Z.js → chunk-MVZKHUX2.js} +1 -1
  8. package/dist/{chunk-DB4IQ3GB.js → chunk-RRBDF4MM.js} +1 -1
  9. package/dist/{chunk-EGQGCB2B.js → chunk-Z26P4PCB.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +5 -5
  14. package/dist/generate.cjs +1 -1
  15. package/dist/generate.js +3 -3
  16. package/dist/utils/cli-logger.cjs +1 -1
  17. package/dist/utils/cli-logger.js +2 -2
  18. package/eventcatalog/astro.config.mjs +1 -1
  19. package/eventcatalog/public/logo.png +0 -0
  20. package/eventcatalog/src/components/CopyAsMarkdown.tsx +2 -2
  21. package/eventcatalog/src/components/EnvironmentDropdown.tsx +33 -21
  22. package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +3 -53
  23. package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +144 -91
  24. package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +112 -109
  25. package/eventcatalog/src/components/Header.astro +9 -19
  26. package/eventcatalog/src/components/MDX/Accordion/Accordion.tsx +12 -14
  27. package/eventcatalog/src/components/MDX/Accordion/AccordionGroup.astro +11 -3
  28. package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +15 -5
  29. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +164 -53
  30. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +1 -1
  31. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +4 -4
  32. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +12 -10
  33. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +48 -77
  34. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +238 -169
  35. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +189 -230
  36. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +39 -36
  37. package/eventcatalog/src/components/Search/Search.astro +1 -1
  38. package/eventcatalog/src/components/Seo.astro +1 -1
  39. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +3 -3
  40. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +229 -256
  41. package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +78 -59
  42. package/eventcatalog/src/components/Tables/Discover/columns.tsx +130 -197
  43. package/eventcatalog/src/components/Tables/Table.tsx +21 -18
  44. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +79 -131
  45. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +104 -175
  46. package/eventcatalog/src/enterprise/auth/error.astro +1 -1
  47. package/eventcatalog/src/enterprise/auth/login.astro +1 -1
  48. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +95 -93
  49. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +174 -136
  50. package/eventcatalog/src/enterprise/fields/pages/fields.astro +10 -8
  51. package/eventcatalog/src/enterprise/integrations/eventcatalog-features.ts +0 -8
  52. package/eventcatalog/src/layouts/DirectoryLayout.astro +17 -88
  53. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +528 -146
  54. package/eventcatalog/src/layouts/VisualiserLayout.astro +7 -2
  55. package/eventcatalog/src/pages/_index.astro +5 -3
  56. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -3
  57. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +223 -73
  58. package/eventcatalog/src/pages/discover/[type]/index.astro +22 -141
  59. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +129 -29
  60. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +129 -29
  61. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +6 -2
  62. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +2 -2
  63. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +21 -18
  64. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +33 -32
  65. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +5 -1
  66. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +2 -2
  67. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +4 -6
  68. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +11 -4
  69. package/eventcatalog/src/pages/docs/users/[id]/index.astro +11 -4
  70. package/eventcatalog/src/pages/schemas/explorer/index.astro +10 -8
  71. package/eventcatalog/src/pages/studio.astro +1 -1
  72. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +2 -7
  73. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +2 -2
  74. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +2 -7
  75. package/eventcatalog/src/styles/theme.css +68 -12
  76. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +13 -0
  77. package/package.json +1 -1
  78. package/eventcatalog/public/logo.svg +0 -14
  79. package/eventcatalog/src/enterprise/plans/index.astro +0 -319
@@ -246,15 +246,15 @@ export const Table = <T extends TCollectionTypes>({
246
246
 
247
247
  return (
248
248
  <div>
249
- <div className="rounded-lg border border-[rgb(var(--ec-page-border))] overflow-hidden">
250
- <table className="min-w-full divide-y divide-[rgb(var(--ec-page-border))]">
251
- <thead className="bg-[rgb(var(--ec-content-hover))] sticky top-0 z-10">
249
+ <div className="overflow-hidden rounded-xl border border-[rgb(var(--ec-page-border)/0.72)] dark:border-white/10 bg-[rgb(var(--ec-dropdown-bg)/0.66)]">
250
+ <table className="min-w-full divide-y divide-[rgb(var(--ec-page-border)/0.62)] dark:divide-white/10">
251
+ <thead className="sticky top-0 z-10 bg-[rgb(var(--ec-content-hover)/0.45)]">
252
252
  {table.getHeaderGroups().map((headerGroup, index) => (
253
253
  <tr key={`${headerGroup}-${index}`}>
254
254
  {headerGroup.headers.map((header) => (
255
255
  <th
256
256
  key={`${header.id}`}
257
- className="px-4 py-3 text-left text-xs font-semibold text-[rgb(var(--ec-page-text-muted))] uppercase tracking-wider"
257
+ className="px-4 py-2.5 text-left text-[11px] font-medium text-[rgb(var(--ec-page-text-muted))] uppercase tracking-wider"
258
258
  >
259
259
  <div className="flex flex-col gap-2">
260
260
  <div>{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}</div>
@@ -269,10 +269,13 @@ export const Table = <T extends TCollectionTypes>({
269
269
  ))}
270
270
  </thead>
271
271
 
272
- <tbody className="bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] divide-y divide-[rgb(var(--ec-page-border))]">
272
+ <tbody className="divide-y divide-[rgb(var(--ec-page-border)/0.5)] dark:divide-white/8">
273
273
  {hasResults ? (
274
274
  table.getRowModel().rows.map((row, index) => (
275
- <tr key={`${row.id}-${index}`} className="hover:bg-[rgb(var(--ec-content-hover))] transition-colors">
275
+ <tr
276
+ key={`${row.id}-${index}`}
277
+ className="group bg-transparent transition-colors hover:bg-[rgb(var(--ec-content-hover)/0.38)]"
278
+ >
276
279
  {row.getVisibleCells().map((cell) => (
277
280
  <td
278
281
  key={cell.id}
@@ -299,8 +302,8 @@ export const Table = <T extends TCollectionTypes>({
299
302
  </div>
300
303
 
301
304
  {/* Pagination */}
302
- <div className="flex items-center justify-between px-1 py-4">
303
- <div className="text-sm text-[rgb(var(--ec-page-text-muted))]">
305
+ <div className="flex items-center justify-between border-t border-[rgb(var(--ec-page-border))] px-1 py-3">
306
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))]">
304
307
  {totalResults > 0 && (
305
308
  <span>
306
309
  Showing <span className="font-medium text-[rgb(var(--ec-page-text))]">{table.getRowModel().rows.length}</span> of{' '}
@@ -309,9 +312,9 @@ export const Table = <T extends TCollectionTypes>({
309
312
  )}
310
313
  </div>
311
314
  <div className="flex items-center gap-2">
312
- <div className="flex items-center rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))]">
315
+ <div className="flex items-center rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.35)]">
313
316
  <button
314
- className="p-2 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors rounded-l-lg"
317
+ className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors rounded-l-lg"
315
318
  onClick={() => table.setPageIndex(0)}
316
319
  disabled={!table.getCanPreviousPage()}
317
320
  title="First page"
@@ -319,20 +322,20 @@ export const Table = <T extends TCollectionTypes>({
319
322
  <ChevronsLeft className="w-4 h-4" />
320
323
  </button>
321
324
  <button
322
- className="p-2 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors border-l border-[rgb(var(--ec-page-border))]"
325
+ className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors border-l border-[rgb(var(--ec-page-border))]"
323
326
  onClick={() => table.previousPage()}
324
327
  disabled={!table.getCanPreviousPage()}
325
328
  title="Previous page"
326
329
  >
327
330
  <ChevronLeft className="w-4 h-4" />
328
331
  </button>
329
- <span className="px-3 py-2 text-sm text-[rgb(var(--ec-page-text-muted))] border-l border-r border-[rgb(var(--ec-page-border))] min-w-[100px] text-center">
330
- Page{' '}
331
- <span className="font-medium text-[rgb(var(--ec-page-text))]">{table.getState().pagination.pageIndex + 1}</span> of{' '}
332
- <span className="font-medium text-[rgb(var(--ec-page-text))]">{table.getPageCount() || 1}</span>
332
+ <span className="min-w-[72px] px-3 py-1.5 text-center text-xs tabular-nums text-[rgb(var(--ec-page-text-muted))] border-l border-r border-[rgb(var(--ec-page-border))]">
333
+ <span className="font-medium text-[rgb(var(--ec-page-text))]">{table.getState().pagination.pageIndex + 1}</span>
334
+ {' / '}
335
+ <span>{table.getPageCount() || 1}</span>
333
336
  </span>
334
337
  <button
335
- className="p-2 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors border-r border-[rgb(var(--ec-page-border))]"
338
+ className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors border-r border-[rgb(var(--ec-page-border))]"
336
339
  onClick={() => table.nextPage()}
337
340
  disabled={!table.getCanNextPage()}
338
341
  title="Next page"
@@ -340,7 +343,7 @@ export const Table = <T extends TCollectionTypes>({
340
343
  <ChevronRight className="w-4 h-4" />
341
344
  </button>
342
345
  <button
343
- className="p-2 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors rounded-r-lg"
346
+ className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-colors rounded-r-lg"
344
347
  onClick={() => table.setPageIndex(table.getPageCount() - 1)}
345
348
  disabled={!table.getCanNextPage()}
346
349
  title="Last page"
@@ -353,7 +356,7 @@ export const Table = <T extends TCollectionTypes>({
353
356
  onChange={(e) => {
354
357
  table.setPageSize(Number(e.target.value));
355
358
  }}
356
- className="px-3 py-2 text-sm text-[rgb(var(--ec-page-text-muted))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-lg hover:border-[rgb(var(--ec-icon-color))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent)/0.2)] transition-colors"
359
+ className="rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.35)] px-3 py-1.5 text-xs text-[rgb(var(--ec-page-text-muted))] hover:border-[rgb(var(--ec-icon-color))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent)/0.2)] transition-colors"
357
360
  >
358
361
  {[10, 20, 30, 40, 50].map((pageSize) => (
359
362
  <option key={pageSize} value={pageSize}>
@@ -4,17 +4,69 @@ import { filterByName, filterCollectionByName } from '../filters/custom-filters'
4
4
  import { buildUrl } from '@utils/url-builder';
5
5
  import type { TData } from '../Table';
6
6
  import type { CollectionUserTypes } from '@types';
7
- import type { CollectionEntry } from 'astro:content';
8
- import { ServerIcon, BoltIcon, ChatBubbleLeftIcon, MagnifyingGlassIcon } from '@heroicons/react/24/solid';
9
- import { Users } from 'lucide-react';
10
7
  import type { TableConfiguration } from '@types';
8
+ import { getColorAndIconForCollection } from '@utils/collections/icons';
11
9
  const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
12
10
 
13
- const getMessageIconAndColor = (collection: string) => {
14
- if (collection === 'events') return { Icon: BoltIcon, color: 'orange' };
15
- if (collection === 'commands') return { Icon: ChatBubbleLeftIcon, color: 'blue' };
16
- if (collection === 'queries') return { Icon: MagnifyingGlassIcon, color: 'green' };
17
- return { Icon: ChatBubbleLeftIcon, color: 'gray' };
11
+ const colorClasses: Record<string, string> = {
12
+ orange: 'text-orange-500',
13
+ blue: 'text-blue-500',
14
+ green: 'text-green-500',
15
+ pink: 'text-pink-500',
16
+ yellow: 'text-yellow-500',
17
+ teal: 'text-teal-500',
18
+ purple: 'text-purple-500',
19
+ red: 'text-red-500',
20
+ gray: 'text-gray-500',
21
+ cyan: 'text-cyan-500',
22
+ };
23
+
24
+ const CollectionListCell = ({
25
+ items,
26
+ emptyText,
27
+ }: {
28
+ items: Array<{ collection: string; data: { id: string; name: string; version?: string } }> | undefined;
29
+ emptyText: string;
30
+ }) => {
31
+ const [isExpanded, setIsExpanded] = useState(false);
32
+
33
+ if (!items || items.length === 0) {
34
+ return <span className="text-xs text-[rgb(var(--ec-icon-color))]">{emptyText}</span>;
35
+ }
36
+
37
+ const visibleItems = isExpanded ? items : items.slice(0, 4);
38
+ const hiddenCount = items.length - 4;
39
+
40
+ return (
41
+ <div className="flex flex-col gap-1">
42
+ {visibleItems.map((item, index) => {
43
+ const { color, Icon } = getColorAndIconForCollection(item.collection);
44
+ const href = buildUrl(`/docs/${item.collection}/${item.data.id}${item.data.version ? `/${item.data.version}` : ''}`);
45
+
46
+ return (
47
+ <a
48
+ key={`${item.data.id}-${index}`}
49
+ href={href}
50
+ className="group inline-flex items-center gap-1.5 text-[0.8rem] text-[rgb(var(--ec-icon-color))] transition-colors hover:text-[rgb(var(--ec-accent))]"
51
+ >
52
+ <Icon className={`h-3.5 w-3.5 flex-shrink-0 ${colorClasses[color] || 'text-[rgb(var(--ec-icon-color))]'}`} />
53
+ <span className="max-w-[140px] truncate" title={item.data.name}>
54
+ {item.data.name}
55
+ </span>
56
+ {item.data.version && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
57
+ </a>
58
+ );
59
+ })}
60
+ {hiddenCount > 0 && (
61
+ <button
62
+ onClick={() => setIsExpanded(!isExpanded)}
63
+ className="text-xs text-[rgb(var(--ec-accent))] hover:underline text-left"
64
+ >
65
+ {isExpanded ? 'Show less' : `+${hiddenCount} more`}
66
+ </button>
67
+ )}
68
+ </div>
69
+ );
18
70
  };
19
71
 
20
72
  export const columns = (tableConfiguration: TableConfiguration) => [
@@ -24,15 +76,11 @@ export const columns = (tableConfiguration: TableConfiguration) => [
24
76
  cell: (info) => {
25
77
  const team = info.row.original;
26
78
  return (
27
- <a href={buildUrl(`/docs/${team.collection}/${team.data.id}`)} className="group inline-flex items-center">
28
- <span className="inline-flex items-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] hover:border-pink-400 dark:hover:border-pink-500 hover:bg-pink-50 dark:hover:bg-pink-500/10 transition-colors">
29
- <span className="flex items-center justify-center w-6 h-6 bg-pink-500 rounded-l-md">
30
- <Users className="h-3 w-3 text-white" />
31
- </span>
32
- <span className="px-2 py-1 text-xs text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-page-text))]">
33
- {team.data.name}
34
- </span>
35
- </span>
79
+ <a
80
+ href={buildUrl(`/docs/${team.collection}/${team.data.id}`)}
81
+ className="group inline-flex items-center text-sm font-semibold text-[rgb(var(--ec-page-text))] transition-colors hover:text-[rgb(var(--ec-accent))]"
82
+ >
83
+ <span>{team.data.name}</span>
36
84
  </a>
37
85
  );
38
86
  },
@@ -56,57 +104,14 @@ export const columns = (tableConfiguration: TableConfiguration) => [
56
104
  meta: {
57
105
  showFilter: false,
58
106
  },
59
- cell: (info) => {
60
- const messages = info.getValue() as Array<
61
- CollectionEntry<'events'> | CollectionEntry<'commands'> | CollectionEntry<'queries'>
62
- >;
63
- const [isExpanded, setIsExpanded] = useState(false);
64
-
65
- if (messages?.length === 0 || !messages)
66
- return (
67
- <span className="inline-flex items-center px-2 py-1 text-xs text-[rgb(var(--ec-icon-color))] bg-[rgb(var(--ec-content-hover))] rounded-md border border-[rgb(var(--ec-page-border))]">
68
- No messages
69
- </span>
70
- );
71
-
72
- const visibleItems = isExpanded ? messages : messages.slice(0, 4);
73
- const hiddenCount = messages.length - 4;
74
-
75
- return (
76
- <div className="flex flex-col gap-1.5">
77
- {visibleItems.map((message, index: number) => {
78
- const { Icon, color } = getMessageIconAndColor(message.collection);
79
- return (
80
- <a
81
- key={`${message.data.id}-${index}`}
82
- href={buildUrl(`/docs/${message.collection}/${message.data.id}/${message.data.version}`)}
83
- className="group inline-flex items-center"
84
- >
85
- <span
86
- className={`inline-flex items-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] hover:border-${color}-400 dark:hover:border-${color}-500 hover:bg-${color}-50 dark:hover:bg-${color}-500/10 transition-colors`}
87
- >
88
- <span className={`flex items-center justify-center w-6 h-6 bg-${color}-500 rounded-l-md`}>
89
- <Icon className="h-3 w-3 text-white" />
90
- </span>
91
- <span className="px-2 py-1 text-xs text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-page-text))]">
92
- {message.data.name}
93
- <span className="text-[rgb(var(--ec-icon-color))] ml-1">v{message.data.version}</span>
94
- </span>
95
- </span>
96
- </a>
97
- );
98
- })}
99
- {hiddenCount > 0 && (
100
- <button
101
- onClick={() => setIsExpanded(!isExpanded)}
102
- className="text-xs text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] text-left"
103
- >
104
- {isExpanded ? 'Show less' : `+${hiddenCount} more`}
105
- </button>
106
- )}
107
- </div>
108
- );
109
- },
107
+ cell: (info) => (
108
+ <CollectionListCell
109
+ items={
110
+ info.getValue() as Array<{ collection: string; data: { id: string; name: string; version?: string } }> | undefined
111
+ }
112
+ emptyText="No messages"
113
+ />
114
+ ),
110
115
  }
111
116
  ),
112
117
 
@@ -117,70 +122,13 @@ export const columns = (tableConfiguration: TableConfiguration) => [
117
122
  filterVariant: 'collection',
118
123
  collectionFilterKey: 'ownedServices',
119
124
  },
120
- cell: (info) => {
121
- const services = info.getValue();
122
- const [isExpanded, setIsExpanded] = useState(false);
123
-
124
- if (services?.length === 0 || !services)
125
- return (
126
- <span className="inline-flex items-center px-2 py-1 text-xs text-[rgb(var(--ec-icon-color))] bg-[rgb(var(--ec-content-hover))] rounded-md border border-[rgb(var(--ec-page-border))]">
127
- No services
128
- </span>
129
- );
130
-
131
- const visibleItems = isExpanded ? services : services.slice(0, 4);
132
- const hiddenCount = services.length - 4;
133
-
134
- return (
135
- <div className="flex flex-col gap-1.5">
136
- {visibleItems.map((service: CollectionEntry<'services'>, index: number) => (
137
- <a
138
- key={`${service.data.id}-${index}`}
139
- href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.version}`)}
140
- className="group inline-flex items-center"
141
- >
142
- <span className="inline-flex items-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] hover:border-pink-400 dark:hover:border-pink-500 hover:bg-pink-50 dark:hover:bg-pink-500/10 transition-colors">
143
- <span className="flex items-center justify-center w-6 h-6 bg-pink-500 rounded-l-md">
144
- <ServerIcon className="h-3 w-3 text-white" />
145
- </span>
146
- <span className="px-2 py-1 text-xs text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-page-text))]">
147
- {service.data.name}
148
- <span className="text-[rgb(var(--ec-icon-color))] ml-1">v{service.data.version}</span>
149
- </span>
150
- </span>
151
- </a>
152
- ))}
153
- {hiddenCount > 0 && (
154
- <button
155
- onClick={() => setIsExpanded(!isExpanded)}
156
- className="text-xs text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] text-left"
157
- >
158
- {isExpanded ? 'Show less' : `+${hiddenCount} more`}
159
- </button>
160
- )}
161
- </div>
162
- );
163
- },
125
+ cell: (info) => (
126
+ <CollectionListCell
127
+ items={info.getValue() as Array<{ collection: string; data: { id: string; name: string; version?: string } }> | undefined}
128
+ emptyText="No services"
129
+ />
130
+ ),
164
131
  footer: (info) => info.column.id,
165
132
  filterFn: filterCollectionByName('ownedServices'),
166
133
  }),
167
-
168
- columnHelper.accessor('data.name', {
169
- header: () => <span>{tableConfiguration.columns?.actions?.label || 'Actions'}</span>,
170
- cell: (info) => {
171
- const item = info.row.original;
172
- return (
173
- <a
174
- className="inline-flex items-center px-2.5 py-1 text-xs font-medium text-[rgb(var(--ec-page-text-muted))] bg-[rgb(var(--ec-content-hover))] border border-[rgb(var(--ec-page-border))] rounded-md hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))] transition-colors whitespace-nowrap"
175
- href={buildUrl(`/docs/${item.collection}/${item.data.id}`)}
176
- >
177
- View team
178
- </a>
179
- );
180
- },
181
- id: 'actions',
182
- meta: {
183
- showFilter: false,
184
- },
185
- }),
186
134
  ];