@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.
- package/README.md +41 -98
- package/dist/__mocks__/astro-content.cjs +32 -0
- package/dist/__mocks__/astro-content.d.cts +13 -0
- package/dist/__mocks__/astro-content.d.ts +13 -0
- package/dist/__mocks__/astro-content.js +7 -0
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/catalog-to-astro-content-directory.cjs +2 -19
- package/dist/catalog-to-astro-content-directory.d.cts +1 -2
- package/dist/catalog-to-astro-content-directory.d.ts +1 -2
- package/dist/catalog-to-astro-content-directory.js +3 -5
- package/dist/{chunk-R2BJ7MJG.js → chunk-6Z6ARMQS.js} +1 -17
- package/dist/{chunk-A4MGWK5T.js → chunk-BYP43AAT.js} +1 -1
- package/dist/{chunk-RAJ7TGWN.js → chunk-E5Q7TZYT.js} +1 -1
- package/dist/{chunk-TT4LZO2Q.js → chunk-EKGR533N.js} +1 -1
- package/dist/{chunk-2VPX4WIJ.js → chunk-KF5PARQK.js} +1 -1
- package/dist/{chunk-TC3R47V6.js → chunk-VO5WYA44.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +20 -64
- package/dist/eventcatalog.config.d.cts +4 -0
- package/dist/eventcatalog.config.d.ts +4 -0
- package/dist/eventcatalog.js +26 -52
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/astro.config.mjs +4 -1
- package/eventcatalog/integrations/eventcatalog-features.ts +69 -0
- package/eventcatalog/public/icons/asyncapi-black.svg +2 -0
- package/eventcatalog/public/icons/graphql-black.svg +1 -0
- package/eventcatalog/public/icons/openapi-black.svg +1 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +994 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +24 -0
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +310 -173
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +299 -180
- package/eventcatalog/src/components/Grids/specification-utils.ts +106 -0
- package/eventcatalog/src/components/Header.astro +25 -5
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +14 -3
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +95 -90
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +144 -0
- package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +34 -8
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -2
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +140 -109
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +5 -14
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +247 -59
- package/eventcatalog/src/components/SchemaExplorer/SchemaFilters.tsx +64 -126
- package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +41 -43
- package/eventcatalog/src/components/Search/Search.astro +2 -2
- package/eventcatalog/src/components/Search/SearchDataLoader.astro +25 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +6 -3
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +44 -16
- package/eventcatalog/src/components/SideNav/SideNav.astro +0 -15
- package/eventcatalog/src/components/Tables/Table.tsx +96 -77
- package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +108 -74
- package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +74 -55
- package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +36 -36
- package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +110 -77
- package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +105 -94
- package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +31 -26
- package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +115 -215
- package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +145 -243
- package/eventcatalog/src/content.config.ts +1 -13
- package/eventcatalog/src/enterprise/ai/chat-api.ts +360 -0
- package/eventcatalog/src/enterprise/auth/[...auth].ts +3 -0
- package/eventcatalog/src/enterprise/auth/login.astro +420 -0
- package/eventcatalog/src/enterprise/collections/index.ts +0 -1
- package/eventcatalog/src/layouts/Footer.astro +8 -5
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +133 -117
- package/eventcatalog/src/pages/_index.astro +243 -559
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +8 -2
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +9 -5
- package/eventcatalog/src/pages/directory/[type]/index.astro +6 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +19 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +7 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +10 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +194 -121
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +94 -70
- package/eventcatalog/src/pages/docs/teams/[id].mdx.ts +36 -0
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +56 -45
- package/eventcatalog/src/pages/docs/users/[id].mdx.ts +36 -0
- package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +178 -0
- package/eventcatalog/src/pages/schemas/explorer/index.astro +7 -157
- package/eventcatalog/src/pages/studio.astro +124 -72
- package/eventcatalog/src/remark-plugins/directives.ts +30 -9
- package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/container.ts +10 -1
- package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/domain.ts +17 -7
- package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/message.ts +10 -1
- package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/service.ts +11 -4
- package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/shared.ts +14 -0
- package/eventcatalog/src/stores/{sidebar-store.ts → sidebar-store/index.ts} +1 -1
- package/eventcatalog/src/utils/collections/channels.ts +0 -2
- package/eventcatalog/src/utils/collections/commands.ts +0 -2
- package/eventcatalog/src/utils/collections/containers.ts +0 -2
- package/eventcatalog/src/utils/collections/domains.ts +0 -2
- package/eventcatalog/src/utils/collections/entities.ts +0 -2
- package/eventcatalog/src/utils/collections/events.ts +0 -2
- package/eventcatalog/src/utils/collections/flows.ts +0 -2
- package/eventcatalog/src/utils/collections/queries.ts +0 -2
- package/eventcatalog/src/utils/collections/schemas.ts +45 -7
- package/eventcatalog/src/utils/collections/services.ts +0 -2
- package/eventcatalog/src/utils/feature.ts +9 -5
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +1 -1
- package/eventcatalog/src/utils/resource-files.ts +86 -0
- package/package.json +12 -15
- package/default-files-for-collections/changelogs.md +0 -5
- package/default-files-for-collections/channels.md +0 -8
- package/default-files-for-collections/commands.md +0 -8
- package/default-files-for-collections/domains.md +0 -8
- package/default-files-for-collections/events.md +0 -8
- package/default-files-for-collections/flows.md +0 -11
- package/default-files-for-collections/queries.md +0 -8
- package/default-files-for-collections/services.md +0 -8
- package/default-files-for-collections/ubiquitousLanguages.md +0 -7
- package/eventcatalog/src/enterprise/collections/chat-prompts.ts +0 -32
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/Chat.tsx +0 -60
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatMessage.tsx +0 -414
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatSidebar.tsx +0 -169
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/InputModal.tsx +0 -244
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/MentionInput.tsx +0 -211
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/WelcomePromptArea.tsx +0 -176
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/default-prompts.ts +0 -93
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/hooks/ChatProvider.tsx +0 -143
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx +0 -387
- package/eventcatalog/src/enterprise/eventcatalog-chat/pages/api/chat.ts +0 -59
- package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +0 -104
- package/eventcatalog/src/enterprise/eventcatalog-chat/providers/ai-provider.ts +0 -140
- package/eventcatalog/src/enterprise/eventcatalog-chat/providers/anthropic.ts +0 -28
- package/eventcatalog/src/enterprise/eventcatalog-chat/providers/google.ts +0 -41
- package/eventcatalog/src/enterprise/eventcatalog-chat/providers/index.ts +0 -26
- package/eventcatalog/src/enterprise/eventcatalog-chat/providers/openai.ts +0 -61
- package/eventcatalog/src/enterprise/eventcatalog-chat/utils/chat-prompts.ts +0 -50
- package/eventcatalog/src/pages/auth/login.astro +0 -280
- package/eventcatalog/src/pages/chat/feature.astro +0 -179
- package/eventcatalog/src/pages/chat/index.astro +0 -10
- package/eventcatalog/src/pages/docs/_default-docs.mdx +0 -25
- package/eventcatalog/src/pages/docs/index.astro +0 -33
- package/eventcatalog/src/pages/nav-index.json.ts +0 -30
- /package/eventcatalog/src/{pages → enterprise}/auth/error.astro +0 -0
- /package/eventcatalog/src/{middleware-auth.ts → enterprise/auth/middleware/middleware-auth.ts} +0 -0
- /package/eventcatalog/src/{middleware.ts → enterprise/auth/middleware/middleware.ts} +0 -0
- /package/eventcatalog/src/{pages/unauthorized/index.astro → enterprise/auth/unauthorized.astro} +0 -0
- /package/eventcatalog/src/{pages → enterprise}/plans/index.astro +0 -0
- /package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/flow.ts +0 -0
- /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
|
-
|
|
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
|
-
<
|
|
22
|
-
<div class="
|
|
23
|
-
<div class="
|
|
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
|
-
</
|
|
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
|
-
|
|
74
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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 '@
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
-
<
|
|
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-
|
|
41
|
+
<div class="relative w-full xl:w-80">
|
|
44
42
|
<input
|
|
45
43
|
type="text"
|
|
46
44
|
id="searchInput"
|
|
47
|
-
placeholder="Search terms
|
|
48
|
-
class="w-full px-4 py-
|
|
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
|
|
51
|
-
<svg class="h-
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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="
|
|
72
|
-
<
|
|
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-
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
<
|
|
93
|
-
|
|
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
|
|
97
|
-
|
|
98
|
-
<div>
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
</
|
|
167
|
+
</a>
|
|
135
168
|
))}
|
|
136
169
|
</div>
|
|
137
|
-
<div
|
|
138
|
-
|
|
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-
|
|
149
|
-
<div class="flex
|
|
150
|
-
<
|
|
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-
|
|
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
|
-
<
|
|
161
|
-
|
|
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
|
|
165
|
-
|
|
166
|
-
<div>
|
|
167
|
-
{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
</
|
|
275
|
+
</a>
|
|
203
276
|
))}
|
|
204
277
|
</div>
|
|
205
278
|
<div
|
|
206
|
-
class="hidden domain-no-results text-center py-
|
|
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
|
-
<
|
|
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:
|
|
342
|
-
box-shadow: 0 0 0 2px
|
|
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
|
|
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
|
|
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>
|