@eventcatalog/core 3.0.0-beta.9 → 3.0.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 (148) hide show
  1. package/README.md +41 -98
  2. package/dist/__mocks__/astro-content.cjs +32 -0
  3. package/dist/__mocks__/astro-content.d.cts +13 -0
  4. package/dist/__mocks__/astro-content.d.ts +13 -0
  5. package/dist/__mocks__/astro-content.js +7 -0
  6. package/dist/analytics/analytics.cjs +1 -1
  7. package/dist/analytics/analytics.js +2 -2
  8. package/dist/analytics/log-build.cjs +1 -1
  9. package/dist/analytics/log-build.js +3 -3
  10. package/dist/catalog-to-astro-content-directory.cjs +2 -19
  11. package/dist/catalog-to-astro-content-directory.d.cts +1 -2
  12. package/dist/catalog-to-astro-content-directory.d.ts +1 -2
  13. package/dist/catalog-to-astro-content-directory.js +3 -5
  14. package/dist/{chunk-R2BJ7MJG.js → chunk-6Z6ARMQS.js} +1 -17
  15. package/dist/{chunk-A4MGWK5T.js → chunk-BYP43AAT.js} +1 -1
  16. package/dist/{chunk-RAJ7TGWN.js → chunk-E5Q7TZYT.js} +1 -1
  17. package/dist/{chunk-TT4LZO2Q.js → chunk-EKGR533N.js} +1 -1
  18. package/dist/{chunk-2VPX4WIJ.js → chunk-KF5PARQK.js} +1 -1
  19. package/dist/{chunk-TC3R47V6.js → chunk-VO5WYA44.js} +1 -1
  20. package/dist/constants.cjs +1 -1
  21. package/dist/constants.js +1 -1
  22. package/dist/eventcatalog.cjs +20 -64
  23. package/dist/eventcatalog.config.d.cts +4 -0
  24. package/dist/eventcatalog.config.d.ts +4 -0
  25. package/dist/eventcatalog.js +26 -52
  26. package/dist/generate.cjs +1 -1
  27. package/dist/generate.js +3 -3
  28. package/dist/utils/cli-logger.cjs +1 -1
  29. package/dist/utils/cli-logger.js +2 -2
  30. package/eventcatalog/astro.config.mjs +4 -1
  31. package/eventcatalog/integrations/eventcatalog-features.ts +69 -0
  32. package/eventcatalog/public/icons/asyncapi-black.svg +2 -0
  33. package/eventcatalog/public/icons/graphql-black.svg +1 -0
  34. package/eventcatalog/public/icons/openapi-black.svg +1 -0
  35. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +994 -0
  36. package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +24 -0
  37. package/eventcatalog/src/components/Grids/DomainGrid.tsx +310 -173
  38. package/eventcatalog/src/components/Grids/MessageGrid.tsx +299 -180
  39. package/eventcatalog/src/components/Grids/specification-utils.ts +106 -0
  40. package/eventcatalog/src/components/Header.astro +25 -5
  41. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +14 -3
  42. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +95 -90
  43. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +144 -0
  44. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +34 -8
  45. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -2
  46. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +140 -109
  47. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +5 -14
  48. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +247 -59
  49. package/eventcatalog/src/components/SchemaExplorer/SchemaFilters.tsx +64 -126
  50. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +41 -43
  51. package/eventcatalog/src/components/Search/Search.astro +2 -2
  52. package/eventcatalog/src/components/Search/SearchDataLoader.astro +25 -0
  53. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +6 -3
  54. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +44 -16
  55. package/eventcatalog/src/components/SideNav/SideNav.astro +0 -15
  56. package/eventcatalog/src/components/Tables/Table.tsx +96 -77
  57. package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +108 -74
  58. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +74 -55
  59. package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +36 -36
  60. package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +110 -77
  61. package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +105 -94
  62. package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +31 -26
  63. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +115 -215
  64. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +145 -243
  65. package/eventcatalog/src/content.config.ts +1 -13
  66. package/eventcatalog/src/enterprise/ai/chat-api.ts +360 -0
  67. package/eventcatalog/src/enterprise/auth/[...auth].ts +3 -0
  68. package/eventcatalog/src/enterprise/auth/login.astro +420 -0
  69. package/eventcatalog/src/enterprise/collections/index.ts +0 -1
  70. package/eventcatalog/src/layouts/Footer.astro +8 -5
  71. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +133 -117
  72. package/eventcatalog/src/pages/_index.astro +243 -559
  73. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +8 -2
  74. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +9 -5
  75. package/eventcatalog/src/pages/directory/[type]/index.astro +6 -0
  76. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +19 -3
  77. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +7 -7
  78. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
  79. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +10 -7
  80. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +194 -121
  81. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +94 -70
  82. package/eventcatalog/src/pages/docs/teams/[id].mdx.ts +36 -0
  83. package/eventcatalog/src/pages/docs/users/[id]/index.astro +56 -45
  84. package/eventcatalog/src/pages/docs/users/[id].mdx.ts +36 -0
  85. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +178 -0
  86. package/eventcatalog/src/pages/schemas/explorer/index.astro +7 -157
  87. package/eventcatalog/src/pages/studio.astro +124 -72
  88. package/eventcatalog/src/remark-plugins/directives.ts +30 -9
  89. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/container.ts +10 -1
  90. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/domain.ts +17 -7
  91. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/message.ts +10 -1
  92. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/service.ts +11 -4
  93. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/shared.ts +14 -0
  94. package/eventcatalog/src/stores/{sidebar-store.ts → sidebar-store/index.ts} +1 -1
  95. package/eventcatalog/src/utils/collections/channels.ts +0 -2
  96. package/eventcatalog/src/utils/collections/commands.ts +0 -2
  97. package/eventcatalog/src/utils/collections/containers.ts +0 -2
  98. package/eventcatalog/src/utils/collections/domains.ts +0 -2
  99. package/eventcatalog/src/utils/collections/entities.ts +0 -2
  100. package/eventcatalog/src/utils/collections/events.ts +0 -2
  101. package/eventcatalog/src/utils/collections/flows.ts +0 -2
  102. package/eventcatalog/src/utils/collections/queries.ts +0 -2
  103. package/eventcatalog/src/utils/collections/schemas.ts +45 -7
  104. package/eventcatalog/src/utils/collections/services.ts +0 -2
  105. package/eventcatalog/src/utils/feature.ts +9 -5
  106. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +1 -1
  107. package/eventcatalog/src/utils/resource-files.ts +86 -0
  108. package/package.json +12 -15
  109. package/default-files-for-collections/changelogs.md +0 -5
  110. package/default-files-for-collections/channels.md +0 -8
  111. package/default-files-for-collections/commands.md +0 -8
  112. package/default-files-for-collections/domains.md +0 -8
  113. package/default-files-for-collections/events.md +0 -8
  114. package/default-files-for-collections/flows.md +0 -11
  115. package/default-files-for-collections/queries.md +0 -8
  116. package/default-files-for-collections/services.md +0 -8
  117. package/default-files-for-collections/ubiquitousLanguages.md +0 -7
  118. package/eventcatalog/src/enterprise/collections/chat-prompts.ts +0 -32
  119. package/eventcatalog/src/enterprise/eventcatalog-chat/components/Chat.tsx +0 -60
  120. package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatMessage.tsx +0 -414
  121. package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatSidebar.tsx +0 -169
  122. package/eventcatalog/src/enterprise/eventcatalog-chat/components/InputModal.tsx +0 -244
  123. package/eventcatalog/src/enterprise/eventcatalog-chat/components/MentionInput.tsx +0 -211
  124. package/eventcatalog/src/enterprise/eventcatalog-chat/components/WelcomePromptArea.tsx +0 -176
  125. package/eventcatalog/src/enterprise/eventcatalog-chat/components/default-prompts.ts +0 -93
  126. package/eventcatalog/src/enterprise/eventcatalog-chat/components/hooks/ChatProvider.tsx +0 -143
  127. package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx +0 -387
  128. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/api/chat.ts +0 -59
  129. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +0 -104
  130. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/ai-provider.ts +0 -140
  131. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/anthropic.ts +0 -28
  132. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/google.ts +0 -41
  133. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/index.ts +0 -26
  134. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/openai.ts +0 -61
  135. package/eventcatalog/src/enterprise/eventcatalog-chat/utils/chat-prompts.ts +0 -50
  136. package/eventcatalog/src/pages/auth/login.astro +0 -280
  137. package/eventcatalog/src/pages/chat/feature.astro +0 -179
  138. package/eventcatalog/src/pages/chat/index.astro +0 -10
  139. package/eventcatalog/src/pages/docs/_default-docs.mdx +0 -25
  140. package/eventcatalog/src/pages/docs/index.astro +0 -33
  141. package/eventcatalog/src/pages/nav-index.json.ts +0 -30
  142. /package/eventcatalog/src/{pages → enterprise}/auth/error.astro +0 -0
  143. /package/eventcatalog/src/{middleware-auth.ts → enterprise/auth/middleware/middleware-auth.ts} +0 -0
  144. /package/eventcatalog/src/{middleware.ts → enterprise/auth/middleware/middleware.ts} +0 -0
  145. /package/eventcatalog/src/{pages/unauthorized/index.astro → enterprise/auth/unauthorized.astro} +0 -0
  146. /package/eventcatalog/src/{pages → enterprise}/plans/index.astro +0 -0
  147. /package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/flow.ts +0 -0
  148. /package/eventcatalog/src/{components/SideNav/NestedSideBar/sidebar-builder.ts → stores/sidebar-store/state.ts} +0 -0
