@eventcatalog/core 2.18.7 → 2.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/{chunk-7GHQF4IY.js → chunk-BKWJZFAQ.js} +1 -1
- package/dist/{chunk-3B32CY7F.js → chunk-G3WSEVOS.js} +1 -1
- package/dist/{chunk-KIJRG7DY.js → chunk-HICY5YZU.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +3 -3
- package/eventcatalog/package-lock.json +1074 -142
- package/eventcatalog/package.json +5 -4
- package/eventcatalog/src/components/MDX/Tabs/Tabs.astro +7 -3
- package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +3 -2
- package/eventcatalog/src/components/SideBars/DomainSideBar.astro +4 -2
- package/eventcatalog/src/components/SideBars/MessageSideBar.astro +4 -2
- package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +4 -2
- package/eventcatalog/src/content/config.ts +15 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +232 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/language.astro +19 -60
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +2 -2
- package/eventcatalog/src/pages/visualiser/context-map/index.astro +2 -2
- package/eventcatalog/src/utils/collections/changelogs.ts +1 -1
- package/eventcatalog/src/utils/collections/owners.ts +43 -0
- package/eventcatalog/src/utils/collections/util.ts +31 -23
- package/package.json +6 -5
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@astrojs/markdown-remark": "^6.0.1",
|
|
21
|
-
"@astrojs/mdx": "^4.0.
|
|
22
|
-
"@astrojs/react": "^4.1.
|
|
23
|
-
"@astrojs/tailwind": "^5.1.
|
|
21
|
+
"@astrojs/mdx": "^4.0.5",
|
|
22
|
+
"@astrojs/react": "^4.1.3",
|
|
23
|
+
"@astrojs/tailwind": "^5.1.4",
|
|
24
24
|
"@asyncapi/avro-schema-parser": "^3.0.24",
|
|
25
25
|
"@asyncapi/parser": "^3.4.0",
|
|
26
26
|
"@asyncapi/react-component": "^2.4.3",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@tailwindcss/typography": "^0.5.13",
|
|
33
33
|
"@tanstack/react-table": "^8.17.3",
|
|
34
34
|
"@xyflow/react": "^12.3.6",
|
|
35
|
-
"astro": "^5.
|
|
35
|
+
"astro": "^5.1.5",
|
|
36
36
|
"astro-expressive-code": "^0.38.3",
|
|
37
37
|
"astro-pagefind": "^1.7.0",
|
|
38
38
|
"astro-seo": "^0.8.4",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"lodash.debounce": "^4.0.8",
|
|
45
45
|
"lodash.merge": "4.6.2",
|
|
46
46
|
"lucide-react": "^0.453.0",
|
|
47
|
+
"marked": "^15.0.6",
|
|
47
48
|
"mermaid": "^11.4.1",
|
|
48
49
|
"prismjs": "^1.29.0",
|
|
49
50
|
"rapidoc": "^9.3.4",
|
|
@@ -93,8 +93,12 @@ const tabsId = Math.random().toString(36).substring(2, 9);
|
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
// We use `ViewTransitions`
|
|
97
|
+
// Whenever happens a navigation, from view transitions or native to the browser, init the tabs.
|
|
98
|
+
document.addEventListener('astro:page-load', () => {
|
|
99
|
+
// Initialize all tab containers
|
|
100
|
+
document.querySelectorAll('[data-tabs-container]').forEach((container: Element) => {
|
|
101
|
+
initTabs(container as HTMLElement);
|
|
102
|
+
});
|
|
99
103
|
});
|
|
100
104
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import PillListFlat from '@components/Lists/PillListFlat';
|
|
4
4
|
import ProtocolList from '@components/Lists/ProtocolList';
|
|
5
5
|
import OwnersList from '@components/Lists/OwnersList';
|
|
@@ -7,6 +7,7 @@ import VersionList from '@components/Lists/VersionList.astro';
|
|
|
7
7
|
import { buildUrl } from '@utils/url-builder';
|
|
8
8
|
import { ScrollText } from 'lucide-react';
|
|
9
9
|
import RepositoryList from '@components/Lists/RepositoryList.astro';
|
|
10
|
+
import { getOwner } from '@utils/collections/owners';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
channel: CollectionEntry<'channels'>;
|
|
@@ -15,7 +16,7 @@ interface Props {
|
|
|
15
16
|
const { channel } = Astro.props;
|
|
16
17
|
|
|
17
18
|
const ownersRaw = channel.data?.owners || [];
|
|
18
|
-
const owners = await Promise.all(ownersRaw.map(
|
|
19
|
+
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
|
|
19
20
|
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
20
21
|
|
|
21
22
|
const channelParameters: Record<string, { enum?: string[]; description?: string }> = channel.data.parameters || {};
|
|
@@ -4,9 +4,11 @@ import PillListFlat from '@components/Lists/PillListFlat';
|
|
|
4
4
|
import RepositoryList from '@components/Lists/RepositoryList.astro';
|
|
5
5
|
import VersionList from '@components/Lists/VersionList.astro';
|
|
6
6
|
import { getUbiquitousLanguage } from '@utils/collections/domains';
|
|
7
|
+
import { getOwner } from '@utils/collections/owners';
|
|
7
8
|
import { buildUrl } from '@utils/url-builder';
|
|
8
|
-
import {
|
|
9
|
+
import type { CollectionEntry } from 'astro:content';
|
|
9
10
|
import { ScrollText, Workflow } from 'lucide-react';
|
|
11
|
+
|
|
10
12
|
interface Props {
|
|
11
13
|
domain: CollectionEntry<'domains'>;
|
|
12
14
|
}
|
|
@@ -20,7 +22,7 @@ const hasUbiquitousLanguage = ubiquitousLanguage.length > 0;
|
|
|
20
22
|
const ubiquitousLanguageDictionary = hasUbiquitousLanguage ? ubiquitousLanguage[0].data.dictionary : [];
|
|
21
23
|
|
|
22
24
|
const ownersRaw = domain.data?.owners || [];
|
|
23
|
-
const owners = await Promise.all(ownersRaw.map(
|
|
25
|
+
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
|
|
24
26
|
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
25
27
|
|
|
26
28
|
const serviceList = services.map((p) => ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import PillListFlat from '@components/Lists/PillListFlat';
|
|
4
4
|
import OwnersList from '@components/Lists/OwnersList';
|
|
5
5
|
import type { CollectionMessageTypes } from '@types';
|
|
@@ -8,6 +8,8 @@ import VersionList from '@components/Lists/VersionList.astro';
|
|
|
8
8
|
import { buildUrl } from '@utils/url-builder';
|
|
9
9
|
import { FileDownIcon, ScrollText, Workflow } from 'lucide-react';
|
|
10
10
|
import RepositoryList from '@components/Lists/RepositoryList.astro';
|
|
11
|
+
import { getOwner } from '@utils/collections/owners';
|
|
12
|
+
|
|
11
13
|
interface Props {
|
|
12
14
|
message: CollectionEntry<CollectionMessageTypes>;
|
|
13
15
|
}
|
|
@@ -19,7 +21,7 @@ const consumers = (message.data.consumers as CollectionEntry<'services'>[]) || [
|
|
|
19
21
|
const channels = (message.data.messageChannels as CollectionEntry<'channels'>[]) || [];
|
|
20
22
|
|
|
21
23
|
const ownersRaw = message.data?.owners || [];
|
|
22
|
-
const owners = await Promise.all(ownersRaw.map(
|
|
24
|
+
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
|
|
23
25
|
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
24
26
|
|
|
25
27
|
const producerList = producers.map((p) => ({
|
|
@@ -5,9 +5,11 @@ import RepositoryList from '@components/Lists/RepositoryList.astro';
|
|
|
5
5
|
import SpecificationsList from '@components/Lists/SpecificationsList.astro';
|
|
6
6
|
import VersionList from '@components/Lists/VersionList.astro';
|
|
7
7
|
import { buildUrl } from '@utils/url-builder';
|
|
8
|
-
import {
|
|
8
|
+
import { getOwner } from '@utils/collections/owners';
|
|
9
|
+
import type { CollectionEntry } from 'astro:content';
|
|
9
10
|
import { ScrollText, Workflow, FileDownIcon, Code, Link } from 'lucide-react';
|
|
10
11
|
import { join } from 'node:path';
|
|
12
|
+
|
|
11
13
|
interface Props {
|
|
12
14
|
service: CollectionEntry<'services'>;
|
|
13
15
|
}
|
|
@@ -20,7 +22,7 @@ const sends = (service.data.sends as CollectionEntry<'events'>[]) || [];
|
|
|
20
22
|
const receives = (service.data.receives as CollectionEntry<'events'>[]) || [];
|
|
21
23
|
|
|
22
24
|
const ownersRaw = service.data?.owners || [];
|
|
23
|
-
const owners = await Promise.all(ownersRaw.map(
|
|
25
|
+
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
|
|
24
26
|
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
25
27
|
|
|
26
28
|
const sendsList = sends.map((p) => ({
|
|
@@ -47,7 +47,21 @@ const changelogs = defineCollection({
|
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
// Create a union type for owners
|
|
50
|
-
const ownerReference = z
|
|
50
|
+
const ownerReference = z
|
|
51
|
+
.union([
|
|
52
|
+
// The ID of the user or team
|
|
53
|
+
z.string(),
|
|
54
|
+
// The full object with the ID and collection (keep compatibility with `reference`)
|
|
55
|
+
z.object({
|
|
56
|
+
id: z.string(),
|
|
57
|
+
collection: z.enum(['users', 'teams']),
|
|
58
|
+
}),
|
|
59
|
+
])
|
|
60
|
+
.transform(
|
|
61
|
+
// This transformation is needed to keep compatibility with `reference`.
|
|
62
|
+
// The utilities `getTeams` and `getUsers` rely on this transformation.
|
|
63
|
+
(lookup) => ({ id: typeof lookup === 'string' ? lookup : lookup.id })
|
|
64
|
+
);
|
|
51
65
|
|
|
52
66
|
const baseSchema = z.object({
|
|
53
67
|
id: z.string(),
|
|
@@ -11,7 +11,7 @@ import { buildUrl } from '@utils/url-builder';
|
|
|
11
11
|
import { getVersions, getPreviousVersion } from '@utils/collections/util';
|
|
12
12
|
import { getDiffsForCurrentAndPreviousVersion } from '@utils/collections/file-diffs';
|
|
13
13
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
14
|
-
import {
|
|
14
|
+
import { ClientRouter } from 'astro:transitions';
|
|
15
15
|
|
|
16
16
|
export async function getStaticPaths() {
|
|
17
17
|
const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains'];
|
|
@@ -222,5 +222,5 @@ const pages = [
|
|
|
222
222
|
</div>
|
|
223
223
|
<Footer />
|
|
224
224
|
</main>
|
|
225
|
-
<
|
|
225
|
+
<ClientRouter />
|
|
226
226
|
</VerticalSideBarLayout>
|
|
@@ -18,7 +18,7 @@ import type { PageTypes } from '@types';
|
|
|
18
18
|
import { buildUrl } from '@utils/url-builder';
|
|
19
19
|
import { getFlows } from '@utils/collections/flows';
|
|
20
20
|
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
21
|
-
import {
|
|
21
|
+
import { ClientRouter } from 'astro:transitions';
|
|
22
22
|
import { ArrowsRightLeftIcon } from '@heroicons/react/20/solid';
|
|
23
23
|
|
|
24
24
|
import config from '@config';
|
|
@@ -225,7 +225,7 @@ const badges = [getBadge(), ...contentBadges, ...getSpecificationBadges()];
|
|
|
225
225
|
{props?.collection === 'channels' && <ChannelSideBar channel={props} />}
|
|
226
226
|
</aside>
|
|
227
227
|
</div>
|
|
228
|
-
<
|
|
228
|
+
<ClientRouter />
|
|
229
229
|
</main>
|
|
230
230
|
|
|
231
231
|
<style is:global>
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
import RectangleGroupIcon from '@heroicons/react/24/outline/RectangleGroupIcon';
|
|
3
|
+
import Footer from '@layouts/Footer.astro';
|
|
4
|
+
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
5
|
+
import { getDomains, getUbiquitousLanguage } from '@utils/collections/domains';
|
|
6
|
+
import { buildUrl } from '@utils/url-builder';
|
|
7
|
+
import { ClientRouter } from 'astro:transitions';
|
|
8
|
+
import { marked } from 'marked';
|
|
9
|
+
|
|
10
|
+
export async function getStaticPaths() {
|
|
11
|
+
const domains = await getDomains({ getAllVersions: false });
|
|
12
|
+
|
|
13
|
+
const pages = await domains.reduce<Promise<any[]>>(async (acc, domain) => {
|
|
14
|
+
const accumulator = await acc;
|
|
15
|
+
const ubiquitousLanguages = await getUbiquitousLanguage(domain);
|
|
16
|
+
|
|
17
|
+
if (ubiquitousLanguages.length === 0) {
|
|
18
|
+
return accumulator;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const dictionary = ubiquitousLanguages[0].data.dictionary;
|
|
22
|
+
|
|
23
|
+
if (!dictionary) {
|
|
24
|
+
return accumulator;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
...accumulator,
|
|
29
|
+
...dictionary.map((item) => ({
|
|
30
|
+
params: {
|
|
31
|
+
type: domain.collection,
|
|
32
|
+
id: domain.data.id,
|
|
33
|
+
dictionaryId: item.id,
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
type: domain.collection,
|
|
37
|
+
domainId: domain.data.id,
|
|
38
|
+
domain: domain.data,
|
|
39
|
+
ubiquitousLanguage: item,
|
|
40
|
+
...item,
|
|
41
|
+
},
|
|
42
|
+
})),
|
|
43
|
+
];
|
|
44
|
+
}, Promise.resolve([]));
|
|
45
|
+
|
|
46
|
+
return pages;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const props = Astro.props;
|
|
50
|
+
const { ubiquitousLanguage } = props;
|
|
51
|
+
const pageTitle = `${props.type} | ${ubiquitousLanguage.name}`.replace(/^\w/, (c) => c.toUpperCase());
|
|
52
|
+
|
|
53
|
+
marked.setOptions({
|
|
54
|
+
breaks: true,
|
|
55
|
+
gfm: true,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const badges = [
|
|
59
|
+
{
|
|
60
|
+
backgroundColor: 'yellow',
|
|
61
|
+
textColor: 'yellow',
|
|
62
|
+
content: props.domain.name,
|
|
63
|
+
icon: RectangleGroupIcon,
|
|
64
|
+
class: 'text-yellow-400',
|
|
65
|
+
href: buildUrl(`/docs/${props.type}/${props.domainId}`),
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
<VerticalSideBarLayout title={pageTitle} description={ubiquitousLanguage.summary}>
|
|
71
|
+
<main class="flex sm:px-8 docs-layout h-full max-w-7xl">
|
|
72
|
+
<div class="flex docs-layout w-full">
|
|
73
|
+
<div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8 min-h-[50em]">
|
|
74
|
+
<nav class="flex mb-4" aria-label="Breadcrumb">
|
|
75
|
+
<ol class="inline-flex items-center space-x-1 md:space-x-3">
|
|
76
|
+
<li class="inline-flex items-center">
|
|
77
|
+
<a
|
|
78
|
+
href={buildUrl(`/docs/${props.type}/${props.domainId}/language`)}
|
|
79
|
+
class="inline-flex items-center text-sm font-medium text-gray-500 hover:text-primary"
|
|
80
|
+
>
|
|
81
|
+
<svg
|
|
82
|
+
class="w-3 h-3 mr-2.5"
|
|
83
|
+
aria-hidden="true"
|
|
84
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
85
|
+
fill="none"
|
|
86
|
+
viewBox="0 0 24 24"
|
|
87
|
+
stroke-width="2"
|
|
88
|
+
stroke="currentColor"
|
|
89
|
+
>
|
|
90
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"></path>
|
|
91
|
+
</svg>
|
|
92
|
+
Back to ubiquitous language List
|
|
93
|
+
</a>
|
|
94
|
+
</li>
|
|
95
|
+
</ol>
|
|
96
|
+
</nav>
|
|
97
|
+
|
|
98
|
+
<div class="border-b border-gray-200 flex justify-between items-start md:pb-2">
|
|
99
|
+
<div>
|
|
100
|
+
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-black">
|
|
101
|
+
{ubiquitousLanguage.name}
|
|
102
|
+
</h2>
|
|
103
|
+
<p class="text-lg pt-2 text-gray-500 font-light">{ubiquitousLanguage.summary}</p>
|
|
104
|
+
<!-- Add bage -->
|
|
105
|
+
{
|
|
106
|
+
badges && (
|
|
107
|
+
<div class="flex flex-wrap py-2 pt-4">
|
|
108
|
+
{badges.map((badge: any) => {
|
|
109
|
+
return (
|
|
110
|
+
<a href={badge.href || '#'} class="pb-2">
|
|
111
|
+
<span
|
|
112
|
+
id={badge.id || ''}
|
|
113
|
+
class={`text-sm font-light text-gray-500 px-2 py-1 rounded-md mr-2 bg-gradient-to-b from-${badge.backgroundColor}-100 to-${badge.backgroundColor}-200 space-x-1 border border-${badge.backgroundColor}-200 text-${badge.textColor}-800 flex items-center ${badge.class ? badge.class : ''} `}
|
|
114
|
+
>
|
|
115
|
+
{badge.icon && <badge.icon className="w-4 h-4 inline-block mr-1 " />}
|
|
116
|
+
{badge.iconURL && <img src={badge.iconURL} class="w-5 h-5 inline-block " />}
|
|
117
|
+
<span>{badge.content}</span>
|
|
118
|
+
</span>
|
|
119
|
+
</a>
|
|
120
|
+
);
|
|
121
|
+
})}
|
|
122
|
+
</div>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
{
|
|
129
|
+
ubiquitousLanguage.description && (
|
|
130
|
+
<div class="prose prose-md py-4 max-w-none" set:html={marked.parse(ubiquitousLanguage.description)} />
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
!ubiquitousLanguage.description && (
|
|
136
|
+
<div class="prose prose-md py-4 max-w-none">
|
|
137
|
+
<p>No description for {ubiquitousLanguage.name} available.</p>
|
|
138
|
+
</div>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
<Footer />
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<ClientRouter />
|
|
146
|
+
</main>
|
|
147
|
+
|
|
148
|
+
<script>
|
|
149
|
+
function initializeSearch() {
|
|
150
|
+
const searchInput = document.getElementById('searchInput');
|
|
151
|
+
const termCards = document.querySelectorAll('.term-card');
|
|
152
|
+
const noSearchResults = document.getElementById('noSearchResults');
|
|
153
|
+
|
|
154
|
+
searchInput?.addEventListener('input', (e) => {
|
|
155
|
+
const searchTerm = (e.target as HTMLInputElement).value.toLowerCase();
|
|
156
|
+
let visibleCount = 0;
|
|
157
|
+
|
|
158
|
+
termCards.forEach((card) => {
|
|
159
|
+
const title = card.querySelector('h3')?.textContent?.toLowerCase() || '';
|
|
160
|
+
const description = card.querySelector('p')?.textContent?.toLowerCase() || '';
|
|
161
|
+
const matches = title.includes(searchTerm) || description.includes(searchTerm);
|
|
162
|
+
|
|
163
|
+
card.classList.toggle('hidden', !matches);
|
|
164
|
+
if (matches) visibleCount++;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Show/hide no results message
|
|
168
|
+
if (noSearchResults) {
|
|
169
|
+
noSearchResults.classList.toggle('hidden', visibleCount > 0);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function initializeShowMore() {
|
|
175
|
+
const cards = document.querySelectorAll('.term-card');
|
|
176
|
+
|
|
177
|
+
cards.forEach((card) => {
|
|
178
|
+
const newCard = card.cloneNode(true);
|
|
179
|
+
if (card.parentNode) {
|
|
180
|
+
card.parentNode.replaceChild(newCard, card);
|
|
181
|
+
// Initially show summary
|
|
182
|
+
const summary = (newCard as Element).querySelector('.summary-text');
|
|
183
|
+
summary?.classList.add('visible');
|
|
184
|
+
}
|
|
185
|
+
newCard.addEventListener('click', () => {
|
|
186
|
+
const description = (newCard as Element).querySelector('.description-text');
|
|
187
|
+
const summary = (newCard as Element).querySelector('.summary-text');
|
|
188
|
+
const showMoreText = (newCard as Element).querySelector('.show-more-text');
|
|
189
|
+
|
|
190
|
+
if (description && summary && showMoreText) {
|
|
191
|
+
(newCard as Element).classList.toggle('expanded');
|
|
192
|
+
description.classList.toggle('visible');
|
|
193
|
+
summary.classList.toggle('visible');
|
|
194
|
+
showMoreText.textContent = description.classList.contains('visible') ? 'Show less' : 'Show more';
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function highlightMatchingTerm() {
|
|
201
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
202
|
+
const termId = urlParams.get('id');
|
|
203
|
+
|
|
204
|
+
if (termId) {
|
|
205
|
+
const cards = document.querySelectorAll('.term-card');
|
|
206
|
+
cards.forEach((card) => {
|
|
207
|
+
const termName = card.querySelector('h3')?.textContent?.trim();
|
|
208
|
+
if (termName?.toLowerCase() === termId.toLowerCase()) {
|
|
209
|
+
// Add highlight class
|
|
210
|
+
card.classList.add('highlighted');
|
|
211
|
+
(card as HTMLElement).click();
|
|
212
|
+
|
|
213
|
+
setTimeout(() => {
|
|
214
|
+
// Scroll into view
|
|
215
|
+
card.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
216
|
+
}, 300);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
document.addEventListener('astro:page-load', () => {
|
|
223
|
+
initializeShowMore();
|
|
224
|
+
initializeSearch();
|
|
225
|
+
highlightMatchingTerm();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
initializeShowMore();
|
|
229
|
+
initializeSearch();
|
|
230
|
+
highlightMatchingTerm();
|
|
231
|
+
</script>
|
|
232
|
+
</VerticalSideBarLayout>
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import Footer from '@layouts/Footer.astro';
|
|
3
3
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
4
4
|
import { getDomains, type Domain, getUbiquitousLanguage } from '@utils/collections/domains';
|
|
5
|
+
import { buildUrl } from '@utils/url-builder';
|
|
5
6
|
import type { CollectionEntry } from 'astro:content';
|
|
6
|
-
import {
|
|
7
|
+
import { ClientRouter } from 'astro:transitions';
|
|
7
8
|
import * as LucideIcons from 'lucide-react';
|
|
8
9
|
|
|
9
10
|
export async function getStaticPaths() {
|
|
@@ -40,7 +41,7 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
40
41
|
<ol class="inline-flex items-center space-x-1 md:space-x-3">
|
|
41
42
|
<li class="inline-flex items-center">
|
|
42
43
|
<a
|
|
43
|
-
href={`/docs/${props.type}/${props.data.id}/${props.data.latestVersion}`}
|
|
44
|
+
href={buildUrl(`/docs/${props.type}/${props.data.id}/${props.data.latestVersion}`)}
|
|
44
45
|
class="inline-flex items-center text-sm font-medium text-gray-500 hover:text-primary"
|
|
45
46
|
>
|
|
46
47
|
<svg
|
|
@@ -99,7 +100,7 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
99
100
|
) : (
|
|
100
101
|
<div id="termsGrid" class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
101
102
|
{ubiquitousLanguage?.data?.dictionary?.map((term) => (
|
|
102
|
-
<div class="term-card block bg-white border border-gray-200 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]
|
|
103
|
+
<div class="term-card block bg-white border border-gray-200 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]">
|
|
103
104
|
<div class="flex flex-col h-full space-y-8">
|
|
104
105
|
{term.icon && (
|
|
105
106
|
<div>
|
|
@@ -119,11 +120,13 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
119
120
|
{term.summary}
|
|
120
121
|
</p>
|
|
121
122
|
{term.description && (
|
|
122
|
-
<div>
|
|
123
|
-
<
|
|
124
|
-
{term.
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
<div class="prose prose-sm prose-p:my-3">
|
|
124
|
+
<a
|
|
125
|
+
href={buildUrl(`/docs/${props.type}/${props.data.id}/language/${term.id}`)}
|
|
126
|
+
class="show-more-text text-sm text-primary font-medium hover:underline"
|
|
127
|
+
>
|
|
128
|
+
Read more
|
|
129
|
+
</a>
|
|
127
130
|
</div>
|
|
128
131
|
)}
|
|
129
132
|
</div>
|
|
@@ -146,7 +149,7 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
146
149
|
<Footer />
|
|
147
150
|
</div>
|
|
148
151
|
</div>
|
|
149
|
-
<
|
|
152
|
+
<ClientRouter />
|
|
150
153
|
</main>
|
|
151
154
|
|
|
152
155
|
<script>
|
|
@@ -177,27 +180,11 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
177
180
|
|
|
178
181
|
function initializeShowMore() {
|
|
179
182
|
const cards = document.querySelectorAll('.term-card');
|
|
180
|
-
|
|
181
183
|
cards.forEach((card) => {
|
|
182
|
-
const
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
// Initially show summary
|
|
186
|
-
const summary = (newCard as Element).querySelector('.summary-text');
|
|
187
|
-
summary?.classList.add('visible');
|
|
184
|
+
const summary = card.querySelector('.summary-text');
|
|
185
|
+
if (summary) {
|
|
186
|
+
summary.classList.add('visible');
|
|
188
187
|
}
|
|
189
|
-
newCard.addEventListener('click', () => {
|
|
190
|
-
const description = (newCard as Element).querySelector('.description-text');
|
|
191
|
-
const summary = (newCard as Element).querySelector('.summary-text');
|
|
192
|
-
const showMoreText = (newCard as Element).querySelector('.show-more-text');
|
|
193
|
-
|
|
194
|
-
if (description && summary && showMoreText) {
|
|
195
|
-
(newCard as Element).classList.toggle('expanded');
|
|
196
|
-
description.classList.toggle('visible');
|
|
197
|
-
summary.classList.toggle('visible');
|
|
198
|
-
showMoreText.textContent = description.classList.contains('visible') ? 'Show less' : 'Show more';
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
188
|
});
|
|
202
189
|
}
|
|
203
190
|
|
|
@@ -240,42 +227,14 @@ const ubiquitousLanguage = ubiquitousLanguages[0];
|
|
|
240
227
|
min-height: 12em;
|
|
241
228
|
}
|
|
242
229
|
|
|
243
|
-
.
|
|
244
|
-
min-height: 24em;
|
|
245
|
-
background-color: rgb(249 250 251);
|
|
246
|
-
z-index: 10;
|
|
247
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.summary-text,
|
|
251
|
-
.description-text {
|
|
252
|
-
transition:
|
|
253
|
-
opacity 0.3s ease-in-out,
|
|
254
|
-
max-height 0.3s ease-in-out;
|
|
255
|
-
opacity: 0;
|
|
256
|
-
max-height: 0;
|
|
257
|
-
overflow: hidden;
|
|
258
|
-
display: none;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
.summary-text.visible,
|
|
262
|
-
.description-text.visible {
|
|
230
|
+
.summary-text {
|
|
263
231
|
opacity: 1;
|
|
264
|
-
max-height:
|
|
265
|
-
margin-bottom: 1rem;
|
|
266
|
-
display: block;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.description-text {
|
|
270
|
-
white-space: pre-line;
|
|
271
|
-
line-height: 1.5;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.show-more-text {
|
|
232
|
+
max-height: unset;
|
|
275
233
|
display: block;
|
|
276
|
-
margin-top: 0.5rem;
|
|
277
234
|
}
|
|
278
235
|
|
|
236
|
+
.description-text,
|
|
237
|
+
.term-card.expanded,
|
|
279
238
|
.term-card.expanded .show-more-text {
|
|
280
239
|
display: none;
|
|
281
240
|
}
|
|
@@ -6,7 +6,7 @@ import { getFlows } from '@utils/collections/flows';
|
|
|
6
6
|
import { buildUrl } from '@utils/url-builder';
|
|
7
7
|
|
|
8
8
|
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
9
|
-
import {
|
|
9
|
+
import { ClientRouter } from 'astro:transitions';
|
|
10
10
|
type PageTypesWithFlows = PageTypes | 'flows';
|
|
11
11
|
|
|
12
12
|
export async function getStaticPaths() {
|
|
@@ -58,7 +58,7 @@ const {
|
|
|
58
58
|
}}
|
|
59
59
|
/>
|
|
60
60
|
</div>
|
|
61
|
-
<
|
|
61
|
+
<ClientRouter />
|
|
62
62
|
</VisualiserLayout>
|
|
63
63
|
|
|
64
64
|
<script define:vars={{ id }}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
|
|
3
|
-
import {
|
|
3
|
+
import { ClientRouter } from 'astro:transitions';
|
|
4
4
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -26,5 +26,5 @@ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
|
26
26
|
}}
|
|
27
27
|
/>
|
|
28
28
|
</div>
|
|
29
|
-
<
|
|
29
|
+
<ClientRouter />
|
|
30
30
|
</VerticalSideBarLayout>
|
|
@@ -8,7 +8,7 @@ export const getChangeLogs = async (item: CollectionEntry<CollectionTypes>): Pro
|
|
|
8
8
|
|
|
9
9
|
// Get all logs for collection type and filter by given collection
|
|
10
10
|
const logs = await getCollection('changelogs', (log) => {
|
|
11
|
-
return log.id.includes(`${collection}/`) && log.
|
|
11
|
+
return log.id.includes(`${collection}/`) && log.slug.includes(slug);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
const hydratedLogs = logs.map((log) => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
2
|
+
|
|
3
|
+
const getOwners = (function () {
|
|
4
|
+
type Owners = CollectionEntry<'users' | 'teams'>;
|
|
5
|
+
let cachedOwners: Map<string, Owners> | null = null;
|
|
6
|
+
let initializingPromise: Promise<Map<string, Owners>> | null = null;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Initializes and caches the owners by fetching from the 'users' and 'teams' collections.
|
|
10
|
+
*/
|
|
11
|
+
async function init() {
|
|
12
|
+
const ownersMap = new Map<string, CollectionEntry<'users' | 'teams'>>();
|
|
13
|
+
|
|
14
|
+
const owners = await Promise.all([
|
|
15
|
+
getCollection('users', (entry) => entry.data.hidden !== true),
|
|
16
|
+
getCollection('teams', (entry) => entry.data.hidden !== true),
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
for (const owner of owners.flat()) {
|
|
20
|
+
ownersMap.set(owner.data.id, owner);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
cachedOwners = ownersMap;
|
|
24
|
+
initializingPromise = null;
|
|
25
|
+
|
|
26
|
+
return cachedOwners;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return () =>
|
|
30
|
+
cachedOwners || // Return cached owners if already initialized
|
|
31
|
+
initializingPromise || // Return the promise if initialization is in progress
|
|
32
|
+
(initializingPromise = init()); // Initialize if neither cache nor promise exists
|
|
33
|
+
})();
|
|
34
|
+
|
|
35
|
+
export async function getOwner(lookup: { id: string }): Promise<CollectionEntry<'users' | 'teams'> | undefined> {
|
|
36
|
+
const lookupId = typeof lookup === 'string' ? lookup : lookup.id;
|
|
37
|
+
|
|
38
|
+
const owner = (await getOwners()).get(lookupId);
|
|
39
|
+
|
|
40
|
+
if (!owner) console.warn(`Entry ${lookupId} not found in "teams"/"users" collections.`);
|
|
41
|
+
|
|
42
|
+
return owner;
|
|
43
|
+
}
|