@eventcatalog/core 3.29.2 → 3.31.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.
Files changed (113) 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-7IGMIOQF.js} +1 -1
  6. package/dist/{chunk-EGQGCB2B.js → chunk-HVOLSUC2.js} +1 -1
  7. package/dist/{chunk-DB4IQ3GB.js → chunk-LWVHWR77.js} +1 -1
  8. package/dist/{chunk-VEUNSJ6Z.js → chunk-QIJOBQZ7.js} +1 -1
  9. package/dist/{chunk-MEJOYC5Z.js → chunk-UY5QDWK7.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 +11 -7
  19. package/eventcatalog/public/logo.png +0 -0
  20. package/eventcatalog/src/components/CopyAsMarkdown.tsx +29 -24
  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/Design/Design.astro +1 -1
  29. package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +15 -5
  30. package/eventcatalog/src/components/MDX/Tiles/Tile.astro +11 -8
  31. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +164 -53
  32. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +1 -1
  33. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +4 -4
  34. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +12 -10
  35. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +48 -77
  36. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +238 -169
  37. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +189 -230
  38. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +39 -36
  39. package/eventcatalog/src/components/Search/Search.astro +1 -1
  40. package/eventcatalog/src/components/Seo.astro +1 -1
  41. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +218 -0
  42. package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +265 -0
  43. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +371 -0
  44. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +183 -0
  45. package/eventcatalog/src/components/Settings/LogoUpload.tsx +137 -0
  46. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +91 -0
  47. package/eventcatalog/src/components/Settings/ReadOnlyBanner.tsx +18 -0
  48. package/eventcatalog/src/components/Settings/Row.tsx +59 -0
  49. package/eventcatalog/src/components/Settings/SettingsShared.tsx +176 -0
  50. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +3 -3
  51. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +233 -261
  52. package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +116 -68
  53. package/eventcatalog/src/components/Tables/Discover/FilterComponents.tsx +2 -2
  54. package/eventcatalog/src/components/Tables/Discover/columns.tsx +130 -197
  55. package/eventcatalog/src/components/Tables/Table.tsx +21 -18
  56. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +79 -131
  57. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +104 -175
  58. package/eventcatalog/src/content.config.ts +1 -1
  59. package/eventcatalog/src/enterprise/auth/error.astro +1 -1
  60. package/eventcatalog/src/enterprise/auth/login.astro +1 -1
  61. package/eventcatalog/src/enterprise/auth/middleware/middleware-auth.ts +11 -7
  62. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +97 -95
  63. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +232 -181
  64. package/eventcatalog/src/enterprise/feature.ts +2 -1
  65. package/eventcatalog/src/enterprise/fields/pages/fields.astro +10 -8
  66. package/eventcatalog/src/enterprise/integrations/eventcatalog-features.ts +0 -8
  67. package/eventcatalog/src/layouts/DirectoryLayout.astro +17 -88
  68. package/eventcatalog/src/layouts/SettingsLayout.astro +116 -0
  69. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +562 -141
  70. package/eventcatalog/src/layouts/VisualiserLayout.astro +7 -2
  71. package/eventcatalog/src/pages/_index.astro +253 -256
  72. package/eventcatalog/src/pages/api/settings/ai.ts +57 -0
  73. package/eventcatalog/src/pages/api/settings/general.ts +71 -0
  74. package/eventcatalog/src/pages/api/settings/logo.ts +113 -0
  75. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -3
  76. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +223 -73
  77. package/eventcatalog/src/pages/discover/[type]/index.astro +22 -141
  78. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +130 -30
  79. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +147 -53
  80. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +6 -2
  81. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +2 -2
  82. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +22 -19
  83. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +71 -61
  84. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +5 -1
  85. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +3 -3
  86. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +6 -32
  87. package/eventcatalog/src/pages/docs/llm/llms.txt.ts +5 -1
  88. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +11 -4
  89. package/eventcatalog/src/pages/docs/users/[id]/index.astro +12 -5
  90. package/eventcatalog/src/pages/schemas/explorer/index.astro +10 -8
  91. package/eventcatalog/src/pages/settings/assistant.astro +37 -0
  92. package/eventcatalog/src/pages/settings/billing.astro +17 -0
  93. package/eventcatalog/src/pages/settings/general.astro +32 -0
  94. package/eventcatalog/src/pages/settings/index.astro +21 -0
  95. package/eventcatalog/src/pages/settings/llm-access.astro +34 -0
  96. package/eventcatalog/src/pages/settings/mcp.astro +14 -0
  97. package/eventcatalog/src/pages/studio.astro +1 -1
  98. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +2 -7
  99. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +2 -2
  100. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +2 -7
  101. package/eventcatalog/src/styles/theme.css +95 -30
  102. package/eventcatalog/src/styles/themes/forest.css +17 -9
  103. package/eventcatalog/src/styles/themes/ocean.css +10 -2
  104. package/eventcatalog/src/styles/themes/sapphire.css +10 -2
  105. package/eventcatalog/src/styles/themes/sunset.css +25 -17
  106. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +13 -0
  107. package/eventcatalog/src/utils/eventcatalog-config/config-schema.ts +49 -0
  108. package/eventcatalog/src/utils/eventcatalog-config/config-writer.ts +149 -0
  109. package/eventcatalog/src/utils/url-builder.ts +4 -2
  110. package/package.json +7 -5
  111. package/eventcatalog/public/logo.svg +0 -14
  112. package/eventcatalog/src/enterprise/plans/index.astro +0 -319
  113. package/eventcatalog/src/pages/docs/llm/llms-services.txt.ts +0 -81
@@ -1,22 +1,12 @@
1
1
  import { createColumnHelper } from '@tanstack/react-table';
2
- import { useMemo, useState } from 'react';
3
- import {
4
- ServerIcon,
5
- BoltIcon,
6
- ChatBubbleLeftIcon,
7
- MagnifyingGlassIcon,
8
- RectangleGroupIcon,
9
- QueueListIcon,
10
- DocumentTextIcon,
11
- MapIcon,
12
- CubeIcon,
13
- } from '@heroicons/react/24/solid';
14
- import { ArrowDownIcon, ArrowUpIcon } from '@heroicons/react/24/outline';
15
- import { DatabaseIcon } from 'lucide-react';
16
- import * as Tooltip from '@radix-ui/react-tooltip';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { DocumentTextIcon, MapIcon } from '@heroicons/react/24/solid';
4
+ import { ArrowDownIcon, ArrowUpIcon, EllipsisVerticalIcon, StarIcon } from '@heroicons/react/24/outline';
17
5
  import { buildUrl } from '@utils/url-builder';
18
6
  import { getColorAndIconForCollection } from '@utils/collections/icons';
19
- import FavoriteButton from '@components/FavoriteButton';
7
+ import { isIconPath, resolveIconUrl } from '@utils/icon';
8
+ import { useStore } from '@nanostores/react';
9
+ import { favoritesStore, toggleFavorite, type FavoriteItem } from '../../../stores/favorites-store';
20
10
  import type { DiscoverTableData, CollectionType } from './DiscoverTable';
21
11
  import type { TableConfiguration } from '@types';
22
12
 
@@ -34,25 +24,6 @@ const colorClasses: Record<string, string> = {
34
24
  cyan: 'text-cyan-500',
35
25
  };
36
26
 
37
- // Reusable tooltip wrapper component
38
- const ActionTooltip = ({ children, label }: { children: React.ReactNode; label: string }) => (
39
- <Tooltip.Provider delayDuration={200}>
40
- <Tooltip.Root>
41
- <Tooltip.Trigger asChild>{children}</Tooltip.Trigger>
42
- <Tooltip.Portal>
43
- <Tooltip.Content
44
- className="bg-[rgb(var(--ec-page-text))] text-[rgb(var(--ec-page-bg))] rounded px-2 py-1 text-xs shadow-md z-50"
45
- side="top"
46
- sideOffset={5}
47
- >
48
- {label}
49
- <Tooltip.Arrow className="fill-[rgb(var(--ec-page-text))]" />
50
- </Tooltip.Content>
51
- </Tooltip.Portal>
52
- </Tooltip.Root>
53
- </Tooltip.Provider>
54
- );
55
-
56
27
  const columnHelper = createColumnHelper<DiscoverTableData>();
57
28
 
58
29
  // Badge cell component (proper React component to use hooks)
@@ -95,6 +66,119 @@ const createBadgesColumn = (tableConfiguration: TableConfiguration) =>
95
66
  },
