@eventcatalog/core 4.10.11 → 4.10.13
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-N6U5CNT7.js → chunk-34RMFKFB.js} +1 -1
- package/dist/{chunk-TWZKZIRW.js → chunk-IIECZFXN.js} +1 -1
- package/dist/{chunk-RLGMIZSH.js → chunk-JHUICVBT.js} +1 -1
- package/dist/{chunk-3XTFNVGA.js → chunk-PADMH2RJ.js} +1 -1
- package/dist/{chunk-VFRR3M72.js → chunk-SSSN5FXC.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.config.d.cts +9 -0
- package/dist/eventcatalog.config.d.ts +9 -0
- package/dist/eventcatalog.js +5 -5
- 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 +2 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +208 -119
- package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +28 -8
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +45 -0
- package/eventcatalog/src/components/Header.astro +11 -6
- package/eventcatalog/src/components/MDX/Design/Design.astro +2 -2
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -2
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -2
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +2 -2
- package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +22 -40
- package/eventcatalog/src/components/Search/Search.astro +11 -4
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +29 -24
- package/eventcatalog/src/content.config.ts +1 -1
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +3 -3
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +5 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +10 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +3 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +2 -2
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -2
- package/eventcatalog/src/plugins/link-validation.ts +42 -0
- package/eventcatalog/src/utils/collections/glob-loader.spec.ts +69 -2
- package/eventcatalog/src/utils/collections/glob-loader.ts +5 -3
- package/eventcatalog/src/utils/collections/schema-loader.ts +1 -1
- package/eventcatalog/src/utils/feature.ts +1 -0
- package/eventcatalog/src/utils/link-validation.ts +224 -0
- package/eventcatalog/src/utils/resource-reference-links.ts +29 -0
- package/package.json +5 -4
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { Sparkles } from 'lucide-react';
|
|
3
3
|
import ChatPanel from './ChatPanel';
|
|
4
4
|
|
|
5
|
-
const ChatPanelButton = () => {
|
|
5
|
+
const ChatPanelButton = ({ configured = false }: { configured?: boolean }) => {
|
|
6
6
|
const [isOpen, setIsOpen] = useState(false);
|
|
7
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
8
|
+
const closePanel = useCallback(() => {
|
|
9
|
+
setIsOpen(false);
|
|
10
|
+
buttonRef.current?.focus();
|
|
11
|
+
}, []);
|
|
12
|
+
const [shortcut, setShortcut] = useState('⌘I');
|
|
7
13
|
|
|
8
14
|
// Listen for custom event to open chat panel from other components
|
|
9
15
|
useEffect(() => {
|
|
@@ -11,22 +17,36 @@ const ChatPanelButton = () => {
|
|
|
11
17
|
setIsOpen(true);
|
|
12
18
|
};
|
|
13
19
|
|
|
20
|
+
setShortcut(/Mac|iPhone|iPad/.test(navigator.platform) ? '⌘I' : 'Ctrl I');
|
|
21
|
+
const handleShortcut = (event: KeyboardEvent) => {
|
|
22
|
+
if ((event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey && event.key.toLowerCase() === 'i') {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
setIsOpen(true);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
window.addEventListener('keydown', handleShortcut);
|
|
14
28
|
window.addEventListener('eventcatalog:open-chat', handleOpenChat);
|
|
15
|
-
return () =>
|
|
29
|
+
return () => {
|
|
30
|
+
window.removeEventListener('keydown', handleShortcut);
|
|
31
|
+
window.removeEventListener('eventcatalog:open-chat', handleOpenChat);
|
|
32
|
+
};
|
|
16
33
|
}, []);
|
|
17
34
|
|
|
18
35
|
return (
|
|
19
36
|
<>
|
|
20
37
|
<button
|
|
38
|
+
ref={buttonRef}
|
|
21
39
|
onClick={() => setIsOpen(true)}
|
|
22
|
-
className="flex items-center gap-1.5 px-4
|
|
40
|
+
className="flex h-9 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-4 rounded-md bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-content-hover))] ring-1 ring-inset ring-[rgb(var(--ec-page-border))] shadow-xs transition-colors text-sm"
|
|
23
41
|
aria-label="Open AI Assistant"
|
|
42
|
+
aria-keyshortcuts="Meta+i Control+i"
|
|
43
|
+
title={`Open Event Catalog Assistant (${shortcut})`}
|
|
24
44
|
>
|
|
25
|
-
<
|
|
26
|
-
<span className="font-light text-
|
|
45
|
+
<Sparkles size={16} className="shrink-0 text-gray-500" aria-hidden="true" />
|
|
46
|
+
<span className="font-light text-gray-500">Ask</span>
|
|
27
47
|
</button>
|
|
28
48
|
|
|
29
|
-
<ChatPanel isOpen={isOpen} onClose={
|
|
49
|
+
<ChatPanel configured={configured} isOpen={isOpen} onClose={closePanel} />
|
|
30
50
|
</>
|
|
31
51
|
);
|
|
32
52
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ArrowUpRight } from 'lucide-react';
|
|
2
|
+
import { buildUrl } from '@utils/url-builder';
|
|
3
|
+
|
|
4
|
+
const setupUrl = 'https://www.eventcatalog.dev/docs/development/ask-your-architecture/eventcatalog-assistant/configuration';
|
|
5
|
+
const introduction = 'Your whole catalog, connected to your AI.';
|
|
6
|
+
const description =
|
|
7
|
+
'Bring your own model and I can help you understand your services, trace how events flow, and explore the impact of a change across your whole catalog.';
|
|
8
|
+
const privacy = 'You choose where your data is processed: on your own infrastructure or with a model provider you trust.';
|
|
9
|
+
const setup = 'I’m not connected to a model yet. Your catalog owner can connect one to get started.';
|
|
10
|
+
|
|
11
|
+
export const offlineReplyText = `${introduction}\n\n${description}\n\n${privacy}\n\n${setup}`;
|
|
12
|
+
|
|
13
|
+
export default function OfflineReply() {
|
|
14
|
+
return (
|
|
15
|
+
<div className="ec-chat-offline w-full space-y-4 py-2 text-[13px] leading-relaxed text-[rgb(var(--ec-content-text))]">
|
|
16
|
+
<div className="space-y-2">
|
|
17
|
+
<p className="text-base font-medium leading-snug text-[rgb(var(--ec-page-text))]">{introduction}</p>
|
|
18
|
+
<p>{description}</p>
|
|
19
|
+
</div>
|
|
20
|
+
<div className="space-y-3 rounded-xl border border-[rgb(var(--ec-accent)/0.15)] bg-[rgb(var(--ec-accent)/0.04)] p-4">
|
|
21
|
+
<div className="space-y-1">
|
|
22
|
+
<p className="font-medium text-[rgb(var(--ec-page-text))]">Your model. Your control.</p>
|
|
23
|
+
<p className="text-[rgb(var(--ec-page-text-muted))]">{privacy}</p>
|
|
24
|
+
</div>
|
|
25
|
+
<p>{setup}</p>
|
|
26
|
+
<a
|
|
27
|
+
href={setupUrl}
|
|
28
|
+
target="_blank"
|
|
29
|
+
rel="noreferrer"
|
|
30
|
+
className="inline-flex items-center gap-2 rounded-lg bg-[rgb(var(--ec-accent))] px-3 py-2 text-xs font-medium text-white transition-colors hover:bg-[rgb(var(--ec-accent-hover))] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[rgb(var(--ec-accent))]"
|
|
31
|
+
>
|
|
32
|
+
Connect your model
|
|
33
|
+
<ArrowUpRight size={14} aria-hidden="true" />
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
<p className="text-xs leading-relaxed text-[rgb(var(--ec-page-text-muted))]">
|
|
37
|
+
Don’t need the assistant?{' '}
|
|
38
|
+
<a href={buildUrl('/settings/assistant')} className="underline underline-offset-2 hover:text-[rgb(var(--ec-page-text))]">
|
|
39
|
+
Turn off Event Catalog Assistant
|
|
40
|
+
</a>{' '}
|
|
41
|
+
or set <code className="text-[11px]">chat.enabled: false</code> in your catalog configuration.
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
import catalog from '@utils/eventcatalog-config/catalog';
|
|
3
3
|
import Search from '@components/Search/Search.astro';
|
|
4
4
|
import { buildUrl } from '@utils/url-builder';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
showEventCatalogBranding,
|
|
7
|
+
showCustomBranding,
|
|
8
|
+
isEventCatalogChatVisible,
|
|
9
|
+
isEventCatalogChatEnabled,
|
|
10
|
+
} from '@utils/feature';
|
|
6
11
|
import { getSession } from 'auth-astro/server';
|
|
7
12
|
import { isAuthEnabled, isSSR } from '@utils/feature';
|
|
8
13
|
import { EnvironmentDropdown } from './EnvironmentDropdown';
|
|
@@ -33,15 +38,15 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
|
|
|
33
38
|
: 'left: var(--ec-vertical-nav-width, 14rem);'}
|
|
34
39
|
>
|
|
35
40
|
<div class="px-6">
|
|
36
|
-
<div class="flex justify-between items-center">
|
|
37
|
-
<div class="
|
|
38
|
-
<div class="w-
|
|
41
|
+
<div class="flex justify-between items-center gap-4">
|
|
42
|
+
<div class="flex min-w-0 flex-1 items-center gap-3">
|
|
43
|
+
<div class="hidden lg:block min-w-0 flex-1 max-w-xl">
|
|
39
44
|
<Search />
|
|
40
45
|
</div>
|
|
41
|
-
{
|
|
46
|
+
{isEventCatalogChatVisible() && <ChatPanelButton configured={isEventCatalogChatEnabled()} client:idle />}
|
|
42
47
|
</div>
|
|
43
48
|
|
|
44
|
-
<div class="hidden md:block
|
|
49
|
+
<div class="hidden md:block shrink-0 ml-auto">
|
|
45
50
|
{
|
|
46
51
|
session ? (
|
|
47
52
|
<div class="flex items-center space-x-4 justify-end pr-2">
|
|
@@ -7,10 +7,10 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
7
7
|
// Visualiser styles ship in the page head so ClientRouter navigations keep them (see NodeGraph.astro).
|
|
8
8
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
9
9
|
|
|
10
|
-
import { isVisualiserEnabled,
|
|
10
|
+
import { isVisualiserEnabled, isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
11
11
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
12
12
|
|
|
13
|
-
const isChatEnabled =
|
|
13
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
14
14
|
|
|
15
15
|
let design: any;
|
|
16
16
|
let id = 'design';
|
|
@@ -7,10 +7,10 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
7
7
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
8
8
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
9
9
|
import { getServices } from '@utils/collections/services';
|
|
10
|
-
import {
|
|
10
|
+
import { isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
11
11
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
12
12
|
|
|
13
|
-
const isChatEnabled =
|
|
13
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
14
14
|
|
|
15
15
|
const { id, version = 'latest', maxHeight, includeKey = true, entities, collection = 'domains', ...rest } = Astro.props;
|
|
16
16
|
let resource = null;
|
|
@@ -6,12 +6,12 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
6
6
|
// Visualiser styles ship in the page head so ClientRouter navigations keep them (see NodeGraph.astro).
|
|
7
7
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
8
8
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
9
|
-
import { isVisualiserEnabled,
|
|
9
|
+
import { isVisualiserEnabled, isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
10
10
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
11
11
|
import { randomUUID } from 'node:crypto';
|
|
12
12
|
import { parseMdxBooleanProp } from '@utils/markdown';
|
|
13
13
|
|
|
14
|
-
const isChatEnabled =
|
|
14
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
15
15
|
|
|
16
16
|
const { id, version = 'latest', maxHeight, mode = 'simple' } = Astro.props;
|
|
17
17
|
const includeKey = parseMdxBooleanProp(Astro.props.legend ?? Astro.props.includeKey, true);
|
|
@@ -29,11 +29,11 @@ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
|
29
29
|
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
|
|
30
30
|
import { getNodesAndEdges as getNodesAndEdgesForChannel } from '@utils/node-graphs/channel-node-graph';
|
|
31
31
|
import config from '@config';
|
|
32
|
-
import {
|
|
32
|
+
import { isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
33
33
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
34
34
|
import { compactVisualiserGraph } from '@utils/node-graphs/compact-visualiser-graph';
|
|
35
35
|
|
|
36
|
-
const isChatEnabled =
|
|
36
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
37
37
|
|
|
38
38
|
interface Props {
|
|
39
39
|
id: string;
|
|
@@ -16,6 +16,12 @@ import { getCollection } from 'astro:content';
|
|
|
16
16
|
import { getServiceSpecifications, getSpecUrl, getSpecLabel } from '@components/Grids/specification-utils';
|
|
17
17
|
import { getResourceReferenceStyle } from '@utils/resource-reference-colors';
|
|
18
18
|
import { isIconPath, resolveIconUrl } from '@utils/icon';
|
|
19
|
+
import {
|
|
20
|
+
getResourceReferenceUrl,
|
|
21
|
+
isVersionedReference,
|
|
22
|
+
resolveMessageReference,
|
|
23
|
+
resolveOwnerReference,
|
|
24
|
+
} from '@utils/resource-reference-links';
|
|
19
25
|
|
|
20
26
|
interface Props {
|
|
21
27
|
type:
|
|
@@ -157,18 +163,16 @@ try {
|
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
const resourcesCollection = (await getCollection(collection as any)) as { data: { id: string; version: string } }[];
|
|
160
|
-
const resources =
|
|
166
|
+
const resources = isVersionedReference(collection)
|
|
167
|
+
? getItemsFromCollectionByIdAndSemverOrLatest(resourcesCollection, resourceId, version)
|
|
168
|
+
: resourcesCollection.filter((item) => item.data.id === resourceId);
|
|
161
169
|
|
|
162
170
|
if (resources.length === 0) {
|
|
163
171
|
throw new Error(`Resource not found: ${resourceId}`);
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
resource = resources[0];
|
|
167
|
-
|
|
168
|
-
href =
|
|
169
|
-
type === 'diagram'
|
|
170
|
-
? buildUrl(`/diagrams/${resourceId}/${resource.data.version}`)
|
|
171
|
-
: buildUrl(`/docs/${collection}/${resourceId}/${resource.data.version}`);
|
|
175
|
+
href = getResourceReferenceUrl(collection, resourceId, resource.data.version);
|
|
172
176
|
}
|
|
173
177
|
} catch (error) {
|
|
174
178
|
hasError = true;
|
|
@@ -180,7 +184,7 @@ const maxSummaryLength = 120;
|
|
|
180
184
|
const summary = resource?.data?.summary || '';
|
|
181
185
|
const truncatedSummary = summary.length > maxSummaryLength ? summary.slice(0, maxSummaryLength) + '...' : summary;
|
|
182
186
|
|
|
183
|
-
const isVersionedResource = type !== 'doc';
|
|
187
|
+
const isVersionedResource = type !== 'doc' && isVersionedReference(collection);
|
|
184
188
|
|
|
185
189
|
// Only these types have visualizers
|
|
186
190
|
const hasVisualizer = ['agent', 'domain', 'service', 'event', 'query', 'command', 'container', 'system'].includes(type);
|
|
@@ -191,7 +195,7 @@ const isDeprecated = deprecation?.isMarkedAsDeprecated || false;
|
|
|
191
195
|
const resourceIconUrl = isIconPath(resource?.data?.styles?.icon) ? resolveIconUrl(resource.data.styles.icon) : null;
|
|
192
196
|
|
|
193
197
|
// Get owners (first 2)
|
|
194
|
-
const owners = resource?.data?.owners?.slice(0, 2) || [];
|
|
198
|
+
const owners = await Promise.all((resource?.data?.owners?.slice(0, 2) || []).map(resolveOwnerReference));
|
|
195
199
|
|
|
196
200
|
// Check if message type has a schema
|
|
197
201
|
const isMessageType = ['event', 'command', 'query'].includes(type);
|
|
@@ -207,39 +211,16 @@ const receives = resource?.data?.receives || [];
|
|
|
207
211
|
const isService = type === 'service' || type === 'agent';
|
|
208
212
|
const supportsSpecifications = type === 'service';
|
|
209
213
|
|
|
210
|
-
// Helper to resolve message version and collection - use specified version or fetch from collection
|
|
211
|
-
const resolveMessage = async (msg: any): Promise<{ version: string | null; collection: string | null }> => {
|
|
212
|
-
// If version is specified and not "latest", use it (assume event as default collection)
|
|
213
|
-
if (msg.version && msg.version !== 'latest') {
|
|
214
|
-
return { version: msg.version, collection: 'events' };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Try to find the message in events, commands, or queries collections
|
|
218
|
-
const collections = ['events', 'commands', 'queries'];
|
|
219
|
-
for (const col of collections) {
|
|
220
|
-
try {
|
|
221
|
-
const items = (await getCollection(col as any)) as { data: { id: string; version: string } }[];
|
|
222
|
-
const found = getItemsFromCollectionByIdAndSemverOrLatest(items, msg.id);
|
|
223
|
-
if (found.length > 0 && found[0].data.version && found[0].data.version !== 'latest') {
|
|
224
|
-
return { version: found[0].data.version, collection: col };
|
|
225
|
-
}
|
|
226
|
-
} catch (e) {
|
|
227
|
-
// Collection might not exist or item not found, continue
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
return { version: null, collection: null };
|
|
231
|
-
};
|
|
232
|
-
|
|
233
214
|
// Resolve versions and collections for messages to show
|
|
234
215
|
const sendsWithVersions = await Promise.all(
|
|
235
216
|
sends.slice(0, maxMessages).map(async (msg: any) => {
|
|
236
|
-
const resolved = await
|
|
217
|
+
const resolved = await resolveMessageReference(msg);
|
|
237
218
|
return { ...msg, resolvedVersion: resolved.version, resolvedCollection: resolved.collection };
|
|
238
219
|
})
|
|
239
220
|
);
|
|
240
221
|
const receivesWithVersions = await Promise.all(
|
|
241
222
|
receives.slice(0, maxMessages).map(async (msg: any) => {
|
|
242
|
-
const resolved = await
|
|
223
|
+
const resolved = await resolveMessageReference(msg);
|
|
243
224
|
return { ...msg, resolvedVersion: resolved.version, resolvedCollection: resolved.collection };
|
|
244
225
|
})
|
|
245
226
|
);
|
|
@@ -422,15 +403,16 @@ const tooltipId = `ref-tooltip-${Math.random().toString(36).slice(2, 9)}`;
|
|
|
422
403
|
<span class="text-[rgb(var(--ec-page-text-muted))]">Owner</span>
|
|
423
404
|
<span class="font-mono text-[rgb(var(--ec-page-text))]">
|
|
424
405
|
{owners.map((o: any, idx: number) => {
|
|
425
|
-
const ownerId =
|
|
406
|
+
const ownerId = o.id;
|
|
426
407
|
return (
|
|
427
408
|
<>
|
|
428
|
-
|
|
429
|
-
href={
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
409
|
+
{o.href ? (
|
|
410
|
+
<a href={o.href} class="hover:underline hover:text-[rgb(var(--ec-accent))]">
|
|
411
|
+
{ownerId}
|
|
412
|
+
</a>
|
|
413
|
+
) : (
|
|
414
|
+
<span>{ownerId}</span>
|
|
415
|
+
)}
|
|
434
416
|
{idx < owners.length - 1 && ', '}
|
|
435
417
|
</>
|
|
436
418
|
);
|
|
@@ -4,18 +4,25 @@ import SearchModal from './SearchModal.tsx';
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<div>
|
|
7
|
-
<div class="relative flex items-center w-full
|
|
7
|
+
<div class="relative flex min-w-0 items-center w-full">
|
|
8
8
|
<input
|
|
9
9
|
id="search-dummy-input"
|
|
10
10
|
type="text"
|
|
11
11
|
name="search"
|
|
12
12
|
placeholder="Search EventCatalog"
|
|
13
13
|
autocomplete="off"
|
|
14
|
-
class="block w-full rounded-md caret-transparent border-0 py-1.5 pr-
|
|
14
|
+
class="block h-9 min-w-0 w-full rounded-md caret-transparent border-0 py-1.5 pr-20 pl-10! text-[rgb(var(--ec-header-text))] bg-[rgb(var(--ec-header-bg))] shadow-xs ring-1 ring-inset ring-[rgb(var(--ec-dropdown-border))] placeholder:text-gray-400 font-light sm:text-sm sm:leading-6"
|
|
15
15
|
/>
|
|
16
16
|
<MagnifyingGlassIcon className="absolute inset-y-0 left-0 h-9 w-8 flex items-center pl-4 text-[rgb(var(--ec-icon-color))]" />
|
|
17
|
-
<div class="absolute inset-y-0 right-0 flex
|
|
18
|
-
<kbd
|
|
17
|
+
<div class="absolute inset-y-0 right-0 flex items-center gap-1 pr-2 pointer-events-none">
|
|
18
|
+
<kbd
|
|
19
|
+
class="inline-flex h-6 min-w-6 items-center justify-center rounded-lg border border-[rgb(var(--ec-dropdown-border))] bg-[rgb(var(--ec-card-bg))] px-1 font-sans text-xs font-normal text-[rgb(var(--ec-icon-color))] shadow-xs"
|
|
20
|
+
>⌘</kbd
|
|
21
|
+
>
|
|
22
|
+
<kbd
|
|
23
|
+
class="inline-flex h-6 min-w-6 items-center justify-center rounded-lg border border-[rgb(var(--ec-dropdown-border))] bg-[rgb(var(--ec-card-bg))] px-1 font-sans text-xs font-normal text-[rgb(var(--ec-icon-color))] shadow-xs"
|
|
24
|
+
>K</kbd
|
|
25
|
+
>
|
|
19
26
|
</div>
|
|
20
27
|
</div>
|
|
21
28
|
</div>
|
|
@@ -76,34 +76,39 @@ export const AssistantSettingsForm = ({ canEdit, initial, chatAvailable, hasPlan
|
|
|
76
76
|
<Row
|
|
77
77
|
title="Assistant Agent"
|
|
78
78
|
description="Assistant agent that answers questions about your architecture directly in your catalog."
|
|
79
|
-
canEdit={canEdit
|
|
79
|
+
canEdit={canEdit}
|
|
80
80
|
dirty={dirty}
|
|
81
81
|
saving={saving}
|
|
82
|
-
onSave={
|
|
82
|
+
onSave={save}
|
|
83
83
|
>
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
) : !hasPlan ? (
|
|
97
|
-
<UpgradeRequired
|
|
98
|
-
tier="Starter and Scale"
|
|
99
|
-
blurb="The EventCatalog Assistant is part of our paid plans. Upgrade to give your team a built-in AI agent that answers questions about your architecture."
|
|
100
|
-
docsUrl={ASSISTANT_DOCS_URL}
|
|
84
|
+
<div className="space-y-3">
|
|
85
|
+
<ToggleRow
|
|
86
|
+
icon={<MessageSquare className="h-4 w-4" aria-hidden />}
|
|
87
|
+
label={chatEnabled ? 'Enabled' : 'Disabled'}
|
|
88
|
+
hint={
|
|
89
|
+
chatEnabled
|
|
90
|
+
? 'Event Catalog Assistant is visible in this catalog.'
|
|
91
|
+
: 'Event Catalog Assistant is hidden from this catalog.'
|
|
92
|
+
}
|
|
93
|
+
checked={chatEnabled}
|
|
94
|
+
disabled={!canEdit}
|
|
95
|
+
onChange={setChatEnabled}
|
|
101
96
|
/>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
{chatEnabled &&
|
|
98
|
+
(chatAvailable ? (
|
|
99
|
+
<ConfigurationRequired />
|
|
100
|
+
) : !hasPlan ? (
|
|
101
|
+
<UpgradeRequired
|
|
102
|
+
tier="Starter and Scale"
|
|
103
|
+
blurb="The EventCatalog Assistant is part of our paid plans. Upgrade to give your team a built-in AI agent that answers questions about your architecture."
|
|
104
|
+
docsUrl={ASSISTANT_DOCS_URL}
|
|
105
|
+
/>
|
|
106
|
+
) : !inSSR ? (
|
|
107
|
+
<AssistantNeedsSSR />
|
|
108
|
+
) : !hasChatConfigFile ? (
|
|
109
|
+
<AssistantNeedsConfigFile />
|
|
110
|
+
) : null)}
|
|
111
|
+
</div>
|
|
107
112
|
</Row>
|
|
108
113
|
</form>
|
|
109
114
|
);
|
|
@@ -1107,7 +1107,7 @@ const teams = defineCollection({
|
|
|
1107
1107
|
|
|
1108
1108
|
const designs = defineCollection({
|
|
1109
1109
|
loader: async () => {
|
|
1110
|
-
const data = await globPackage('**/**/*.ecstudio', { cwd: projectDirBase, ignore: ['dist/**'] });
|
|
1110
|
+
const data = await globPackage('**/**/*.ecstudio', { cwd: projectDirBase, ignore: ['dist/**', '**/node_modules/**'] });
|
|
1111
1111
|
// File all the files in the designs folder
|
|
1112
1112
|
// Limit 3 designs community edition?
|
|
1113
1113
|
const files = data.reduce<{ id: string; name: string }[]>((acc, filePath) => {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
isVisualiserEnabled,
|
|
22
22
|
isMarkdownDownloadEnabled,
|
|
23
23
|
isRSSEnabled,
|
|
24
|
-
|
|
24
|
+
isEventCatalogChatVisible,
|
|
25
25
|
isArchitectureGraphEnabled,
|
|
26
26
|
} from '@utils/feature';
|
|
27
27
|
|
|
@@ -152,11 +152,11 @@ const editUrl =
|
|
|
152
152
|
client:only="react"
|
|
153
153
|
variant="toolbar"
|
|
154
154
|
schemas={[]}
|
|
155
|
-
chatEnabled={
|
|
155
|
+
chatEnabled={isEventCatalogChatVisible()}
|
|
156
156
|
markdownDownloadEnabled={isMarkdownDownloadEnabled()}
|
|
157
157
|
rssFeedEnabled={isRSSEnabled()}
|
|
158
158
|
editUrl={editUrl}
|
|
159
|
-
preferChatAsDefault={
|
|
159
|
+
preferChatAsDefault={isEventCatalogChatVisible()}
|
|
160
160
|
/>
|
|
161
161
|
</div>
|
|
162
162
|
</div>
|
|
@@ -7,7 +7,7 @@ import config from '@config';
|
|
|
7
7
|
import { buildUrl } from '@utils/url-builder';
|
|
8
8
|
import { GitCompare, X, AlignLeft, HistoryIcon } from 'lucide-react';
|
|
9
9
|
import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
10
|
-
import { isLLMSTxtEnabled,
|
|
10
|
+
import { isLLMSTxtEnabled, isEventCatalogChatVisible } from '@utils/feature';
|
|
11
11
|
|
|
12
12
|
import { Page } from './_index.data';
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ const pageTitle = `Diagram | ${props.data.name}`;
|
|
|
21
21
|
const currentVersion = props.data.version;
|
|
22
22
|
const allVersions = props.allVersions || [currentVersion];
|
|
23
23
|
const hasMultipleVersions = allVersions.length > 1;
|
|
24
|
-
const chatEnabled =
|
|
24
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
25
25
|
const markdownDownloadEnabled = isLLMSTxtEnabled();
|
|
26
26
|
const chatQuery = `Tell me about the "${props.data.name}" diagram (version ${props.data.version})`;
|
|
27
27
|
---
|
package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro
CHANGED
|
@@ -8,7 +8,7 @@ import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
|
8
8
|
import Badge from '@components/Badge.astro';
|
|
9
9
|
import { buildUrl } from '@utils/url-builder';
|
|
10
10
|
import { AlignLeftIcon, HistoryIcon } from 'lucide-react';
|
|
11
|
-
import {
|
|
11
|
+
import { isEventCatalogChatVisible, isMarkdownDownloadEnabled, isResourceDocsEnabled } from '@utils/feature';
|
|
12
12
|
import { getResourceDocTypeLabel } from '@utils/collections/resource-docs';
|
|
13
13
|
import { getIcon } from '@utils/badges';
|
|
14
14
|
import { collectionToResourceMap } from '@utils/collections/util';
|
|
@@ -37,7 +37,7 @@ const docsBasePath = `/docs/${props.data.resourceCollection}/${props.data.resour
|
|
|
37
37
|
const singularResourceName =
|
|
38
38
|
collectionToResourceMap[props.data.resourceCollection as keyof typeof collectionToResourceMap] ??
|
|
39
39
|
props.data.resourceCollection.slice(0, props.data.resourceCollection.length - 1);
|
|
40
|
-
const chatEnabled =
|
|
40
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
41
41
|
const chatQuery = `Tell me about the ${props.data.type} doc "${title}" for ${props.data.resourceId} (version ${props.data.version})`;
|
|
42
42
|
|
|
43
43
|
const pagefindAttributes =
|
|
@@ -69,7 +69,9 @@ const pagefindAttributes =
|
|
|
69
69
|
{
|
|
70
70
|
badges.length > 0 && (
|
|
71
71
|
<div class="flex flex-wrap gap-1.5 pt-4">
|
|
72
|
-
{badges.map((badge: any) =>
|
|
72
|
+
{badges.map((badge: any) => (
|
|
73
|
+
<Badge badge={badge} />
|
|
74
|
+
))}
|
|
73
75
|
</div>
|
|
74
76
|
)
|
|
75
77
|
}
|
|
@@ -8,7 +8,7 @@ import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
|
8
8
|
import Badge from '@components/Badge.astro';
|
|
9
9
|
import { buildUrl } from '@utils/url-builder';
|
|
10
10
|
import { AlignLeftIcon, HistoryIcon } from 'lucide-react';
|
|
11
|
-
import {
|
|
11
|
+
import { isEventCatalogChatVisible, isMarkdownDownloadEnabled, isResourceDocsEnabled } from '@utils/feature';
|
|
12
12
|
import { getIcon } from '@utils/badges';
|
|
13
13
|
import { collectionToResourceMap } from '@utils/collections/util';
|
|
14
14
|
import { getResourceDocTypeLabel } from '@utils/collections/resource-docs';
|
|
@@ -38,7 +38,7 @@ const singularResourceName =
|
|
|
38
38
|
collectionToResourceMap[props.data.resourceCollection as keyof typeof collectionToResourceMap] ??
|
|
39
39
|
props.data.resourceCollection.slice(0, props.data.resourceCollection.length - 1);
|
|
40
40
|
const typeLabel = getResourceDocTypeLabel(props.data.type);
|
|
41
|
-
const chatEnabled =
|
|
41
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
42
42
|
const chatQuery = `Tell me about the ${props.data.type} doc "${title}" for ${props.data.resourceId} (version ${props.data.version})`;
|
|
43
43
|
|
|
44
44
|
const pagefindAttributes =
|
|
@@ -60,11 +60,17 @@ const pagefindAttributes =
|
|
|
60
60
|
<span class="text-xs md:text-sm font-semibold text-[rgb(var(--ec-accent))] capitalize">{typeLabel}</span>
|
|
61
61
|
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{title}</h2>
|
|
62
62
|
</div>
|
|
63
|
-
{
|
|
63
|
+
{
|
|
64
|
+
props.data.summary && (
|
|
65
|
+
<p class="text-base pt-4 text-[rgb(var(--ec-page-text-muted))] font-light">{props.data.summary}</p>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
64
68
|
{
|
|
65
69
|
badges.length > 0 && (
|
|
66
70
|
<div class="flex flex-wrap gap-1.5 pt-4">
|
|
67
|
-
{badges.map((badge: any) =>
|
|
71
|
+
{badges.map((badge: any) => (
|
|
72
|
+
<Badge badge={badge} />
|
|
73
|
+
))}
|
|
68
74
|
</div>
|
|
69
75
|
)
|
|
70
76
|
}
|
|
@@ -12,7 +12,7 @@ import js from '@asyncapi/react-component/browser/standalone/without-parser.js?u
|
|
|
12
12
|
import { AsyncApiComponentWP, type ConfigInterface } from '@asyncapi/react-component';
|
|
13
13
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
14
14
|
import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
15
|
-
import {
|
|
15
|
+
import { isEventCatalogChatVisible } from '@utils/feature';
|
|
16
16
|
import Config from '@utils/eventcatalog-config/catalog';
|
|
17
17
|
import { Page } from './_[filename].data';
|
|
18
18
|
import { getAbsoluteFilePathForAstroFile } from '@utils/files';
|
|
@@ -148,7 +148,7 @@ const renderedComponent = renderToString(component);
|
|
|
148
148
|
const pageTitle = `${collection} | ${data.name} | AsyncApi Spec`.replace(/^\w/, (c) => c.toUpperCase());
|
|
149
149
|
|
|
150
150
|
// Chat configuration
|
|
151
|
-
const chatEnabled =
|
|
151
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
152
152
|
const chatQuery = `Tell me about the AsyncAPI specification for "${data.name}" (version ${data.version})`;
|
|
153
153
|
|
|
154
154
|
// Index only the latest version
|
|
@@ -61,7 +61,7 @@ import { getIcon } from '@utils/badges';
|
|
|
61
61
|
import { buildUrl, buildEditUrlForResource } from '@utils/url-builder';
|
|
62
62
|
import { isIconPath, resolveIconUrl } from '@utils/icon';
|
|
63
63
|
import {
|
|
64
|
-
|
|
64
|
+
isEventCatalogChatVisible,
|
|
65
65
|
isMarkdownDownloadEnabled,
|
|
66
66
|
isVisualiserEnabled,
|
|
67
67
|
isRSSEnabled,
|
|
@@ -479,11 +479,11 @@ if (!isAdrPage && !hasCurrentFlowEmbed && !hasCurrentPageNodeGraph) {
|
|
|
479
479
|
variant="toolbar"
|
|
480
480
|
schemas={schemasForResource}
|
|
481
481
|
chatQuery={generatePromptForResource(props)}
|
|
482
|
-
chatEnabled={
|
|
482
|
+
chatEnabled={isEventCatalogChatVisible()}
|
|
483
483
|
markdownDownloadEnabled={isMarkdownDownloadEnabled()}
|
|
484
484
|
rssFeedEnabled={isRSSEnabled()}
|
|
485
485
|
editUrl={editUrl}
|
|
486
|
-
preferChatAsDefault={
|
|
486
|
+
preferChatAsDefault={isEventCatalogChatVisible()}
|
|
487
487
|
mcpServerUrl={mcpServerUrl}
|
|
488
488
|
resourceName={props.data.name}
|
|
489
489
|
mcpResourceType={mcpResourceType}
|
|
@@ -5,7 +5,7 @@ import OpenAPISpec from './_OpenAPI.tsx';
|
|
|
5
5
|
import { DocumentMinusIcon } from '@heroicons/react/24/outline';
|
|
6
6
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
7
7
|
import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
8
|
-
import {
|
|
8
|
+
import { isEventCatalogChatVisible } from '@utils/feature';
|
|
9
9
|
import './_styles.css';
|
|
10
10
|
import { Page } from './_[filename].data.ts';
|
|
11
11
|
import { getAbsoluteFilePathForAstroFile } from '@utils/files';
|
|
@@ -31,7 +31,7 @@ let content = '';
|
|
|
31
31
|
const pageTitle = `${collection} | ${data.name} | OpenAPI Spec`.replace(/^\w/, (c) => c.toUpperCase());
|
|
32
32
|
|
|
33
33
|
// Chat configuration
|
|
34
|
-
const chatEnabled =
|
|
34
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
35
35
|
const chatQuery = `Tell me about the OpenAPI specification for "${data.name}" (version ${data.version})`;
|
|
36
36
|
|
|
37
37
|
// Index only the latest version
|
|
@@ -4,11 +4,11 @@ import AstroNodeGraph from '@components/MDX/NodeGraph/AstroNodeGraph';
|
|
|
4
4
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
5
5
|
import { ClientRouter } from 'astro:transitions';
|
|
6
6
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
7
|
-
import {
|
|
7
|
+
import { isEventCatalogChatVisible } from '@utils/feature';
|
|
8
8
|
|
|
9
9
|
import { Page } from './_index.data';
|
|
10
10
|
|
|
11
|
-
const isChatEnabled =
|
|
11
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
12
12
|
|
|
13
13
|
export const prerender = Page.prerender;
|
|
14
14
|
export const getStaticPaths = Page.getStaticPaths;
|