@@ -2,6 +2,8 @@ import { isSSR } from '@utils/feature';
2
2
  import { HybridPage } from '@utils/page-loaders/hybrid-page';
3
3
  import type { PageTypes } from '@types';
4
4
  import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
5
+ import { getDomains } from '@utils/collections/domains';
6
+ import { getServices } from '@utils/collections/services';
5
7
 
6
8
  /**
7
9
  * Documentation page class for all collection types with versioning
@@ -13,9 +15,13 @@ export class Page extends HybridPage {
13
15
  }
14
16
 
15
17
  const itemTypes: PageTypes[] = ['services', 'domains'];
16
- const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
17
18
 
18
- return allItems.flatMap((items, index) =>
19
+ const domains = await getDomains({ enrichServices: true });
20
+ const services = await getServices();
21
+
22
+ const pageData = [services, domains];
23
+
24
+ return pageData.flatMap((items, index) =>
19
25
  items.map((item) => ({
20
26
  params: {
21
27
  type: itemTypes[index],
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import DomainGrid from '@components/Grids/DomainGrid';
3
3
  import MessageGrid from '@components/Grids/MessageGrid';
4
+ import { getSpecificationsForService } from '@utils/collections/services';
4
5
 
5
6
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
6
7
  import { Page } from './_index.data';
@@ -15,15 +16,18 @@ let domain = props;
15
16
  const pageTitle = `${props.type} | ${props.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
16
17
 
17
18
  const type = props.type;
19
+
20
+ // Get specifications for services
21
+ const specifications = type === 'services' ? getSpecificationsForService(props) : [];
18
22
  ---
19
23
 
20
24
  <VerticalSideBarLayout title={pageTitle}>
21
- <div class="bg-white min-h-screen">
22
- <div class="mx-auto h-full">
23
- <div class="px-6 py-6 h-full">
25
+ <main class="flex docs-layout h-full">
26
+ <div class="flex docs-layout w-full pl-16">
27
+ <div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
24
28
  {type === 'domains' && <DomainGrid domain={domain} client:load />}
25
- {type === 'services' && <MessageGrid service={props} client:load />}
29
+ {type === 'services' && <MessageGrid service={props} specifications={specifications} client:load />}
26
30
  </div>
27
31
  </div>
28
- </div>
32
+ </main>
29
33
  </VerticalSideBarLayout>
@@ -37,6 +37,12 @@ function mapToItem(i: any) {
37
37
  // @ts-ignore
38
38
  avatarUrl: d.data?.avatarUrl,
39
39
  // @ts-ignore
40
+ email: d.data?.email,
41
+ // @ts-ignore
42
+ slackDirectMessageUrl: d.data?.slackDirectMessageUrl,
43
+ // @ts-ignore
44
+ msTeamsDirectMessageUrl: d.data?.msTeamsDirectMessageUrl,
45
+ // @ts-ignore
40
46
  associatedTeams: d.data?.associatedTeams?.map(mapToItem) ?? [],
41
47
  // @ts-ignore
42
48
  ownedCommands: d.data?.ownedCommands?.map(mapToItem) ?? [],
@@ -69,9 +69,21 @@ const pagefindAttributes =
69
69
  </VerticalSideBarLayout>
70
70
 
71
71
  <script is:inline src={js}></script>
72
- <script define:vars={{ schema: stringified, config }}>
73
- const root = document.getElementById('asyncapi');
74
- AsyncApiStandalone.hydrate({ schema, config }, root);
72
+ <script is:inline define:vars={{ schema: stringified, config }}>
73
+ function initAsyncApi() {
74
+ const root = document.getElementById('asyncapi');
75
+ if (!root || root.dataset.initialized) return;
76
+
77
+ if (typeof AsyncApiStandalone !== 'undefined') {
78
+ AsyncApiStandalone.render({ schema, config }, root);
79
+ root.dataset.initialized = 'true';
80
+ } else {
81
+ setTimeout(initAsyncApi, 50);
82
+ }
83
+ }
84
+
85
+ document.addEventListener('astro:page-load', initAsyncApi);
86
+ initAsyncApi();
75
87
  </script>
76
88
 
77
89
  <style>
@@ -82,6 +94,10 @@ const pagefindAttributes =
82
94
  }
83
95
  }
84
96
 
97
+ .burger-menu {
98
+ display: none;
99
+ }
100
+
85
101
  .aui-root .z-10 {
86
102
  z-index: 8;
87
103
  }
@@ -73,16 +73,16 @@ const logList = await Promise.all(logListPromise);
73
73
 
74
74
  const getBadge = () => {
75
75
  if (props.collection === 'services') {
76
- return { backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-400' };
76
+ return { backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-600' };
77
77
  }
78
78
  if (props.collection === 'events') {
79
- return { backgroundColor: 'orange', textColor: 'orange', content: 'Event', icon: BoltIcon, class: 'text-orange-400' };
79
+ return { backgroundColor: 'orange', textColor: 'orange', content: 'Event', icon: BoltIcon, class: 'text-orange-600' };
80
80
  }
81
81
  if (props.collection === 'commands') {
82
- return { backgroundColor: 'blue', textColor: 'blue', content: 'Command', icon: ChatBubbleLeftIcon, class: 'text-blue-400' };
82
+ return { backgroundColor: 'blue', textColor: 'blue', content: 'Command', icon: ChatBubbleLeftIcon, class: 'text-blue-600' };
83
83
  }
84
84
  if (props.collection === 'queries') {
85
- return { backgroundColor: 'green', textColor: 'green', content: 'Query', icon: MagnifyingGlassIcon, class: 'text-blue-400' };
85
+ return { backgroundColor: 'green', textColor: 'green', content: 'Query', icon: MagnifyingGlassIcon, class: 'text-green-600' };
86
86
  }
87
87
  if (props.collection === 'domains') {
88
88
  return {
@@ -90,14 +90,14 @@ const getBadge = () => {
90
90
  textColor: 'yellow',
91
91
  content: 'Domain',
92
92
  icon: RectangleGroupIcon,
93
- class: 'text-yellow-400',
93
+ class: 'text-yellow-600',
94
94
  };
95
95
  }
96
96
  if (props.collection === 'containers') {
97
- return { backgroundColor: 'blue', textColor: 'blue', content: 'Container', icon: DatabaseIcon, class: 'text-blue-400' };
97
+ return { backgroundColor: 'blue', textColor: 'blue', content: 'Container', icon: DatabaseIcon, class: 'text-blue-600' };
98
98
  }
99
99
  if (props.collection === 'flows') {
100
- return { backgroundColor: 'teal', textColor: 'teal', content: 'Flow', icon: QueueListIcon, class: 'text-teal-400' };
100
+ return { backgroundColor: 'teal', textColor: 'teal', content: 'Flow', icon: QueueListIcon, class: 'text-teal-600' };
101
101
  }
102
102
  };
103
103
 
@@ -36,7 +36,7 @@ if (isRemote) {
36
36
  const pageTitle = `${collection} | ${data.name} | GraphQL Schema`.replace(/^\w/, (c) => c.toUpperCase());
37
37
 
38
38
  const getServiceBadge = () => {
39
- return [{ backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-400' }];
39
+ return [{ backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-600' }];
40
40
  };
41
41
 
42
42
  const getGraphQLBadge = () => {
@@ -15,7 +15,7 @@ import Admonition from '@components/MDX/Admonition';
15
15
  import VersionList from '@components/Lists/VersionList.astro';
16
16
  import CopyAsMarkdown from '@components/CopyAsMarkdown';
17
17
  import FavoriteButton from '@components/FavoriteButton';
18
- import { shouldRenderSideBarSection } from '@components/SideNav/NestedSideBar/builders/shared';
18
+ import { shouldRenderSideBarSection } from '@stores/sidebar-store/builders/shared';
19
19
 
20
20
  import {
21
21
  QueueListIcon,
@@ -71,17 +71,17 @@ const getContentBadges = () =>
71
71
 
72
72
  const getBadge = () => {
73
73
  if (props.collection === 'services') {
74
- return [{ backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-400' }];
74
+ return [{ backgroundColor: 'pink', textColor: 'pink', content: 'Service', icon: ServerIcon, class: 'text-pink-600' }];
75
75
  }
76
76
  if (props.collection === 'events') {
77
- return [{ backgroundColor: 'orange', textColor: 'orange', content: 'Event', icon: BoltIcon, class: 'text-orange-400' }];
77
+ return [{ backgroundColor: 'orange', textColor: 'orange', content: 'Event', icon: BoltIcon, class: 'text-orange-600' }];
78
78
  }
79
79
  if (props.collection === 'commands') {
80
- return [{ backgroundColor: 'blue', textColor: 'blue', content: 'Command', icon: ChatBubbleLeftIcon, class: 'text-blue-400' }];
80
+ return [{ backgroundColor: 'blue', textColor: 'blue', content: 'Command', icon: ChatBubbleLeftIcon, class: 'text-blue-600' }];
81
81
  }
82
82
  if (props.collection === 'queries') {
83
83
  return [
84
- { backgroundColor: 'green', textColor: 'green', content: 'Query', icon: MagnifyingGlassIcon, class: 'text-green-400' },
84
+ { backgroundColor: 'green', textColor: 'green', content: 'Query', icon: MagnifyingGlassIcon, class: 'text-green-600' },
85
85
  ];
86
86
  }
87
87
  if (props.collection === 'domains') {
@@ -91,7 +91,7 @@ const getBadge = () => {
91
91
  textColor: 'yellow',
92
92
  content: 'Domain',
93
93
  icon: RectangleGroupIcon,
94
- class: 'text-yellow-400',
94
+ class: 'text-yellow-600',
95
95
  },
96
96
  ];
97
97
  }
@@ -491,7 +491,10 @@ nodeGraphs.push({
491
491
  }
492
492
  </div>
493
493
  </div>
494
- <aside class="hidden xl:block sticky top-0 pb-10 w-[280px] overflow-y-auto py-2 flex-shrink-0 pr-10">
494
+ <aside
495
+ id="eventcatalog-docs-sidebar"
496
+ class="hidden xl:block sticky top-0 pb-10 w-[280px] overflow-y-auto py-2 flex-shrink-0 pr-10"
497
+ >
495
498
  <div class="mt-4 space-y-8">
496
499
  {
497
500
  headings.length > 0 && (
@@ -26,12 +26,10 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
26
26
  <div class="flex docs-layout w-full">
27
27
  <div class="w-full lg:mr-2 pr-8 overflow-y-auto pt-6 pb-8 min-h-[50em]">
28
28
  {/* Title Section */}
