@eventcatalog/core 5.0.0-beta.12 → 5.0.0-beta.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 +4 -4
- package/dist/catalog-runtime.cjs +1 -1
- package/dist/{chunk-FY6MSP6J.js → chunk-BO2HHVZ3.js} +1 -1
- package/dist/{chunk-CX2VB7AI.js → chunk-JPT3QC5V.js} +1 -1
- package/dist/{chunk-BWC4YKW3.js → chunk-PLTLW45Q.js} +5 -5
- package/dist/{chunk-TSY5CC27.js → chunk-T75DOVFP.js} +1 -1
- package/dist/{chunk-QB7X34OD.js → chunk-XA5W6DXX.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +2 -2
- package/dist/eventcatalog.js +14 -14
- package/dist/federation/federate.js +3 -3
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +3 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +11 -3
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +133 -71
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +66 -66
- package/eventcatalog/src/features/studio/agent-choreography.ts +5 -4
- package/eventcatalog/src/features/studio/agents.ts +28 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +1 -1
- package/eventcatalog/src/features/studio/canvas-actions.ts +22 -14
- package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
- package/eventcatalog/src/features/studio/catalog.ts +1 -4
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +246 -115
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +7 -3
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +1 -1
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +102 -241
- package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
- package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +1 -1
- package/eventcatalog/src/features/studio/components/Presence.tsx +6 -8
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1005 -354
- package/eventcatalog/src/features/studio/document-name.ts +7 -0
- package/eventcatalog/src/features/studio/from-visualiser.ts +1 -1
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +162 -23
- package/eventcatalog/src/features/studio/identity.ts +23 -1
- package/eventcatalog/src/features/studio/pages/[id].astro +2 -1
- package/eventcatalog/src/features/studio/pages/index.astro +1 -2
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +7 -22
- package/eventcatalog/src/features/studio/server/runtime.ts +4 -5
- package/package.json +3 -3
- package/eventcatalog/src/features/studio/canvas-doc.ts +0 -569
- package/eventcatalog/src/features/studio/clipboard.ts +0 -97
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -119
- package/eventcatalog/src/features/studio/components/Comments.tsx +0 -777
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
- package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -271
- package/eventcatalog/src/features/studio/components/icons.ts +0 -53
- package/eventcatalog/src/features/studio/components/status.ts +0 -53
- package/eventcatalog/src/features/studio/edges.ts +0 -56
- package/eventcatalog/src/features/studio/flow-state.ts +0 -121
- package/eventcatalog/src/features/studio/grouping.ts +0 -230
- package/eventcatalog/src/features/studio/hooks/use-counter-scale.ts +0 -20
- package/eventcatalog/src/features/studio/layout.ts +0 -56
- package/eventcatalog/src/features/studio/level-layout.ts +0 -145
- package/eventcatalog/src/features/studio/levels.ts +0 -337
- package/eventcatalog/src/features/studio/node-types.ts +0 -245
- package/eventcatalog/src/features/studio/placement.ts +0 -197
- package/eventcatalog/src/features/studio/studio.css +0 -273
- package/dist/{chunk-KHACCTW2.js → chunk-ZEY2XUJN.js} +4 -4
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { memo, type RefObject } from 'react';
|
|
2
|
+
import type { Node } from '@xyflow/react';
|
|
3
|
+
import { Box, ExternalLink, Library } from 'lucide-react';
|
|
4
|
+
import { getCatalogLink } from '../catalog';
|
|
5
|
+
import {
|
|
6
|
+
EditableText,
|
|
7
|
+
EditStatus,
|
|
8
|
+
Field,
|
|
9
|
+
NodeCard,
|
|
10
|
+
getNodeLabel,
|
|
11
|
+
getResource,
|
|
12
|
+
isVersioned,
|
|
13
|
+
updateResource,
|
|
14
|
+
useSavedFlash,
|
|
15
|
+
type UpdateNodeData,
|
|
16
|
+
NODE_ICONS,
|
|
17
|
+
} from '@eventcatalog/visualiser/studio';
|
|
18
|
+
|
|
19
|
+
/** Something it's connected to: the node at the other end, and the connection's label */
|
|
20
|
+
export type NodeConnection = { id: string; name: string; type?: string; label?: string; outgoing: boolean };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A node's details, in a card next to it (as Studio on the web's): its type and where it is, and its name, version
|
|
24
|
+
* and summary, saved as they're typed, and what it's connected to (click one to go to it). Catalog resources are read only (they're changed in the catalog), as is
|
|
25
|
+
* everything on a locked canvas. Notes and text are edited on the canvas.
|
|
26
|
+
*/
|
|
27
|
+
export default memo(function NodeDetails({
|
|
28
|
+
node,
|
|
29
|
+
parentName,
|
|
30
|
+
connections,
|
|
31
|
+
onOpenNode,
|
|
32
|
+
containerRef,
|
|
33
|
+
locked,
|
|
34
|
+
onChange,
|
|
35
|
+
onClose,
|
|
36
|
+
}: {
|
|
37
|
+
/** What's shown of the node (not its position: the card follows the node on screen by itself) */
|
|
38
|
+
node: Pick<Node, 'id' | 'type' | 'data'>;
|
|
39
|
+
/** The domain or system it's in, if it's in one */
|
|
40
|
+
parentName?: string;
|
|
41
|
+
connections: NodeConnection[];
|
|
42
|
+
/** Goes to a node it's connected to (and shows its card) */
|
|
43
|
+
onOpenNode: (id: string) => void;
|
|
44
|
+
/** The canvas, to put the card next to the node */
|
|
45
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
46
|
+
locked: boolean;
|
|
47
|
+
onChange: UpdateNodeData;
|
|
48
|
+
onClose: () => void;
|
|
49
|
+
}) {
|
|
50
|
+
const { saved, showSaved } = useSavedFlash();
|
|
51
|
+
const resource = getResource(node.type, node.data);
|
|
52
|
+
const link = getCatalogLink(node);
|
|
53
|
+
const label = getNodeLabel(node.type);
|
|
54
|
+
const { icon: Icon, className: iconClassName } = NODE_ICONS[node.type ?? ''] ?? { icon: Box, className: '' };
|
|
55
|
+
const versioned = isVersioned(node.type);
|
|
56
|
+
const name = String(resource.name ?? '');
|
|
57
|
+
const version = String(link?.version ?? resource.version ?? '');
|
|
58
|
+
const summary = String(resource.summary ?? '');
|
|
59
|
+
const save = (fields: Record<string, string>) => onChange(node.id, (data) => updateResource(node.type, data, fields));
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<NodeCard
|
|
63
|
+
nodeId={node.id}
|
|
64
|
+
containerRef={containerRef}
|
|
65
|
+
label={name || label}
|
|
66
|
+
onClose={onClose}
|
|
67
|
+
kicker={
|
|
68
|
+
<>
|
|
69
|
+
{/* Its type, in its colour (as the web's type pill) */}
|
|
70
|
+
<span className={`flex-none ${iconClassName}`}>
|
|
71
|
+
<span className="inline-flex items-center gap-1 rounded bg-current px-1.5 text-[9px] font-bold uppercase leading-4 tracking-wider">
|
|
72
|
+
<Icon aria-hidden size={10} className="text-white" />
|
|
73
|
+
<span className="text-white">{label}</span>
|
|
74
|
+
</span>
|
|
75
|
+
</span>
|
|
76
|
+
{parentName && <span className="ec-doc-card-breadcrumb">in {parentName}</span>}
|
|
77
|
+
</>
|
|
78
|
+
}
|
|
79
|
+
header={
|
|
80
|
+
link || locked ? (
|
|
81
|
+
<>
|
|
82
|
+
<h2 className="ec-doc-card-title">
|
|
83
|
+
{name}
|
|
84
|
+
{version && <span className="ec-doc-card-version">v{version}</span>}
|
|
85
|
+
</h2>
|
|
86
|
+
{summary && <p className="ec-doc-card-summary">{summary}</p>}
|
|
87
|
+
{link && (
|
|
88
|
+
<div className="mt-3 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[rgb(var(--ec-page-text-muted))]">
|
|
89
|
+
<span className="inline-flex items-center gap-1.5">
|
|
90
|
+
<Library aria-hidden size={13} className="text-[rgb(var(--ec-accent))]" />
|
|
91
|
+
From your catalog: change it there
|
|
92
|
+
</span>
|
|
93
|
+
<a
|
|
94
|
+
href={link.url}
|
|
95
|
+
target="_blank"
|
|
96
|
+
rel="noreferrer"
|
|
97
|
+
className="inline-flex items-center gap-1 font-medium text-[rgb(var(--ec-accent))] hover:underline"
|
|
98
|
+
>
|
|
99
|
+
Open in EventCatalog <ExternalLink aria-hidden size={12} />
|
|
100
|
+
</a>
|
|
101
|
+
</div>
|
|
102
|
+
)}
|
|
103
|
+
</>
|
|
104
|
+
) : (
|
|
105
|
+
// A small form: what's typed is saved as it's typed (there's nothing to press), and shown on the node
|
|
106
|
+
<div className="ec-edit-form" key={node.id}>
|
|
107
|
+
<Field label="Name">
|
|
108
|
+
<EditableText
|
|
109
|
+
label="Name"
|
|
110
|
+
value={name}
|
|
111
|
+
onSave={(next) => save({ name: next })}
|
|
112
|
+
onSaved={showSaved}
|
|
113
|
+
placeholder={`Name this ${label.toLowerCase()}`}
|
|
114
|
+
className="ec-editable-title"
|
|
115
|
+
required
|
|
116
|
+
/>
|
|
117
|
+
</Field>
|
|
118
|
+
{versioned && (
|
|
119
|
+
<Field label="Version" className="ec-field-version">
|
|
120
|
+
<EditableText
|
|
121
|
+
label="Version"
|
|
122
|
+
value={version || '0.0.1'}
|
|
123
|
+
onSave={(next) => save({ version: next })}
|
|
124
|
+
onSaved={showSaved}
|
|
125
|
+
placeholder="0.0.1"
|
|
126
|
+
required
|
|
127
|
+
/>
|
|
128
|
+
</Field>
|
|
129
|
+
)}
|
|
130
|
+
<Field label="Summary">
|
|
131
|
+
<EditableText
|
|
132
|
+
label="Summary"
|
|
133
|
+
value={summary}
|
|
134
|
+
onSave={(next) => save({ summary: next })}
|
|
135
|
+
onSaved={showSaved}
|
|
136
|
+
placeholder="What it does, in a sentence or two"
|
|
137
|
+
className="ec-editable-summary"
|
|
138
|
+
multiline
|
|
139
|
+
/>
|
|
140
|
+
</Field>
|
|
141
|
+
<EditStatus saved={saved} />
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
>
|
|
146
|
+
<div className="ec-doc-card-body px-4 pb-3.5 pt-1 empty:hidden">
|
|
147
|
+
{(['Connects to', 'Connected from'] as const).map((heading) => {
|
|
148
|
+
const items = connections.filter((connection) => connection.outgoing === (heading === 'Connects to'));
|
|
149
|
+
if (!items.length) return null;
|
|
150
|
+
return (
|
|
151
|
+
<section key={heading} className="mt-3">
|
|
152
|
+
<h3 className="mb-1.5 text-xs font-semibold text-[rgb(var(--ec-page-text-muted))]">{heading}</h3>
|
|
153
|
+
<ul className="space-y-0.5">
|
|
154
|
+
{items.map((item) => {
|
|
155
|
+
const { icon: ItemIcon, className: itemIconClassName } = NODE_ICONS[item.type ?? ''] ?? {
|
|
156
|
+
icon: Box,
|
|
157
|
+
className: '',
|
|
158
|
+
};
|
|
159
|
+
return (
|
|
160
|
+
<li key={`${item.id}-${item.label}`}>
|
|
161
|
+
<button
|
|
162
|
+
type="button"
|
|
163
|
+
title={`Go to ${item.name}`}
|
|
164
|
+
onClick={() => onOpenNode(item.id)}
|
|
165
|
+
className="flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-left text-sm hover:bg-[rgb(var(--ec-content-hover))]"
|
|
166
|
+
>
|
|
167
|
+
<ItemIcon aria-hidden size={15} className={`flex-none ${itemIconClassName}`} />
|
|
168
|
+
<span className="min-w-0 flex-1 truncate">{item.name}</span>
|
|
169
|
+
{item.label && (
|
|
170
|
+
<span className="flex-none text-[11px] text-[rgb(var(--ec-page-text-muted))]">{item.label}</span>
|
|
171
|
+
)}
|
|
172
|
+
</button>
|
|
173
|
+
</li>
|
|
174
|
+
);
|
|
175
|
+
})}
|
|
176
|
+
</ul>
|
|
177
|
+
</section>
|
|
178
|
+
);
|
|
179
|
+
})}
|
|
180
|
+
</div>
|
|
181
|
+
</NodeCard>
|
|
182
|
+
);
|
|
183
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useState, type FormEvent } from 'react';
|
|
2
2
|
import { MAX_TITLE_LENGTH } from '../limits';
|
|
3
3
|
import Dialog, { PRIMARY_BUTTON, SECONDARY_BUTTON } from './Dialog';
|
|
4
|
-
import { STATUS } from '
|
|
4
|
+
import { STATUS } from '@eventcatalog/visualiser/studio';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Naming the canvas a diagram is opened in (the visualiser's "Open in Studio"), named after the diagram to start
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Fragment, memo, useEffect, useLayoutEffect, useRef, useSyncExternalStore, type MutableRefObject } from 'react';
|
|
2
|
-
import { useInternalNode, useStore, useStoreApi,
|
|
3
|
-
import {
|
|
4
|
-
import { sizeOf } from '
|
|
2
|
+
import { useInternalNode, useStore, useStoreApi, type XYPosition } from '@xyflow/react';
|
|
3
|
+
import { Eye, EyeOff } from 'lucide-react';
|
|
4
|
+
import { CanvasPortal, sizeOf, COUNTER_SCALE, useCounterScale, Picture, AgentMark } from '@eventcatalog/visualiser/studio';
|
|
5
5
|
import { usePeople, type Peer, type PresenceStore } from '../hooks/presence-store';
|
|
6
|
-
import { COUNTER_SCALE, useCounterScale } from '../hooks/use-counter-scale';
|
|
7
6
|
import { useFollowCamera } from '../hooks/use-follow-camera';
|
|
8
|
-
import Picture from './Picture';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Other people on the canvas: their pointers, selections and the connections they're dragging. Drawn in the
|
|
@@ -26,7 +24,7 @@ export const RemotePresence = memo(function RemotePresence({
|
|
|
26
24
|
const others = store ? people.filter((peer) => peer.clientId !== clientId) : [];
|
|
27
25
|
|
|
28
26
|
return (
|
|
29
|
-
<
|
|
27
|
+
<CanvasPortal>
|
|
30
28
|
{/* Above nodes (selected ones are raised to 1000) */}
|
|
31
29
|
<div ref={layer} className="pointer-events-none absolute left-0 top-0" style={{ zIndex: 2000 }}>
|
|
32
30
|
{others.map((peer) => (
|
|
@@ -36,7 +34,7 @@ export const RemotePresence = memo(function RemotePresence({
|
|
|
36
34
|
</Fragment>
|
|
37
35
|
))}
|
|
38
36
|
</div>
|
|
39
|
-
</
|
|
37
|
+
</CanvasPortal>
|
|
40
38
|
);
|
|
41
39
|
});
|
|
42
40
|
|
|
@@ -151,7 +149,7 @@ const PeerPointer = memo(function PeerPointer({ store, peer }: { store: Presence
|
|
|
151
149
|
className="absolute left-4 top-4 flex items-center gap-1 whitespace-nowrap rounded px-1.5 py-0.5 text-[11px] font-medium text-white"
|
|
152
150
|
style={{ backgroundColor: peer.color }}
|
|
153
151
|
>
|
|
154
|
-
{peer.agent && <
|
|
152
|
+
{peer.agent && <AgentMark name={peer.name} size={12} />}
|
|
155
153
|
<Picture src={peer.picture} className="-ml-0.5 h-4 w-4 shrink-0" />
|
|
156
154
|
{peer.name}
|
|
157
155
|
{peer.activity && <span className="font-normal opacity-90">· {peer.activity}</span>}
|