96
67
  });
97
68
 
69
+ const ResourceNameCell = ({ item }: { item: DiscoverTableData }) => {
70
+ const isLatestVersion = item.data.version === item.data.latestVersion;
71
+ const { color, Icon } = getColorAndIconForCollection(item.collection);
72
+ const resourceIcon = item.data.icon;
73
+ const resourceIconUrl = isIconPath(resourceIcon) ? resolveIconUrl(resourceIcon) : null;
74
+
75
+ return (
76
+ <a
77
+ href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
78
+ className="group inline-flex items-center gap-2.5 hover:text-[rgb(var(--ec-accent))] transition-colors"
79
+ >
80
+ {resourceIconUrl ? (
81
+ <img src={resourceIconUrl} alt="" className="h-5 w-5 flex-shrink-0 rounded-sm object-contain" />
82
+ ) : (
83
+ <Icon className={`h-4 w-4 flex-shrink-0 ${colorClasses[color] || 'text-[rgb(var(--ec-icon-color))]'}`} />
84
+ )}
85
+ <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
86
+ {item.data.name}
87
+ </span>
88
+ {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
89
+ </a>
90
+ );
91
+ };
92
+
93
+ const RowActionsMenu = ({ item, collectionType }: { item: DiscoverTableData; collectionType: CollectionType }) => {
94
+ const [isOpen, setIsOpen] = useState(false);
95
+ const menuRef = useRef<HTMLDivElement>(null);
96
+ const favorites = useStore(favoritesStore);
97
+ const href = buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`);
98
+ const visualiserHref = buildUrl(`/visualiser/${item.collection}/${item.data.id}/${item.data.version}`);
99
+ const nodeKey = `${item.collection}-${item.data.id}-${item.data.version}`;
100
+ const badgeLabel =
101
+ collectionType === 'external-systems'
102
+ ? 'External System'
103
+ : collectionType.charAt(0).toUpperCase() + collectionType.slice(1, -1);
104
+ const isFavorite = favorites.some((fav) => fav.nodeKey === nodeKey);
105
+
106
+ useEffect(() => {
107
+ const handlePointerDown = (event: MouseEvent) => {
108
+ if (!menuRef.current?.contains(event.target as Node)) {
109
+ setIsOpen(false);
110
+ }
111
+ };
112
+
113
+ const handleEscape = (event: KeyboardEvent) => {
114
+ if (event.key === 'Escape') {
115
+ setIsOpen(false);
116
+ }
117
+ };
118
+
119
+ document.addEventListener('mousedown', handlePointerDown);
120
+ document.addEventListener('keydown', handleEscape);
121
+
122
+ return () => {
123
+ document.removeEventListener('mousedown', handlePointerDown);
124
+ document.removeEventListener('keydown', handleEscape);
125
+ };
126
+ }, []);
127
+
128
+ const handleToggleFavorite = () => {
129
+ const favoriteItem: FavoriteItem = {
130
+ nodeKey,
131
+ path: [],
132
+ title: item.data.name,
133
+ badge: badgeLabel,
134
+ href,
135
+ };
136
+ toggleFavorite(favoriteItem);
137
+ setIsOpen(false);
138
+ };
139
+
140
+ return (
141
+ <div className="relative flex justify-end" ref={menuRef}>
142
+ <button
143
+ type="button"
144
+ aria-haspopup="menu"
145
+ aria-expanded={isOpen}
146
+ onClick={() => setIsOpen((prev) => !prev)}
147
+ className="rounded-md p-1.5 text-[rgb(var(--ec-icon-color))] transition-colors hover:bg-[rgb(var(--ec-content-hover)/0.5)] hover:text-[rgb(var(--ec-page-text))]"
148
+ >
149
+ <EllipsisVerticalIcon className="h-4 w-4" />
150
+ </button>
151
+
152
+ {isOpen && (
153
+ <div className="absolute right-0 top-[calc(100%+0.35rem)] z-30 min-w-[280px] overflow-hidden rounded-xl border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-dropdown-bg))] shadow-xl">
154
+ <a
155
+ href={href}
156
+ className="flex items-center gap-2.5 px-3 py-2.5 text-xs font-medium text-[rgb(var(--ec-page-text))] transition-colors hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-accent))]"
157
+ >
158
+ <DocumentTextIcon className="h-3.5 w-3.5 text-[rgb(var(--ec-page-text-muted))]" />
159
+ View documentation
160
+ </a>
161
+ <a
162
+ href={visualiserHref}
163
+ className="flex items-center gap-2.5 px-3 py-2.5 text-xs font-medium text-[rgb(var(--ec-page-text))] transition-colors hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-accent))]"
164
+ >
165
+ <MapIcon className="h-3.5 w-3.5 text-[rgb(var(--ec-page-text-muted))]" />
166
+ View in visualiser
167
+ </a>
168
+ <button
169
+ type="button"
170
+ onClick={handleToggleFavorite}
171
+ className="flex w-full items-center gap-2.5 px-3 py-2.5 text-left text-xs font-medium text-[rgb(var(--ec-page-text))] transition-colors hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-accent))]"
172
+ >
173
+ <StarIcon className="h-3.5 w-3.5 text-[rgb(var(--ec-page-text-muted))]" />
174
+ {isFavorite ? 'Remove from favorites' : 'Add to favorites'}
175
+ </button>
176
+ </div>
177
+ )}
178
+ </div>
179
+ );
180
+ };
181
+
98
182
  // Shared actions column
99
183
  const createActionsColumn = (collectionType: CollectionType, tableConfiguration: TableConfiguration) =>
100
184
  columnHelper.accessor('data.name', {
@@ -102,38 +186,7 @@ const createActionsColumn = (collectionType: CollectionType, tableConfiguration:
102
186
  header: () => <span></span>,
103
187
  cell: (info) => {
104
188
  const item = info.row.original;
105
- const href = buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`);
106
- const nodeKey = `${item.collection}-${item.data.id}-${item.data.version}`;
107
- const badgeLabel =
108
- collectionType === 'external-systems'
109
- ? 'External System'
110
- : collectionType.charAt(0).toUpperCase() + collectionType.slice(1, -1);
111
-
112
- return (
113
- <div className="flex items-center gap-0.5">
114
- <ActionTooltip label="View documentation">
115
- <a
116
- className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent)/0.1)] rounded-md transition-colors"
117
- href={href}
118
- >
119
- <DocumentTextIcon className="w-4 h-4" />
120
- </a>
121
- </ActionTooltip>
122
- <ActionTooltip label="View in visualiser">
123
- <a
124
- className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent)/0.1)] rounded-md transition-colors"
125
- href={buildUrl(`/visualiser/${item.collection}/${item.data.id}/${item.data.version}`)}
126
- >
127
- <MapIcon className="w-4 h-4" />
128
- </a>
129
- </ActionTooltip>
130
- <ActionTooltip label="Add to favorites">
131
- <span>
132
- <FavoriteButton nodeKey={nodeKey} title={item.data.name} badge={badgeLabel} href={href} size="sm" />
133
- </span>
134
- </ActionTooltip>
135
- </div>
136
- );
189
+ return <RowActionsMenu item={item} collectionType={collectionType} />;
137
190
  },
