@eventcatalog/core 3.8.2 → 3.9.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/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-OCD75GFW.js → chunk-CZG5RQXY.js} +1 -1
- package/dist/{chunk-I7HRERRK.js → chunk-FM44RPBS.js} +1 -1
- package/dist/{chunk-MOBOWLEW.js → chunk-HJOMVPCL.js} +1 -1
- package/dist/{chunk-275AT7XV.js → chunk-OQYLI4YJ.js} +1 -1
- package/dist/{chunk-KBMXUUXX.js → chunk-UYBPI4UO.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 +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/src/components/ChatPanel/ChatPanel.tsx +50 -0
- package/eventcatalog/src/components/MDX/Design/Design.astro +4 -1
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +4 -0
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -1
- package/eventcatalog/src/components/MDX/NodeGraph/MermaidView.tsx +240 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +4 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +333 -189
- package/eventcatalog/src/components/MDX/NodeGraph/VisualizerDropdownContent.tsx +224 -0
- package/eventcatalog/src/content.config.ts +1 -1
- package/eventcatalog/src/enterprise/ai/chat-api.ts +23 -0
- package/eventcatalog/src/enterprise/tools/catalog-tools.ts +96 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +128 -0
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +4 -0
- package/eventcatalog/src/utils/clipboard.ts +22 -0
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +299 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-FM44RPBS.js";
|
|
4
|
+
import "../chunk-HJOMVPCL.js";
|
|
5
|
+
import "../chunk-UYBPI4UO.js";
|
|
6
6
|
import "../chunk-UPONRQSN.js";
|
|
7
7
|
export {
|
|
8
8
|
log_build_default as default
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
|
@@ -109,7 +109,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
109
109
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
110
110
|
|
|
111
111
|
// package.json
|
|
112
|
-
var version = "3.
|
|
112
|
+
var version = "3.9.0";
|
|
113
113
|
|
|
114
114
|
// src/constants.ts
|
|
115
115
|
var VERSION = version;
|
package/dist/eventcatalog.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
} from "./chunk-PLNJC7NZ.js";
|
|
7
7
|
import {
|
|
8
8
|
log_build_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-FM44RPBS.js";
|
|
10
|
+
import "./chunk-HJOMVPCL.js";
|
|
11
11
|
import {
|
|
12
12
|
runMigrations
|
|
13
13
|
} from "./chunk-BH3JMNAV.js";
|
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
} from "./chunk-5VBIXL6C.js";
|
|
22
22
|
import {
|
|
23
23
|
generate
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-CZG5RQXY.js";
|
|
25
25
|
import {
|
|
26
26
|
logger
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-OQYLI4YJ.js";
|
|
28
28
|
import {
|
|
29
29
|
VERSION
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-UYBPI4UO.js";
|
|
31
31
|
import "./chunk-UPONRQSN.js";
|
|
32
32
|
|
|
33
33
|
// src/eventcatalog.ts
|
package/dist/generate.cjs
CHANGED
package/dist/generate.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generate
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-CZG5RQXY.js";
|
|
4
|
+
import "./chunk-OQYLI4YJ.js";
|
|
5
|
+
import "./chunk-UYBPI4UO.js";
|
|
6
6
|
import "./chunk-UPONRQSN.js";
|
|
7
7
|
export {
|
|
8
8
|
generate
|
package/dist/utils/cli-logger.js
CHANGED
|
@@ -171,6 +171,55 @@ const suggestedQuestionsConfig: QuestionConfig[] = [
|
|
|
171
171
|
{ label: 'Who owns this domain?', prompt: 'Who owns this domain and how do I contact them?' },
|
|
172
172
|
],
|
|
173
173
|
},
|
|
174
|
+
// Business Flows / Workflows (must be before general visualiser pattern)
|
|
175
|
+
{
|
|
176
|
+
pattern: /^\/(docs|visualiser)\/flows\/.+/,
|
|
177
|
+
questions: [
|
|
178
|
+
{
|
|
179
|
+
label: 'Walk me through this workflow',
|
|
180
|
+
prompt:
|
|
181
|
+
'Get the architecture diagram for this flow and walk me through each step of this business workflow. Explain what happens at each stage.',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
label: 'What services are involved?',
|
|
185
|
+
prompt:
|
|
186
|
+
'Using the architecture diagram, list all the services involved in this workflow and explain their role in the process.',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
label: 'What events does this trigger?',
|
|
190
|
+
prompt: 'What events are produced during this workflow? When are they triggered and who consumes them?',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
label: 'What can go wrong?',
|
|
194
|
+
prompt:
|
|
195
|
+
'Analyze this workflow and identify potential failure points. What happens if a step fails? Are there retry mechanisms or compensating actions?',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
// Visualizer page (/visualiser/*) - general fallback for other visualiser pages
|
|
200
|
+
{
|
|
201
|
+
pattern: /^\/visualiser\/.+/,
|
|
202
|
+
questions: [
|
|
203
|
+
{
|
|
204
|
+
label: 'Explain this architecture',
|
|
205
|
+
prompt:
|
|
206
|
+
'Get the architecture diagram for this resource and explain what I am looking at. Describe the key components and how they connect.',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
label: 'What are the dependencies?',
|
|
210
|
+
prompt: 'Using the architecture diagram, show me what this resource depends on and what depends on it.',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
label: 'How does data flow here?',
|
|
214
|
+
prompt: 'Get the architecture diagram and explain how data flows through this part of the system.',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
label: 'What would break if this changes?',
|
|
218
|
+
prompt:
|
|
219
|
+
'Analyze the architecture diagram to identify what services or components would be affected if this resource changes.',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
174
223
|
// Data Products page
|
|
175
224
|
{
|
|
176
225
|
pattern: /^\/(docs|visualiser)\/data-products\/.+/,
|
|
@@ -182,6 +231,7 @@ const suggestedQuestionsConfig: QuestionConfig[] = [
|
|
|
182
231
|
{ label: 'Who owns this data product?', prompt: 'Who owns this data product and how do I contact them?' },
|
|
183
232
|
],
|
|
184
233
|
},
|
|
234
|
+
|
|
185
235
|
// Designs page
|
|
186
236
|
{
|
|
187
237
|
pattern: /^\/diagrams\/.+/,
|
|
@@ -5,7 +5,9 @@ import { getAbsoluteFilePathForAstroFile } from '@utils/files';
|
|
|
5
5
|
import Admonition from '@components/MDX/Admonition';
|
|
6
6
|
import NodeGraph from '../NodeGraph/NodeGraph';
|
|
7
7
|
|
|
8
|
-
import { isVisualiserEnabled } from '@utils/feature';
|
|
8
|
+
import { isVisualiserEnabled, isEventCatalogChatEnabled } from '@utils/feature';
|
|
9
|
+
|
|
10
|
+
const isChatEnabled = isEventCatalogChatEnabled();
|
|
9
11
|
|
|
10
12
|
let design: any;
|
|
11
13
|
let id = 'design';
|
|
@@ -57,6 +59,7 @@ try {
|
|
|
57
59
|
designId={design.id || id}
|
|
58
60
|
client:only="react"
|
|
59
61
|
showSearch={search}
|
|
62
|
+
isChatEnabled={isChatEnabled}
|
|
60
63
|
/>
|
|
61
64
|
</div>
|
|
62
65
|
</div>
|
|
@@ -5,6 +5,9 @@ import Admonition from '@components/MDX/Admonition';
|
|
|
5
5
|
import NodeGraph from '../NodeGraph/NodeGraph';
|
|
6
6
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
7
7
|
import { getServices } from '@utils/collections/services';
|
|
8
|
+
import { isEventCatalogChatEnabled } from '@utils/feature';
|
|
9
|
+
|
|
10
|
+
const isChatEnabled = isEventCatalogChatEnabled();
|
|
8
11
|
|
|
9
12
|
const { id, version = 'latest', maxHeight, includeKey = true, entities, collection = 'domains', ...rest } = Astro.props;
|
|
10
13
|
let resource = null;
|
|
@@ -71,6 +74,7 @@ const { nodes, edges } = await getNodesAndEdges({
|
|
|
71
74
|
footerLabel={`Entity Map - ${resource?.data?.name} - v(${resource?.data?.version})`}
|
|
72
75
|
client:only="react"
|
|
73
76
|
portalId={`${id}-entity-map-portal`}
|
|
77
|
+
isChatEnabled={isChatEnabled}
|
|
74
78
|
/>
|
|
75
79
|
</div>
|
|
76
80
|
|
|
@@ -4,7 +4,9 @@ import { getNodesAndEdges } from '@utils/node-graphs/flows-node-graph';
|
|
|
4
4
|
import Admonition from '@components/MDX/Admonition';
|
|
5
5
|
import NodeGraph from '../NodeGraph/NodeGraph';
|
|
6
6
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
7
|
-
import { isVisualiserEnabled } from '@utils/feature';
|
|
7
|
+
import { isVisualiserEnabled, isEventCatalogChatEnabled } from '@utils/feature';
|
|
8
|
+
|
|
9
|
+
const isChatEnabled = isEventCatalogChatEnabled();
|
|
8
10
|
|
|
9
11
|
const { id, version = 'latest', maxHeight, includeKey = true, mode = 'simple', walkthrough = true, search = true } = Astro.props;
|
|
10
12
|
|
|
@@ -57,6 +59,7 @@ const { nodes, edges } = await getNodesAndEdges({
|
|
|
57
59
|
client:only="react"
|
|
58
60
|
showFlowWalkthrough={walkthrough}
|
|
59
61
|
showSearch={search}
|
|
62
|
+
isChatEnabled={isChatEnabled}
|
|
60
63
|
/>
|
|
61
64
|
</div>
|
|
62
65
|
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { CheckIcon, ClipboardIcon } from 'lucide-react';
|
|
3
|
+
import type { Node, Edge } from '@xyflow/react';
|
|
4
|
+
import { convertToMermaid } from '@utils/node-graphs/export-mermaid';
|
|
5
|
+
import { copyToClipboard } from '@utils/clipboard';
|
|
6
|
+
|
|
7
|
+
interface MermaidViewProps {
|
|
8
|
+
nodes: Node[];
|
|
9
|
+
edges: Edge[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const MermaidView = ({ nodes, edges }: MermaidViewProps) => {
|
|
13
|
+
const [copySuccess, setCopySuccess] = useState(false);
|
|
14
|
+
const [mermaidCode, setMermaidCode] = useState('');
|
|
15
|
+
const [previewSvg, setPreviewSvg] = useState<string | null>(null);
|
|
16
|
+
const [previewError, setPreviewError] = useState<string | null>(null);
|
|
17
|
+
const [isRendering, setIsRendering] = useState(true);
|
|
18
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
19
|
+
const svgContainerRef = useRef<HTMLDivElement>(null);
|
|
20
|
+
const panZoomInstanceRef = useRef<any>(null);
|
|
21
|
+
|
|
22
|
+
// Generate mermaid code
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const code = convertToMermaid(nodes, edges, { includeStyles: true, direction: 'LR' });
|
|
25
|
+
setMermaidCode(code);
|
|
26
|
+
}, [nodes, edges]);
|
|
27
|
+
|
|
28
|
+
// Render mermaid preview
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!mermaidCode) return;
|
|
31
|
+
|
|
32
|
+
let cancelled = false;
|
|
33
|
+
setIsRendering(true);
|
|
34
|
+
setPreviewError(null);
|
|
35
|
+
|
|
36
|
+
const renderMermaid = async () => {
|
|
37
|
+
try {
|
|
38
|
+
const { default: mermaid } = await import('mermaid');
|
|
39
|
+
|
|
40
|
+
// Detect current theme
|
|
41
|
+
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark';
|
|
42
|
+
const currentTheme = isDarkMode ? 'dark' : 'default';
|
|
43
|
+
|
|
44
|
+
mermaid.initialize({
|
|
45
|
+
startOnLoad: false,
|
|
46
|
+
theme: currentTheme,
|
|
47
|
+
flowchart: {
|
|
48
|
+
curve: 'basis',
|
|
49
|
+
padding: 20,
|
|
50
|
+
},
|
|
51
|
+
securityLevel: 'loose',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const id = 'mermaid-view-' + Math.random().toString(36).substring(2, 9);
|
|
55
|
+
const { svg } = await mermaid.render(id, mermaidCode);
|
|
56
|
+
|
|
57
|
+
if (!cancelled) {
|
|
58
|
+
setPreviewSvg(svg);
|
|
59
|
+
setPreviewError(null);
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (!cancelled) {
|
|
63
|
+
console.error('Mermaid render error:', error);
|
|
64
|
+
setPreviewError(error instanceof Error ? error.message : 'Failed to render diagram');
|
|
65
|
+
setPreviewSvg(null);
|
|
66
|
+
}
|
|
67
|
+
} finally {
|
|
68
|
+
if (!cancelled) {
|
|
69
|
+
setIsRendering(false);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
renderMermaid();
|
|
75
|
+
|
|
76
|
+
return () => {
|
|
77
|
+
cancelled = true;
|
|
78
|
+
};
|
|
79
|
+
}, [mermaidCode]);
|
|
80
|
+
|
|
81
|
+
// Initialize pan/zoom after SVG is rendered
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!previewSvg || !svgContainerRef.current) return;
|
|
84
|
+
|
|
85
|
+
const initZoom = async () => {
|
|
86
|
+
const svgElement = svgContainerRef.current?.querySelector('svg');
|
|
87
|
+
if (!svgElement) return;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const { default: svgPanZoom } = await import('svg-pan-zoom');
|
|
91
|
+
|
|
92
|
+
// Set SVG to fill container
|
|
93
|
+
svgElement.style.width = '100%';
|
|
94
|
+
svgElement.style.height = '100%';
|
|
95
|
+
svgElement.removeAttribute('height');
|
|
96
|
+
svgElement.removeAttribute('width');
|
|
97
|
+
|
|
98
|
+
const instance = svgPanZoom(svgElement, {
|
|
99
|
+
zoomEnabled: true,
|
|
100
|
+
controlIconsEnabled: false,
|
|
101
|
+
fit: true,
|
|
102
|
+
center: true,
|
|
103
|
+
minZoom: 0.1,
|
|
104
|
+
maxZoom: 10,
|
|
105
|
+
zoomScaleSensitivity: 0.15,
|
|
106
|
+
dblClickZoomEnabled: true,
|
|
107
|
+
mouseWheelZoomEnabled: true,
|
|
108
|
+
panEnabled: true,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
panZoomInstanceRef.current = instance;
|
|
112
|
+
} catch (e) {
|
|
113
|
+
console.warn('Failed to initialize zoom:', e);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
initZoom();
|
|
118
|
+
|
|
119
|
+
return () => {
|
|
120
|
+
if (panZoomInstanceRef.current) {
|
|
121
|
+
try {
|
|
122
|
+
panZoomInstanceRef.current.destroy();
|
|
123
|
+
} catch (e) {
|
|
124
|
+
// Ignore
|
|
125
|
+
}
|
|
126
|
+
panZoomInstanceRef.current = null;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}, [previewSvg]);
|
|
130
|
+
|
|
131
|
+
const handleCopyToClipboard = useCallback(async () => {
|
|
132
|
+
await copyToClipboard(mermaidCode);
|
|
133
|
+
setCopySuccess(true);
|
|
134
|
+
setTimeout(() => setCopySuccess(false), 2000);
|
|
135
|
+
}, [mermaidCode]);
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
ref={containerRef}
|
|
140
|
+
className="w-full h-full bg-[rgb(var(--ec-page-bg))] relative flex flex-col"
|
|
141
|
+
style={{ animation: 'fadeIn 200ms ease-out' }}
|
|
142
|
+
>
|
|
143
|
+
<style>{`
|
|
144
|
+
@keyframes fadeIn {
|
|
145
|
+
from { opacity: 0; }
|
|
146
|
+
to { opacity: 1; }
|
|
147
|
+
}
|
|
148
|
+
`}</style>
|
|
149
|
+
|
|
150
|
+
{/* Copy button - top right */}
|
|
151
|
+
<div className="absolute top-[10px] right-4 z-20">
|
|
152
|
+
<div className="relative group">
|
|
153
|
+
<button
|
|
154
|
+
onClick={handleCopyToClipboard}
|
|
155
|
+
className={`p-2.5 rounded-md shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[rgb(var(--ec-accent))] transition-all duration-150 ${
|
|
156
|
+
copySuccess
|
|
157
|
+
? 'bg-green-500 text-white scale-110'
|
|
158
|
+
: 'bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-page-border))/0.5] text-[rgb(var(--ec-icon-color))] hover:scale-105'
|
|
159
|
+
}`}
|
|
160
|
+
aria-label={copySuccess ? 'Copied!' : 'Copy Mermaid code'}
|
|
161
|
+
>
|
|
162
|
+
{copySuccess ? <CheckIcon className="h-5 w-5" /> : <ClipboardIcon className="h-5 w-5" />}
|
|
163
|
+
</button>
|
|
164
|
+
<div className="absolute top-full right-0 mt-2 px-2 py-1 bg-[rgb(var(--ec-page-text))] text-[rgb(var(--ec-page-bg))] text-xs rounded shadow-lg opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50">
|
|
165
|
+
{copySuccess ? 'Copied!' : 'Copy Mermaid code'}
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
{/* Mermaid diagram container */}
|
|
171
|
+
<div className="flex-1 overflow-hidden">
|
|
172
|
+
{isRendering && (
|
|
173
|
+
<div className="w-full h-full flex items-center justify-center">
|
|
174
|
+
<div className="relative">
|
|
175
|
+
<div className="flex items-center gap-4 opacity-40">
|
|
176
|
+
<div className="w-24 h-10 bg-[rgb(var(--ec-page-border))] rounded animate-pulse" />
|
|
177
|
+
<div className="w-12 h-0.5 bg-[rgb(var(--ec-page-border))] animate-pulse" />
|
|
178
|
+
<div
|
|
179
|
+
className="w-20 h-10 bg-[rgb(var(--ec-page-border))] rounded-full animate-pulse"
|
|
180
|
+
style={{ animationDelay: '75ms' }}
|
|
181
|
+
/>
|
|
182
|
+
<div className="w-12 h-0.5 bg-[rgb(var(--ec-page-border))] animate-pulse" style={{ animationDelay: '150ms' }} />
|
|
183
|
+
<div
|
|
184
|
+
className="w-24 h-10 bg-[rgb(var(--ec-page-border))] rounded animate-pulse"
|
|
185
|
+
style={{ animationDelay: '225ms' }}
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
<p className="text-center text-sm text-[rgb(var(--ec-page-text-muted))] mt-4">Rendering diagram...</p>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
192
|
+
|
|
193
|
+
{previewError && !isRendering && (
|
|
194
|
+
<div className="w-full h-full flex flex-col items-center justify-center p-4">
|
|
195
|
+
<div className="text-red-500 text-sm mb-2">Failed to render diagram</div>
|
|
196
|
+
<div className="text-[rgb(var(--ec-page-text-muted))] text-xs font-mono bg-[rgb(var(--ec-code-bg))] p-2 rounded max-w-lg overflow-auto">
|
|
197
|
+
{previewError}
|
|
198
|
+
</div>
|
|
199
|
+
<div className="mt-4 text-sm text-[rgb(var(--ec-page-text-muted))]">
|
|
200
|
+
<p>You can still copy the Mermaid code and paste it into</p>
|
|
201
|
+
<a
|
|
202
|
+
href="https://mermaid.live"
|
|
203
|
+
target="_blank"
|
|
204
|
+
rel="noopener noreferrer"
|
|
205
|
+
className="text-[rgb(var(--ec-accent))] hover:underline"
|
|
206
|
+
>
|
|
207
|
+
mermaid.live
|
|
208
|
+
</a>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
)}
|
|
212
|
+
|
|
213
|
+
{previewSvg && !isRendering && !previewError && (
|
|
214
|
+
<div
|
|
215
|
+
ref={svgContainerRef}
|
|
216
|
+
className="w-full h-full cursor-grab active:cursor-grabbing [&_svg]:w-full [&_svg]:h-full"
|
|
217
|
+
dangerouslySetInnerHTML={{ __html: previewSvg }}
|
|
218
|
+
/>
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
{/* Footer hint */}
|
|
223
|
+
<div className="absolute bottom-4 left-4 z-20">
|
|
224
|
+
<div className="flex items-center gap-2 bg-[rgb(var(--ec-card-bg))]/90 backdrop-blur-sm px-3 py-1.5 rounded-md shadow-sm border border-[rgb(var(--ec-page-border))]">
|
|
225
|
+
<svg className="w-3.5 h-3.5 text-[rgb(var(--ec-icon-color))]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
226
|
+
<path
|
|
227
|
+
strokeLinecap="round"
|
|
228
|
+
strokeLinejoin="round"
|
|
229
|
+
strokeWidth={2}
|
|
230
|
+
d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122"
|
|
231
|
+
/>
|
|
232
|
+
</svg>
|
|
233
|
+
<span className="text-xs text-[rgb(var(--ec-page-text-muted))]">Scroll to zoom · Drag to pan</span>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export default MermaidView;
|
|
@@ -19,6 +19,9 @@ import { getVersionFromCollection } from '@utils/collections/versions';
|
|
|
19
19
|
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
20
20
|
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
|
|
21
21
|
import config from '@config';
|
|
22
|
+
import { isEventCatalogChatEnabled } from '@utils/feature';
|
|
23
|
+
|
|
24
|
+
const isChatEnabled = isEventCatalogChatEnabled();
|
|
22
25
|
|
|
23
26
|
interface Props {
|
|
24
27
|
id: string;
|
|
@@ -154,6 +157,7 @@ if (collection === 'services-containers') {
|
|
|
154
157
|
showSearch={showSearch}
|
|
155
158
|
includeKey={showLegend}
|
|
156
159
|
zoomOnScroll={zoomOnScroll}
|
|
160
|
+
isChatEnabled={isChatEnabled}
|
|
157
161
|
/>
|
|
158
162
|
</div>
|
|
159
163
|
|