29
- <div class="relative border-b border-gray-200 mb-4 pb-4">
29
+ <div class="relative border-b border-gray-200 mb-6 pb-6">
30
30
  <div class="xl:flex xl:items-start xl:justify-between">
31
31
  <div class="min-w-0 flex-1">
32
- <div class="flex items-center gap-2">
33
- <h1 class="text-xl font-bold leading-7 text-gray-900 sm:text-2xl xl:text-3xl">Ubiquitous Language</h1>
34
- </div>
32
+ <h1 class="text-xl font-bold leading-7 text-gray-900 sm:text-2xl xl:text-3xl">Ubiquitous Language</h1>
35
33
  <p class="mt-2 text-sm text-gray-500">
36
34
  Browse and discover ubiquitous language terms in the {props.data.name} domain{
37
35
  subdomains.length > 0 ? ' and its subdomains' : ''
@@ -40,15 +38,15 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
40
38
  </div>
41
39
 
42
40
  <div class="mt-4 xl:mt-0 xl:ml-4 xl:flex-shrink-0">
43
- <div class="relative w-full xl:w-96">
41
+ <div class="relative w-full xl:w-80">
44
42
  <input
45
43
  type="text"
46
44
  id="searchInput"
47
- placeholder="Search terms across domains..."
48
- class="w-full px-4 py-3 pl-10 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm xl:px-5 xl:py-3.5 xl:pl-12"
45
+ placeholder="Search terms..."
46
+ class="w-full px-4 py-2.5 pl-10 border border-gray-200 rounded-lg focus:ring-2 focus:ring-gray-900 focus:border-gray-900 text-sm bg-gray-50 focus:bg-white transition-colors"
49
47
  />
50
- <div class="absolute inset-y-0 left-0 pl-3 xl:pl-4 flex items-center pointer-events-none">
51
- <svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
48
+ <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
49
+ <svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
52
50
  <path
53
51
  stroke-linecap="round"
54
52
  stroke-linejoin="round"
@@ -58,9 +56,12 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
58
56
  </div>
59
57
  </div>
60
58
  <div class="mt-2 text-right">
61
- <div class="text-sm text-gray-500" id="resultsCount">
59
+ <span
60
+ class="inline-flex items-center px-2 py-1 text-xs font-medium text-gray-500 bg-gray-100 rounded-md"
61
+ id="resultsCount"
62
+ >
62
63
  {/* This will be updated by JavaScript */}
63
- </div>
64
+ </span>
64
65
  </div>
65
66
  </div>
66
67
  </div>
@@ -68,8 +69,16 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
68
69
 
69
70
  {
70
71
  !ubiquitousLanguage && subdomains.length === 0 && (
71
- <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 my-4">
72
- <p class="text-yellow-700">
72
+ <div class="flex flex-col items-center justify-center py-16 px-4">
73
+ <div class="flex items-center justify-center w-16 h-16 rounded-full bg-gray-100 mb-4">
74
+ {(() => {
75
+ const BookOpen = LucideIcons.BookOpen;
76
+ //@ts-ignore
77
+ return <BookOpen className="w-8 h-8 text-gray-400" />;
78
+ })()}
79
+ </div>
80
+ <h3 class="text-lg font-medium text-gray-900 mb-2">No ubiquitous language defined</h3>
81
+ <p class="text-sm text-gray-500 text-center max-w-md">
73
82
  This domain does not have any defined ubiquitous language terms yet. Consider adding some terms to help establish
74
83
  a common vocabulary for your domain.
75
84
  </p>
@@ -83,59 +92,96 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
83
92
  <div>
84
93
  {/* Domain Language Section */}
85
94
  {ubiquitousLanguage && (
86
- <div class="mb-8" data-domain-section="main">
87
- <h3 class="text-xl font-semibold text-gray-900 mb-4 border-b border-gray-200 pb-2">
88
- {props.data.name} Domain Language
89
- </h3>
90
- <div class="grid grid-cols-1 md:grid-cols-3 gap-4" data-terms-grid="main">
95
+ <div class="mb-10" data-domain-section="main">
96
+ <div class="flex items-center justify-between mb-5">
97
+ <div class="flex items-center gap-3">
98
+ {/* <div class="flex items-center justify-center w-8 h-8 rounded-lg bg-gray-900">
99
+ <RectangleGroupIcon className="w-4 h-4 text-white" />
100
+ </div> */}
101
+ <h3 class="text-xl font-semibold text-gray-900">
102
+ {props.data.name} Domain Language
103
+ <span class="ml-1 text-sm font-normal text-gray-500">
104
+ ({ubiquitousLanguage?.data?.dictionary?.length || 0} terms)
105
+ </span>
106
+ </h3>
107
+ </div>
108
+ </div>
109
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" data-terms-grid="main">
91
110
  {ubiquitousLanguage?.data?.dictionary?.map((term) => (
92
- <div
93
- class={`term-card block bg-white border rounded-lg p-6 transition-all duration-300 ease-in-out hover:shadow-md hover:border-primary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-primary focus:ring-white min-h-[12em] ${duplicateTerms.has(term.name.toLowerCase()) ? 'border-orange-300 bg-orange-50' : 'border-gray-200'}`}
111
+ <a
112
+ href={buildUrl(`/docs/${props.collection}/${props.data.id}/language/${term.id}`)}
113
+ class={`term-card group block bg-white border rounded-lg p-5 transition-all duration-200 hover:shadow-md hover:border-gray-400 hover:-translate-y-0.5 ${duplicateTerms.has(term.name.toLowerCase()) ? 'border-orange-300 bg-orange-50/50' : 'border-gray-200'}`}
94
114
  data-domain="main"
95
115
  >
96
- <div class="flex flex-col h-full space-y-8">
97
- {term.icon && (
98
- <div>
99
- {(() => {
100
- const Icon = LucideIcons[term.icon as keyof typeof LucideIcons];
101
- //@ts-ignore
102
- return Icon ? <Icon className="w-6 h-6 text-primary" /> : null;
103
- })()}
104
- </div>
105
- )}
106
- <div>
107
- <h4
108
- class={`text-lg font-semibold transition-colors duration-300 ease-in-out group-hover:text-gray-300 ${duplicateTerms.has(term.name.toLowerCase()) ? 'text-orange-800' : 'text-gray-800'}`}
109
- >
110
- {term.name}
111
- {duplicateTerms.has(term.name.toLowerCase()) && (
112
- <span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-800">
113
- Duplicate
114
- </span>
115
- )}
116
- </h4>
117
- <div class="term-content">
118
- <p class="summary-text text-gray-600 transition-colors duration-300 ease-in-out group-hover:text-gray-200 m-0 font-light text-sm mb-4">
119
- {term.summary}
120
- </p>
121
- {term.description && (
122
- <div class="prose prose-sm prose-p:my-3">
123
- <a
124
- href={buildUrl(`/docs/${props.collection}/${props.data.id}/language/${term.id}`)}
125
- class="show-more-text text-sm text-primary font-medium hover:underline"
126
- >
127
- Read more
128
- </a>
116
+ <div class="flex flex-col h-full">
117
+ <div class="flex items-start justify-between gap-3 mb-3">
118
+ <div class="flex items-center gap-2.5">
119
+ {term.icon ? (
120
+ <div class="flex items-center justify-center w-8 h-8 rounded-md bg-gray-100 group-hover:bg-gray-200 transition-colors">
121
+ {(() => {
122
+ const Icon = LucideIcons[term.icon as keyof typeof LucideIcons];
123
+ //@ts-ignore
124
+ return Icon ? <Icon className="w-4 h-4 text-gray-700" /> : null;
125
+ })()}
126
+ </div>
127
+ ) : (
128
+ <div class="flex items-center justify-center w-8 h-8 rounded-md bg-gray-100 group-hover:bg-gray-200 transition-colors">
129
+ {(() => {
130
+ const BookText = LucideIcons.BookText;
131
+ //@ts-ignore
132
+ return (
133
+ <BookText className="w-4 h-4 text-gray-500 group-hover:text-gray-700 transition-colors" />
134
+ );
135
+ })()}
129
136
  </div>
130
137
  )}
138
+ <h4
139
+ class={`text-base font-semibold group-hover:text-black transition-colors ${duplicateTerms.has(term.name.toLowerCase()) ? 'text-orange-800' : 'text-gray-900'}`}
140
+ >
141
+ {term.name}
142
+ </h4>
131
143
  </div>
144
+ {duplicateTerms.has(term.name.toLowerCase()) && (
145
+ <span class="flex-shrink-0 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-700 border border-orange-200">
146
+ Duplicate
147
+ </span>
148
+ )}
149
+ </div>
150
+ <p class="summary-text text-gray-600 text-sm leading-relaxed line-clamp-3 flex-grow mb-3">
151
+ {term.summary}
152
+ </p>
153
+ <div class="pt-3 border-t border-gray-100">
154
+ <span class="inline-flex items-center text-sm text-gray-600 font-medium group-hover:text-gray-900">
155
+ View details
156
+ <svg
157
+ class="ml-1 w-4 h-4 transition-transform group-hover:translate-x-0.5"
158
+ fill="none"
159
+ stroke="currentColor"
160
+ viewBox="0 0 24 24"
161
+ >
162
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
163
+ </svg>
164
+ </span>
132
165
  </div>
133
166
  </div>
134
- </div>
167
+ </a>
135
168
  ))}
136
169
  </div>
137
- <div class="hidden domain-no-results text-center py-8 bg-gray-50 rounded-lg" data-domain-no-results="main">
138
- <h4 class="text-md font-medium text-gray-900">No matching terms in {props.data.name} domain</h4>
170
+ <div
171
+ class="hidden domain-no-results text-center py-12 bg-gray-50 rounded-lg border border-gray-200 border-dashed"
172
+ data-domain-no-results="main"
173
+ >
174
+ <div class="flex items-center justify-center w-12 h-12 mx-auto mb-4 rounded-full bg-gray-100">
175
+ <svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
176
+ <path
177
+ stroke-linecap="round"
178
+ stroke-linejoin="round"
179
+ stroke-width="2"
180
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
181
+ />
182
+ </svg>
183
+ </div>
184
+ <h4 class="text-base font-medium text-gray-900">No matching terms in {props.data.name}</h4>
139
185
  <p class="mt-1 text-sm text-gray-500">Try adjusting your search terms.</p>
140
186
  </div>
141
187
  </div>
@@ -145,68 +191,105 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
145
191
  {subdomains
146
192
  .filter((s) => s.ubiquitousLanguage)
147
193
  .map(({ subdomain, ubiquitousLanguage: subdomainUL }) => (
148
- <div class="mb-8" data-domain-section={subdomain.data.id}>
149
- <div class="flex justify-between items-center mb-4 border-b border-gray-200 pb-2">
150
- <h3 class="text-xl font-semibold text-gray-900">{subdomain.data.name} Subdomain Language</h3>
194
+ <div class="mb-10" data-domain-section={subdomain.data.id}>
195
+ <div class="flex items-center justify-between mb-5">
196
+ <div class="flex items-center gap-3">
197
+ {/* <div class="flex items-center justify-center w-8 h-8 rounded-lg bg-gray-200">
198
+ <RectangleGroupIcon className="w-4 h-4 text-gray-700" />
199
+ </div> */}
200
+ <h3 class="text-xl font-semibold text-gray-900">
201
+ {subdomain.data.name} Domain Language
202
+ <span class="ml-1 text-sm font-normal text-gray-500">
203
+ ({subdomainUL?.data?.dictionary?.length || 0} terms)
204
+ </span>
205
+ </h3>
206
+ </div>
151
207
  <a
152
208
  href={buildUrl(`/docs/domains/${subdomain.data.id}/${subdomain.data.version}`)}
153
- class="text-sm text-primary hover:underline font-medium"
209
+ class="inline-flex items-center text-sm text-gray-600 hover:text-gray-900 font-medium transition-colors"
154
210
  >
155
- View Domain
211
+ View Domain
212
+ <svg class="ml-1 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
213
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
214
+ </svg>
156
215
  </a>
157
216
  </div>
158
- <div class="grid grid-cols-1 md:grid-cols-3 gap-4" data-terms-grid={subdomain.data.id}>
217
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" data-terms-grid={subdomain.data.id}>
159
218
  {subdomainUL?.data?.dictionary?.map((term) => (
160
- <div
161
- class={`term-card block bg-white border rounded-lg p-6 transition-all duration-300 ease-in-out hover:shadow-md hover:border-primary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-primary focus:ring-white min-h-[12em] ${duplicateTerms.has(term.name.toLowerCase()) ? 'border-orange-300 bg-orange-50' : 'border-gray-200'}`}
219
+ <a
220
+ href={buildUrl(`/docs/${props.collection}/${subdomain.data.id}/language/${term.id}`)}
221
+ class={`term-card group block bg-white border rounded-lg p-5 transition-all duration-200 hover:shadow-md hover:border-gray-400 hover:-translate-y-0.5 ${duplicateTerms.has(term.name.toLowerCase()) ? 'border-orange-300 bg-orange-50/50' : 'border-gray-200'}`}
162
222
  data-domain={subdomain.data.id}
163
223
  >
164
- <div class="flex flex-col h-full space-y-8">
165
- {term.icon && (
166
- <div>
167
- {(() => {
168
- const Icon = LucideIcons[term.icon as keyof typeof LucideIcons];
169
- //@ts-ignore
170
- return Icon ? <Icon className="w-6 h-6 text-primary" /> : null;
171
- })()}
172
- </div>
173
- )}
174
- <div>
175
- <h4
176
- class={`text-lg font-semibold transition-colors duration-300 ease-in-out group-hover:text-gray-300 ${duplicateTerms.has(term.name.toLowerCase()) ? 'text-orange-800' : 'text-gray-800'}`}
177
- >
178
- {term.name}
179
- {duplicateTerms.has(term.name.toLowerCase()) && (
180
- <span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-800">
181
- Duplicate
182
- </span>
183
- )}
184
- </h4>
185
- <div class="term-content">
186
- <p class="summary-text text-gray-600 transition-colors duration-300 ease-in-out group-hover:text-gray-200 m-0 font-light text-sm mb-4">
187
- {term.summary}
188
- </p>
189
- {term.description && (
190
- <div class="prose prose-sm prose-p:my-3">
191
- <a
192
- href={buildUrl(`/docs/${props.collection}/${subdomain.data.id}/language/${term.id}`)}
193
- class="show-more-text text-sm text-primary font-medium hover:underline"
194
- >
195
- Read more
196
- </a>
224
+ <div class="flex flex-col h-full">
225
+ <div class="flex items-start justify-between gap-3 mb-3">
226
+ <div class="flex items-center gap-2.5">
227
+ {term.icon ? (
228
+ <div class="flex items-center justify-center w-8 h-8 rounded-md bg-gray-100 group-hover:bg-gray-200 transition-colors">
229
+ {(() => {
230
+ const Icon = LucideIcons[term.icon as keyof typeof LucideIcons];
231
+ //@ts-ignore
232
+ return Icon ? <Icon className="w-4 h-4 text-gray-700" /> : null;
233
+ })()}
234
+ </div>
235
+ ) : (
236
+ <div class="flex items-center justify-center w-8 h-8 rounded-md bg-gray-100 group-hover:bg-gray-200 transition-colors">
237
+ {(() => {
238
+ const BookText = LucideIcons.BookText;
239
+ //@ts-ignore
240
+ return (
241
+ <BookText className="w-4 h-4 text-gray-500 group-hover:text-gray-700 transition-colors" />
242
+ );
243
+ })()}
197
244
  </div>
198
245
  )}
246
+ <h4
247
+ class={`text-base font-semibold group-hover:text-black transition-colors ${duplicateTerms.has(term.name.toLowerCase()) ? 'text-orange-800' : 'text-gray-900'}`}
248
+ >
249
+ {term.name}
250
+ </h4>
199
251
  </div>
252
+ {duplicateTerms.has(term.name.toLowerCase()) && (
253
+ <span class="flex-shrink-0 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-700 border border-orange-200">
254
+ Duplicate
255
+ </span>
256
+ )}
257
+ </div>
258
+ <p class="summary-text text-gray-600 text-sm leading-relaxed line-clamp-3 flex-grow mb-3">
259
+ {term.summary}
260
+ </p>
261
+ <div class="pt-3 border-t border-gray-100">
262
+ <span class="inline-flex items-center text-sm text-gray-600 font-medium group-hover:text-gray-900">
263
+ View details
264
+ <svg
265
+ class="ml-1 w-4 h-4 transition-transform group-hover:translate-x-0.5"
266
+ fill="none"
267
+ stroke="currentColor"
268
+ viewBox="0 0 24 24"
269
+ >
270
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
271
+ </svg>
272
+ </span>
200
273
  </div>
201
274
  </div>
202
- </div>
275
+ </a>
203
276
  ))}
204
277
  </div>
205
278
  <div
206
- class="hidden domain-no-results text-center py-8 bg-gray-50 rounded-lg"
279
+ class="hidden domain-no-results text-center py-12 bg-gray-50 rounded-lg border border-gray-200 border-dashed"
207
280
  data-domain-no-results={subdomain.data.id}
208
281
  >
209
- <h4 class="text-md font-medium text-gray-900">No matching terms in {subdomain.data.name} subdomain</h4>
282
+ <div class="flex items-center justify-center w-12 h-12 mx-auto mb-4 rounded-full bg-gray-100">
283
+ <svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
284
+ <path
285
+ stroke-linecap="round"
286
+ stroke-linejoin="round"
287
+ stroke-width="2"
288
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
289
+ />
290
+ </svg>
291
+ </div>
292
+ <h4 class="text-base font-medium text-gray-900">No matching terms in {subdomain.data.name}</h4>
210
293
  <p class="mt-1 text-sm text-gray-500">Try adjusting your search terms.</p>
211
294
  </div>
212
295
  </div>
@@ -320,26 +403,9 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
320
403
  </script>
321
404
 
322
405
  <style is:global>
323
- .term-card {
324
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
325
- min-height: 12em;
326
- }
327
-
328
- .summary-text {
329
- opacity: 1;
330
- max-height: unset;
331
- display: block;
332
- }
333
-
334
- .description-text,
335
- .term-card.expanded,
336
- .term-card.expanded .show-more-text {
337
- display: none;
338
- }
339
-
340
406
  .term-card.highlighted {
341
- border-color: var(--color-primary);
342
- box-shadow: 0 0 0 2px var(--color-primary);
407
+ border-color: #111827;
408
+ box-shadow: 0 0 0 2px #111827;
343
409
  animation: pulse 1s;
344
410
  }
345
411
 
@@ -347,12 +413,19 @@ const { subdomains, duplicateTerms } = ubiquitousLanguageData;
347
413
  0%,
348
414
  100% {
349
415
  transform: scale(1);
350
- box-shadow: 0 0 0 2px var(--color-primary);
416
+ box-shadow: 0 0 0 2px #111827;
351
417
  }
352
418
  50% {
353
419
  transform: scale(1.01);
354
- box-shadow: 0 0 0 4px var(--color-primary);
420
+ box-shadow: 0 0 0 4px #111827;
355
421
  }
356
422
  }
423
+
424
+ .line-clamp-3 {
425
+ display: -webkit-box;
426
+ -webkit-line-clamp: 3;
427
+ -webkit-box-orient: vertical;
428
+ overflow: hidden;
429
+ }
357
430
  </style>
358
431
  </VerticalSideBarLayout>