138
191
  meta: {
139
192
  showFilter: false,
@@ -150,7 +203,7 @@ const createSummaryColumn = (tableConfiguration: TableConfiguration) =>
150
203
  const isDraft = info.row.original.data.draft;
151
204
  const displayText = `${summary || ''}${isDraft ? ' (Draft)' : ''}`;
152
205
  return (
153
- <span className="text-sm text-[rgb(var(--ec-icon-color))] line-clamp-2" title={displayText}>
206
+ <span className="text-[0.8rem] text-[rgb(var(--ec-icon-color))] line-clamp-2" title={displayText}>
154
207
  {displayText}
155
208
  </span>
156
209
  );
@@ -193,7 +246,7 @@ const CollectionListCell = ({
193
246
  <a
194
247
  key={`${item.data.id}-${index}`}
195
248
  href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
196
- className="group inline-flex items-center gap-1.5 text-xs hover:text-[rgb(var(--ec-accent))] transition-colors"
249
+ className="group inline-flex items-center gap-1.5 text-[0.8rem] text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] transition-colors"
197
250
  >
198
251
  <item.Icon className={`h-3.5 w-3.5 ${colorClasses[item.color] || 'text-gray-500'} flex-shrink-0`} />
199
252
  <span className="truncate max-w-[120px]" title={item.data.name}>
@@ -220,22 +273,7 @@ export const getEventColumns = (tableConfiguration: TableConfiguration) => [
220
273
  columnHelper.accessor('data.name', {
221
274
  id: 'name',
222
275
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Event'}</span>,
223
- cell: (info) => {
224
- const item = info.row.original;
225
- const isLatestVersion = item.data.version === item.data.latestVersion;
226
- return (
227
- <a
228
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
229
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
230
- >
231
- <BoltIcon className="h-4 w-4 text-orange-500 flex-shrink-0" />
232
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
233
- {item.data.name}
234
- </span>
235
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
236
- </a>
237
- );
238
- },
276
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
239
277
  meta: {
240
278
  filterVariant: 'name',
241
279
  },
@@ -268,22 +306,7 @@ export const getCommandColumns = (tableConfiguration: TableConfiguration) => [
268
306
  columnHelper.accessor('data.name', {
269
307
  id: 'name',
270
308
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Command'}</span>,
271
- cell: (info) => {
272
- const item = info.row.original;
273
- const isLatestVersion = item.data.version === item.data.latestVersion;
274
- return (
275
- <a
276
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
277
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
278
- >
279
- <ChatBubbleLeftIcon className="h-4 w-4 text-blue-500 flex-shrink-0" />
280
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
281
- {item.data.name}
282
- </span>
283
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
284
- </a>
285
- );
286
- },
309
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
287
310
  meta: {
288
311
  filterVariant: 'name',
289
312
  },
@@ -316,22 +339,7 @@ export const getQueryColumns = (tableConfiguration: TableConfiguration) => [
316
339
  columnHelper.accessor('data.name', {
317
340
  id: 'name',
318
341
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Query'}</span>,
319
- cell: (info) => {
320
- const item = info.row.original;
321
- const isLatestVersion = item.data.version === item.data.latestVersion;
322
- return (
323
- <a
324
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
325
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
326
- >
327
- <MagnifyingGlassIcon className="h-4 w-4 text-green-500 flex-shrink-0" />
328
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
329
- {item.data.name}
330
- </span>
331
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
332
- </a>
333
- );
334
- },
342
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
335
343
  meta: {
336
344
  filterVariant: 'name',
337
345
  },
@@ -364,22 +372,7 @@ export const getServiceColumns = (tableConfiguration: TableConfiguration) => [
364
372
  columnHelper.accessor('data.name', {
365
373
  id: 'name',
366
374
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Service'}</span>,
367
- cell: (info) => {
368
- const item = info.row.original;
369
- const isLatestVersion = item.data.version === item.data.latestVersion;
370
- return (
371
- <a
372
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
373
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
374
- >
375
- <ServerIcon className="h-4 w-4 text-pink-500 flex-shrink-0" />
376
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
377
- {item.data.name}
378
- </span>
379
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
380
- </a>
381
- );
382
- },
375
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
383
376
  meta: {
384
377
  filterVariant: 'name',
385
378
  },
@@ -422,22 +415,7 @@ export const getDomainColumns = (tableConfiguration: TableConfiguration) => [
422
415
  columnHelper.accessor('data.name', {
423
416
  id: 'name',
424
417
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Domain'}</span>,
425
- cell: (info) => {
426
- const item = info.row.original;
427
- const isLatestVersion = item.data.version === item.data.latestVersion;
428
- return (
429
- <a
430
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
431
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
432
- >
433
- <RectangleGroupIcon className="h-4 w-4 text-yellow-500 flex-shrink-0" />
434
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
435
- {item.data.name}
436
- </span>
437
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
438
- </a>
439
- );
440
- },
418
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
441
419
  meta: {
442
420
  filterVariant: 'name',
443
421
  },
@@ -462,22 +440,7 @@ export const getFlowColumns = (tableConfiguration: TableConfiguration) => [
462
440
  columnHelper.accessor('data.name', {
463
441
  id: 'name',
464
442
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Flow'}</span>,
465
- cell: (info) => {
466
- const item = info.row.original;
467
- const isLatestVersion = item.data.version === item.data.latestVersion;
468
- return (
469
- <a
470
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
471
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
472
- >
473
- <QueueListIcon className="h-4 w-4 text-teal-500 flex-shrink-0" />
474
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
475
- {item.data.name}
476
- </span>
477
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
478
- </a>
479
- );
480
- },
443
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
481
444
  meta: {
482
445
  filterVariant: 'name',
483
446
  },
@@ -494,22 +457,7 @@ export const getContainerColumns = (tableConfiguration: TableConfiguration) => [
494
457
  columnHelper.accessor('data.name', {
495
458
  id: 'name',
496
459
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Data'}</span>,
497
- cell: (info) => {
498
- const item = info.row.original;
499
- const isLatestVersion = item.data.version === item.data.latestVersion;
500
- return (
501
- <a
502
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
503
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
504
- >
505
- <DatabaseIcon className="h-4 w-4 text-blue-500 flex-shrink-0" />
506
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
507
- {item.data.name}
508
- </span>
509
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
510
- </a>
511
- );
512
- },
460
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
513
461
  meta: {
514
462
  filterVariant: 'name',
515
463
  },
@@ -552,22 +500,7 @@ export const getDataProductColumns = (tableConfiguration: TableConfiguration) =>
552
500
  columnHelper.accessor('data.name', {
553
501
  id: 'name',
554
502
  header: () => <span>{tableConfiguration?.columns?.name?.label || 'Data Product'}</span>,
555
- cell: (info) => {
556
- const item = info.row.original;
557
- const isLatestVersion = item.data.version === item.data.latestVersion;
558
- return (
559
- <a
560
- href={buildUrl(`/docs/${item.collection}/${item.data.id}/${item.data.version}`)}
561
- className="group inline-flex items-center gap-2 hover:text-[rgb(var(--ec-accent))] transition-colors"
562
- >
563
- <CubeIcon className="h-4 w-4 text-cyan-500 flex-shrink-0" />
564
- <span className="text-sm font-semibold text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent))]">
565
- {item.data.name}
566
- </span>
567
- {!isLatestVersion && <span className="text-xs text-[rgb(var(--ec-icon-color))]">v{item.data.version}</span>}
568
- </a>
569
- );
570
- },
503
+ cell: (info) => <ResourceNameCell item={info.row.original} />,
571
504
  meta: {
572
505
  filterVariant: 'name',
573
506
  },
@@ -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}>