@eventcatalog/core 3.42.0 → 3.43.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 (52) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/count-resources.cjs +1 -0
  4. package/dist/analytics/count-resources.js +1 -1
  5. package/dist/analytics/log-build.cjs +3 -1
  6. package/dist/analytics/log-build.js +4 -4
  7. package/dist/{chunk-6FAGUEM4.js → chunk-2EI3M7OO.js} +1 -1
  8. package/dist/{chunk-UQIDXF2V.js → chunk-7M5IQL3J.js} +1 -1
  9. package/dist/{chunk-3DVHEVHQ.js → chunk-DAOXTQVS.js} +1 -0
  10. package/dist/{chunk-VPZ77Y6E.js → chunk-KY74BE42.js} +1 -1
  11. package/dist/{chunk-L66TCSM7.js → chunk-QV2PKXZM.js} +3 -2
  12. package/dist/{chunk-QMORF42U.js → chunk-ZONBICNH.js} +8 -0
  13. package/dist/{chunk-KE6YTTLB.js → chunk-ZQHBDPIY.js} +1 -1
  14. package/dist/constants.cjs +1 -1
  15. package/dist/constants.js +1 -1
  16. package/dist/eventcatalog.cjs +11 -1
  17. package/dist/eventcatalog.js +7 -7
  18. package/dist/generate.cjs +1 -1
  19. package/dist/generate.js +3 -3
  20. package/dist/search-indexer.cjs +8 -0
  21. package/dist/search-indexer.js +1 -1
  22. package/dist/utils/cli-logger.cjs +1 -1
  23. package/dist/utils/cli-logger.js +2 -2
  24. package/eventcatalog/src/components/MDX/Attachments.astro +3 -3
  25. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +11 -2
  26. package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +100 -2
  27. package/eventcatalog/src/components/Tables/Discover/columns.tsx +53 -1
  28. package/eventcatalog/src/content.config.ts +61 -0
  29. package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +19 -0
  30. package/eventcatalog/src/layouts/DiscoverLayout.astro +12 -1
  31. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +98 -46
  32. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -0
  33. package/eventcatalog/src/pages/discover/[type]/index.astro +17 -0
  34. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -0
  35. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +68 -2
  36. package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +1 -0
  37. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +26 -1
  38. package/eventcatalog/src/pages/docs/users/[id]/index.astro +26 -1
  39. package/eventcatalog/src/stores/sidebar-store/builders/adr.ts +150 -0
  40. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +2 -0
  41. package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +50 -0
  42. package/eventcatalog/src/stores/sidebar-store/state.ts +209 -68
  43. package/eventcatalog/src/types/index.ts +2 -0
  44. package/eventcatalog/src/utils/collection-colors.ts +2 -0
  45. package/eventcatalog/src/utils/collections/adr-constants.ts +53 -0
  46. package/eventcatalog/src/utils/collections/adrs.ts +146 -0
  47. package/eventcatalog/src/utils/collections/icons.ts +2 -0
  48. package/eventcatalog/src/utils/collections/teams.ts +6 -1
  49. package/eventcatalog/src/utils/collections/users.ts +17 -10
  50. package/eventcatalog/src/utils/collections/util.ts +2 -0
  51. package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
  52. package/package.json +3 -3
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(analytics_exports);
36
36
  var import_os = __toESM(require("os"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.42.0";
39
+ var version = "3.43.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-6FAGUEM4.js";
4
- import "../chunk-VPZ77Y6E.js";
3
+ } from "../chunk-2EI3M7OO.js";
4
+ import "../chunk-KY74BE42.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -26,6 +26,7 @@ __export(count_resources_exports, {
26
26
  module.exports = __toCommonJS(count_resources_exports);
27
27
  var import_glob = require("glob");
28
28
  var RESOURCE_PATTERNS = {
29
+ adrs: ["**/adrs/*/index.@(md|mdx)"],
29
30
  agents: ["**/agents/*/index.@(md|mdx)"],
30
31
  events: ["**/events/*/index.@(md|mdx)"],
31
32
  commands: ["**/commands/*/index.@(md|mdx)"],
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  countResources,
3
3
  serializeCounts
4
- } from "../chunk-3DVHEVHQ.js";
4
+ } from "../chunk-DAOXTQVS.js";
5
5
  export {
6
6
  countResources,
7
7
  serializeCounts
@@ -110,7 +110,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
110
110
  var import_os = __toESM(require("os"), 1);
111
111
 
112
112
  // package.json
113
- var version = "3.42.0";
113
+ var version = "3.43.0";
114
114
 
115
115
  // src/constants.ts
116
116
  var VERSION = version;
@@ -149,6 +149,7 @@ async function raiseEvent(eventData) {
149
149
  // src/analytics/count-resources.js
150
150
  var import_glob = require("glob");
151
151
  var RESOURCE_PATTERNS = {
152
+ adrs: ["**/adrs/*/index.@(md|mdx)"],
152
153
  agents: ["**/agents/*/index.@(md|mdx)"],
153
154
  events: ["**/events/*/index.@(md|mdx)"],
154
155
  commands: ["**/commands/*/index.@(md|mdx)"],
@@ -196,6 +197,7 @@ var getFeatures = async (configFile) => {
196
197
  };
197
198
  var CLOUD_ANALYTICS_ENDPOINT = "https://api.ecingest.dev/v1/analytics/ingest";
198
199
  var toCloudResourceCounts = (counts) => ({
200
+ adrs: counts.adrs || 0,
199
201
  agents: counts.agents || 0,
200
202
  domains: counts.domains || 0,
201
203
  services: counts.services || 0,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-L66TCSM7.js";
4
- import "../chunk-6FAGUEM4.js";
5
- import "../chunk-3DVHEVHQ.js";
6
- import "../chunk-VPZ77Y6E.js";
3
+ } from "../chunk-QV2PKXZM.js";
4
+ import "../chunk-2EI3M7OO.js";
5
+ import "../chunk-DAOXTQVS.js";
6
+ import "../chunk-KY74BE42.js";
7
7
  import "../chunk-5T63CXKU.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-VPZ77Y6E.js";
3
+ } from "./chunk-KY74BE42.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import os from "os";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-VPZ77Y6E.js";
3
+ } from "./chunk-KY74BE42.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,7 @@
1
1
  // src/analytics/count-resources.js
2
2
  import { glob } from "glob";
3
3
  var RESOURCE_PATTERNS = {
4
+ adrs: ["**/adrs/*/index.@(md|mdx)"],
4
5
  agents: ["**/agents/*/index.@(md|mdx)"],
5
6
  events: ["**/events/*/index.@(md|mdx)"],
6
7
  commands: ["**/commands/*/index.@(md|mdx)"],
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "3.42.0";
2
+ var version = "3.43.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-6FAGUEM4.js";
3
+ } from "./chunk-2EI3M7OO.js";
4
4
  import {
5
5
  countResources,
6
6
  serializeCounts
7
- } from "./chunk-3DVHEVHQ.js";
7
+ } from "./chunk-DAOXTQVS.js";
8
8
  import {
9
9
  getEventCatalogConfigFile,
10
10
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -21,6 +21,7 @@ var getFeatures = async (configFile) => {
21
21
  };
22
22
  var CLOUD_ANALYTICS_ENDPOINT = "https://api.ecingest.dev/v1/analytics/ingest";
23
23
  var toCloudResourceCounts = (counts) => ({
24
+ adrs: counts.adrs || 0,
24
25
  agents: counts.agents || 0,
25
26
  domains: counts.domains || 0,
26
27
  services: counts.services || 0,
@@ -4,6 +4,7 @@ import path from "path";
4
4
  import { glob } from "glob";
5
5
  import matter from "gray-matter";
6
6
  var RESOURCE_COLLECTIONS = {
7
+ adrs: { docsPath: "adrs", type: "Architecture Decision" },
7
8
  agents: { docsPath: "agents", type: "Agent" },
8
9
  channels: { docsPath: "channels", type: "Channel" },
9
10
  commands: { docsPath: "commands", type: "Command" },
@@ -68,6 +69,9 @@ var findResourceSegment = (segments) => {
68
69
  let match = null;
69
70
  for (let index = 0; index < segments.length - 1; index++) {
70
71
  const segment = segments[index];
72
+ if (segments[index - 1] === "docs") {
73
+ continue;
74
+ }
71
75
  if (RESOURCE_COLLECTIONS[segment] && segments[index + 1]) {
72
76
  match = { index, segment };
73
77
  }
@@ -234,6 +238,10 @@ var collectSearchRecords = async ({
234
238
  summary: baseRecord.summary,
235
239
  version: baseRecord.version,
236
240
  owners: parsed.data.owners,
241
+ status: parsed.data.status,
242
+ date: parsed.data.date,
243
+ decisionMakers: parsed.data.decisionMakers,
244
+ appliesTo: parsed.data.appliesTo,
237
245
  badges: parsed.data.badges
238
246
  });
239
247
  const content = [frontmatterText, markdownToSearchText(parsed.content)].filter(Boolean).join("\n\n");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-UQIDXF2V.js";
3
+ } from "./chunk-7M5IQL3J.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "3.42.0";
28
+ var version = "3.43.0";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-VPZ77Y6E.js";
3
+ } from "./chunk-KY74BE42.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -114,7 +114,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
114
114
  var import_picocolors = __toESM(require("picocolors"), 1);
115
115
 
116
116
  // package.json
117
- var version = "3.42.0";
117
+ var version = "3.43.0";
118
118
 
119
119
  // src/constants.ts
120
120
  var VERSION = version;
@@ -244,6 +244,7 @@ async function raiseEvent(eventData) {
244
244
  // src/analytics/count-resources.js
245
245
  var import_glob = require("glob");
246
246
  var RESOURCE_PATTERNS = {
247
+ adrs: ["**/adrs/*/index.@(md|mdx)"],
247
248
  agents: ["**/agents/*/index.@(md|mdx)"],
248
249
  events: ["**/events/*/index.@(md|mdx)"],
249
250
  commands: ["**/commands/*/index.@(md|mdx)"],
@@ -291,6 +292,7 @@ var getFeatures = async (configFile) => {
291
292
  };
292
293
  var CLOUD_ANALYTICS_ENDPOINT = "https://api.ecingest.dev/v1/analytics/ingest";
293
294
  var toCloudResourceCounts = (counts) => ({
295
+ adrs: counts.adrs || 0,
294
296
  agents: counts.agents || 0,
295
297
  domains: counts.domains || 0,
296
298
  services: counts.services || 0,
@@ -1332,6 +1334,7 @@ var import_node_path8 = __toESM(require("path"), 1);
1332
1334
  var import_glob4 = require("glob");
1333
1335
  var import_gray_matter4 = __toESM(require("gray-matter"), 1);
1334
1336
  var RESOURCE_COLLECTIONS = {
1337
+ adrs: { docsPath: "adrs", type: "Architecture Decision" },
1335
1338
  agents: { docsPath: "agents", type: "Agent" },
1336
1339
  channels: { docsPath: "channels", type: "Channel" },
1337
1340
  commands: { docsPath: "commands", type: "Command" },
@@ -1396,6 +1399,9 @@ var findResourceSegment = (segments) => {
1396
1399
  let match = null;
1397
1400
  for (let index = 0; index < segments.length - 1; index++) {
1398
1401
  const segment = segments[index];
1402
+ if (segments[index - 1] === "docs") {
1403
+ continue;
1404
+ }
1399
1405
  if (RESOURCE_COLLECTIONS[segment] && segments[index + 1]) {
1400
1406
  match = { index, segment };
1401
1407
  }
@@ -1562,6 +1568,10 @@ var collectSearchRecords = async ({
1562
1568
  summary: baseRecord.summary,
1563
1569
  version: baseRecord.version,
1564
1570
  owners: parsed.data.owners,
1571
+ status: parsed.data.status,
1572
+ date: parsed.data.date,
1573
+ decisionMakers: parsed.data.decisionMakers,
1574
+ appliesTo: parsed.data.appliesTo,
1565
1575
  badges: parsed.data.badges
1566
1576
  });
1567
1577
  const content = [frontmatterText, markdownToSearchText(parsed.content)].filter(Boolean).join("\n\n");
@@ -7,15 +7,15 @@ import {
7
7
  } from "./chunk-WAJIJEI3.js";
8
8
  import {
9
9
  buildSearchIndex
10
- } from "./chunk-QMORF42U.js";
10
+ } from "./chunk-ZONBICNH.js";
11
11
  import {
12
12
  watch
13
13
  } from "./chunk-3H2RT3CM.js";
14
14
  import {
15
15
  log_build_default
16
- } from "./chunk-L66TCSM7.js";
17
- import "./chunk-6FAGUEM4.js";
18
- import "./chunk-3DVHEVHQ.js";
16
+ } from "./chunk-QV2PKXZM.js";
17
+ import "./chunk-2EI3M7OO.js";
18
+ import "./chunk-DAOXTQVS.js";
19
19
  import {
20
20
  catalogToAstro
21
21
  } from "./chunk-O6KT4DPL.js";
@@ -28,13 +28,13 @@ import {
28
28
  } from "./chunk-ULZYHF3V.js";
29
29
  import {
30
30
  generate
31
- } from "./chunk-KE6YTTLB.js";
31
+ } from "./chunk-ZQHBDPIY.js";
32
32
  import {
33
33
  logger
34
- } from "./chunk-UQIDXF2V.js";
34
+ } from "./chunk-7M5IQL3J.js";
35
35
  import {
36
36
  VERSION
37
- } from "./chunk-VPZ77Y6E.js";
37
+ } from "./chunk-KY74BE42.js";
38
38
  import {
39
39
  getEventCatalogConfigFile,
40
40
  verifyRequiredFieldsAreInCatalogConfigFile
package/dist/generate.cjs CHANGED
@@ -78,7 +78,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
78
78
  var import_picocolors = __toESM(require("picocolors"), 1);
79
79
 
80
80
  // package.json
81
- var version = "3.42.0";
81
+ var version = "3.43.0";
82
82
 
83
83
  // src/constants.ts
84
84
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-KE6YTTLB.js";
4
- import "./chunk-UQIDXF2V.js";
5
- import "./chunk-VPZ77Y6E.js";
3
+ } from "./chunk-ZQHBDPIY.js";
4
+ import "./chunk-7M5IQL3J.js";
5
+ import "./chunk-KY74BE42.js";
6
6
  import "./chunk-5T63CXKU.js";
7
7
  export {
8
8
  generate
@@ -40,6 +40,7 @@ var import_node_path = __toESM(require("path"), 1);
40
40
  var import_glob = require("glob");
41
41
  var import_gray_matter = __toESM(require("gray-matter"), 1);
42
42
  var RESOURCE_COLLECTIONS = {
43
+ adrs: { docsPath: "adrs", type: "Architecture Decision" },
43
44
  agents: { docsPath: "agents", type: "Agent" },
44
45
  channels: { docsPath: "channels", type: "Channel" },
45
46
  commands: { docsPath: "commands", type: "Command" },
@@ -104,6 +105,9 @@ var findResourceSegment = (segments) => {
104
105
  let match = null;
105
106
  for (let index = 0; index < segments.length - 1; index++) {
106
107
  const segment = segments[index];
108
+ if (segments[index - 1] === "docs") {
109
+ continue;
110
+ }
107
111
  if (RESOURCE_COLLECTIONS[segment] && segments[index + 1]) {
108
112
  match = { index, segment };
109
113
  }
@@ -270,6 +274,10 @@ var collectSearchRecords = async ({
270
274
  summary: baseRecord.summary,
271
275
  version: baseRecord.version,
272
276
  owners: parsed.data.owners,
277
+ status: parsed.data.status,
278
+ date: parsed.data.date,
279
+ decisionMakers: parsed.data.decisionMakers,
280
+ appliesTo: parsed.data.appliesTo,
273
281
  badges: parsed.data.badges
274
282
  });
275
283
  const content = [frontmatterText, markdownToSearchText(parsed.content)].filter(Boolean).join("\n\n");
@@ -2,7 +2,7 @@ import {
2
2
  buildSearchIndex,
3
3
  collectSearchRecords,
4
4
  markdownToSearchText
5
- } from "./chunk-QMORF42U.js";
5
+ } from "./chunk-ZONBICNH.js";
6
6
  export {
7
7
  buildSearchIndex,
8
8
  collectSearchRecords,
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.42.0";
39
+ var version = "3.43.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-UQIDXF2V.js";
4
- import "../chunk-VPZ77Y6E.js";
3
+ } from "../chunk-7M5IQL3J.js";
4
+ import "../chunk-KY74BE42.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -19,13 +19,13 @@ interface Props {
19
19
  title?: string;
20
20
  description?: string;
21
21
  columns?: number;
22
- data: {
23
- attachments: Attachment[];
22
+ data?: {
23
+ attachments?: Attachment[];
24
24
  };
25
25
  }
26
26
 
27
27
  const { title = 'Attachments', description, columns = 2, ...props } = Astro.props;
28
- const { attachments } = props.data;
28
+ const attachments = props.data?.attachments ?? [];
29
29
 
30
30
  function getIconForAttachment(attachment: AttachmentObject): ComponentType<{ className?: string }> | null {
31
31
  // If custom icon is provided, try to find it
@@ -221,6 +221,8 @@ export default function NestedSideBar() {
221
221
  // Agents
222
222
  { pattern: /^\/docs\/agents\/([^/]+)\/([^/]+)/, type: 'agent' },
223
223
  { pattern: /^\/visualiser\/agents\/([^/]+)\/([^/]+)/, type: 'agent' },
224
+ // Decision Records
225
+ { pattern: /^\/docs\/adrs\/([^/]+)\/([^/]+)/, type: 'adr' },
224
226
  // Services
225
227
  { pattern: /^\/docs\/services\/([^/]+)\/([^/]+)/, type: 'service' },
226
228
  { pattern: /^\/architecture\/services\/([^/]+)\/([^/]+)/, type: 'service' },
@@ -503,6 +505,13 @@ export default function NestedSideBar() {
503
505
  [favorites]
504
506
  );
505
507
 
508
+ const urlsMatch = useCallback((left: string | undefined, right: string | undefined) => {
509
+ if (!left || !right) return false;
510
+ return stripBasePath(left).replace(/\/$/, '') === stripBasePath(right).replace(/\/$/, '');
511
+ }, []);
512
+
513
+ const activeNodeKey = useMemo(() => findNodeKeyByUrl(currentPath), [currentPath, findNodeKeyByUrl]);
514
+
506
515
  // Show loading state if no data yet
507
516
  if (!data || roots.length === 0) {
508
517
  return (
@@ -838,7 +847,7 @@ export default function NestedSideBar() {
838
847
  */
839
848
  const renderItem = (item: NavNode, itemKey: string | null, index: number) => {
840
849
  const itemHasChildren = hasChildren(item);
841
- const isActive = item.href && currentPath === item.href;
850
+ const isActive = urlsMatch(item.href, currentPath) || (itemKey !== null && itemKey === activeNodeKey);
842
851
  const isFav = isFavorited(itemKey);
843
852
  const canFavorite = itemKey !== null; // Only items with keys can be favorited
844
853
 
@@ -925,7 +934,7 @@ export default function NestedSideBar() {
925
934
  key={`item-${itemKey || index}`}
926
935
  title={item.title}
927
936
  onClick={() => handleDrillDown(item, itemKey)}
928
- className={cn(baseClasses, parentClasses)}
937
+ className={cn(baseClasses, parentClasses, activeClasses)}
929
938
  >
930
939
  {content}
931
940
  </button>
@@ -6,10 +6,12 @@ import {
6
6
  getFacetedUniqueValues,
7
7
  getFilteredRowModel,
8
8
  getPaginationRowModel,
9
+ getSortedRowModel,
9
10
  useReactTable,
10
11
  type ColumnFiltersState,
12
+ type SortingState,
11
13
  } from '@tanstack/react-table';
12
- import { ChevronLeft, ChevronRight, SearchX, X, Search, Users } from 'lucide-react';
14
+ import { ArrowDown, ArrowUp, ArrowUpDown, ChevronLeft, ChevronRight, SearchX, X, Search, Users } from 'lucide-react';
13
15
  import { UserIcon } from '@heroicons/react/24/outline';
14
16
  import { useEffect, useMemo, useState } from 'react';
15
17
  import type { TableConfiguration } from '@types';
@@ -17,12 +19,14 @@ import { isSameVersion } from '@utils/collections/version-compare';
17
19
  import { resolveIconUrl } from '@utils/icon';
18
20
  import { FilterDropdown, CheckboxItem } from './FilterComponents';
19
21
  import { getDiscoverColumns } from './columns';
22
+ import { formatAdrStatus, type AdrStatus } from '@utils/collections/adr-constants';
20
23
 
21
24
  export type CollectionType =
22
25
  | 'agents'
23
26
  | 'events'
24
27
  | 'commands'
25
28
  | 'queries'
29
+ | 'adrs'
26
30
  | 'services'
27
31
  | 'external-systems'
28
32
  | 'domains'
@@ -41,6 +45,8 @@ export interface DiscoverTableData {
41
45
  hasDataDependencies?: boolean;
42
46
  hasTools?: boolean;
43
47
  hasModel?: boolean;
48
+ hasAppliesTo?: boolean;
49
+ hasDecisionMakers?: boolean;
44
50
  hasInputs?: boolean;
45
51
  hasOutputs?: boolean;
46
52
  data: {
@@ -58,6 +64,13 @@ export interface DiscoverTableData {
58
64
  textColor?: string;
59
65
  url?: string;
60
66
  }>;
67
+ status?: string;
68
+ date?: string | Date;
69
+ statusBadge?: {
70
+ content: string;
71
+ backgroundColor?: string;
72
+ textColor?: string;
73
+ };
61
74
  producers?: Array<any>;
62
75
  consumers?: Array<any>;
63
76
  receives?: Array<any>;
@@ -159,6 +172,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
159
172
  [collectionType, tableConfiguration]
160
173
  );
161
174
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
175
+ const [sorting, setSorting] = useState<SortingState>([]);
162
176
  const [tableFilter, setTableFilter] = useState('');
163
177
  const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
164
178
  const PAGE_SIZE_STORAGE_KEY = 'eventcatalog-discover-page-size';
@@ -182,6 +196,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
182
196
  const [selectedAgentModels, setSelectedAgentModels] = useState<string[]>([]);
183
197
  const [selectedBadges, setSelectedBadges] = useState<string[]>([]);
184
198
  const [selectedProperties, setSelectedProperties] = useState<string[]>([]);
199
+ const [selectedStatuses, setSelectedStatuses] = useState<string[]>([]);
185
200
 
186
201
  // Collect unique badges from all items
187
202
  const allBadges = useMemo(() => {
@@ -286,6 +301,14 @@ export function DiscoverTable<T extends DiscoverTableData>({
286
301
  }
287
302
  }
288
303
 
304
+ // ADR status filter
305
+ if (selectedStatuses.length > 0) {
306
+ const status = row.data.status;
307
+ if (!status || !selectedStatuses.includes(status)) {
308
+ return false;
309
+ }
310
+ }
311
+
289
312
  // Property filters
290
313
  if (selectedProperties.length > 0) {
291
314
  for (const prop of selectedProperties) {
@@ -364,6 +387,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
364
387
  selectedAgentProviders,
365
388
  selectedAgentModels,
366
389
  selectedBadges,
390
+ selectedStatuses,
367
391
  selectedProperties,
368
392
  tableFilter,
369
393
  ]);
@@ -378,14 +402,17 @@ export function DiscoverTable<T extends DiscoverTableData>({
378
402
  data: filteredData,
379
403
  columns,
380
404
  onColumnFiltersChange: setColumnFilters,
405
+ onSortingChange: setSorting,
381
406
  getCoreRowModel: getCoreRowModel(),
382
407
  getFilteredRowModel: getFilteredRowModel(),
408
+ getSortedRowModel: getSortedRowModel(),
383
409
  getFacetedRowModel: getFacetedRowModel(),
384
410
  getFacetedUniqueValues: getFacetedUniqueValues(),
385
411
  getFacetedMinMaxValues: getFacetedMinMaxValues(),
386
412
  getPaginationRowModel: getPaginationRowModel(),
387
413
  state: {
388
414
  columnFilters,
415
+ sorting,
389
416
  columnVisibility,
390
417
  },
391
418
  initialState: {
@@ -468,6 +495,27 @@ export function DiscoverTable<T extends DiscoverTableData>({
468
495
  return counts;
469
496
  }, [initialData]);
470
497
 
498
+ const statusCounts = useMemo(() => {
499
+ const counts: Record<string, number> = {};
500
+ initialData.forEach((item) => {
501
+ const status = item.data.status;
502
+ if (status) counts[status] = (counts[status] || 0) + 1;
503
+ });
504
+ return counts;
505
+ }, [initialData]);
506
+
507
+ const statusOptions = useMemo(
508
+ () =>
509
+ Object.keys(statusCounts)
510
+ .map((status) => ({
511
+ id: status,
512
+ name: formatAdrStatus(status as AdrStatus),
513
+ count: statusCounts[status],
514
+ }))
515
+ .sort((a, b) => a.name.localeCompare(b.name)),
516
+ [statusCounts]
517
+ );
518
+
471
519
  const toggleDomain = (domainId: string) => {
472
520
  setSelectedDomains((prev) => (prev.includes(domainId) ? prev.filter((id) => id !== domainId) : [...prev, domainId]));
473
521
  };
@@ -498,6 +546,10 @@ export function DiscoverTable<T extends DiscoverTableData>({
498
546
  setSelectedBadges((prev) => (prev.includes(badgeContent) ? prev.filter((b) => b !== badgeContent) : [...prev, badgeContent]));
499
547
  };
500
548
 
549
+ const toggleStatus = (status: string) => {
550
+ setSelectedStatuses((prev) => (prev.includes(status) ? prev.filter((item) => item !== status) : [...prev, status]));
551
+ };
552
+
501
553
  const toggleProperty = (propertyId: string) => {
502
554
  setSelectedProperties((prev) => (prev.includes(propertyId) ? prev.filter((p) => p !== propertyId) : [...prev, propertyId]));
503
555
  };
@@ -510,6 +562,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
510
562
  setSelectedAgentProviders([]);
511
563
  setSelectedAgentModels([]);
512
564
  setSelectedBadges([]);
565
+ setSelectedStatuses([]);
513
566
  setSelectedProperties([]);
514
567
  setShowOnlyLatest(true);
515
568
  setOnlyShowDrafts(false);
@@ -525,6 +578,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
525
578
  selectedAgentProviders.length +
526
579
  selectedAgentModels.length +
527
580
  selectedBadges.length +
581
+ selectedStatuses.length +
528
582
  selectedProperties.length +
529
583
  (!showOnlyLatest ? 1 : 0) +
530
584
  (onlyShowDrafts ? 1 : 0);
@@ -545,6 +599,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
545
599
  (id) => agentProviders.find((provider) => provider.id === id)?.name || id
546
600
  );
547
601
  const selectedAgentModelNames = selectedAgentModels.map((id) => agentModels.find((model) => model.id === id)?.name || id);
602
+ const selectedStatusNames = selectedStatuses.map((id) => statusOptions.find((status) => status.id === id)?.name || id);
548
603
 
549
604
  // Filter producers/consumers to only show those with count > 0
550
605
  const filteredProducers = producers.filter((p) => (producerCounts[p.id] || 0) > 0);
@@ -767,6 +822,32 @@ export function DiscoverTable<T extends DiscoverTableData>({
767
822
  </div>
768
823
  )}
769
824
 
825
+ {/* ADR Status Filter */}
826
+ {collectionType === 'adrs' && statusOptions.length > 0 && (
827
+ <div>
828
+ <label className="block text-xs font-medium text-[rgb(var(--ec-page-text)/0.8)] mb-1.5">Status</label>
829
+ <FilterDropdown
830
+ label="Select statuses..."
831
+ selectedItems={selectedStatusNames}
832
+ onClear={() => setSelectedStatuses([])}
833
+ onRemoveItem={(name) => {
834
+ const status = statusOptions.find((item) => item.name === name);
835
+ if (status) toggleStatus(status.id);
836
+ }}
837
+ >
838
+ {statusOptions.map((status) => (
839
+ <CheckboxItem
840
+ key={status.id}
841
+ label={status.name}
842
+ checked={selectedStatuses.includes(status.id)}
843
+ onChange={() => toggleStatus(status.id)}
844
+ count={status.count}
845
+ />
846
+ ))}
847
+ </FilterDropdown>
848
+ </div>
849
+ )}
850
+
770
851
  {/* Badges Filter */}
771
852
  {allBadges.length > 0 && (
772
853
  <div>
@@ -899,7 +980,24 @@ export function DiscoverTable<T extends DiscoverTableData>({
899
980
  key={`${header.id}`}
900
981
  className="px-4 py-2.5 text-left text-[11px] font-medium text-[rgb(var(--ec-page-text-muted))] uppercase tracking-wider"
901
982
  >
902
- {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
983
+ {header.isPlaceholder ? null : header.column.id === 'date' && header.column.getCanSort() ? (
984
+ <button
985
+ type="button"
986
+ onClick={header.column.getToggleSortingHandler()}
987
+ className="flex items-center gap-1.5 rounded-sm text-left uppercase tracking-wider hover:text-[rgb(var(--ec-page-text))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
988
+ >
989
+ {flexRender(header.column.columnDef.header, header.getContext())}
990
+ {header.column.getIsSorted() === 'asc' ? (
991
+ <ArrowUp className="h-3.5 w-3.5" />
992
+ ) : header.column.getIsSorted() === 'desc' ? (
993
+ <ArrowDown className="h-3.5 w-3.5" />
994
+ ) : (
995
+ <ArrowUpDown className="h-3.5 w-3.5 opacity-40" />
996
+ )}
997
+ </button>
998
+ ) : (
999
+ flexRender(header.column.columnDef.header, header.getContext())
1000
+ )}
903
1001
  </th>
904
1002
  ))}
905
1003
  </tr>