@likec4/diagram 1.27.1 → 1.27.3
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/bundle/index.js +2152 -6757
- package/dist/LikeC4Diagram.js +1 -1
- package/dist/LikeC4Diagram.props.d.ts +5 -3
- package/dist/StaticLikeC4Diagram.js +1 -1
- package/dist/_virtual/set.js +5 -0
- package/dist/_virtual/set2.js +3 -0
- package/dist/base/BaseXYFlow.d.ts +2 -1
- package/dist/base/primitives/compound/CompoundNodeContainer.d.ts +1 -1
- package/dist/base/primitives/compound/CompoundNodeContainer.js +0 -1
- package/dist/base/primitives/edge/EdgeLabelContainer.js +3 -2
- package/dist/base/primitives/element/ElementActionButtons.js +8 -11
- package/dist/base/primitives/element/ElementNodeContainer.css.js +4 -4
- package/dist/base/updateEdges.js +1 -9
- package/dist/base/updateNodes.js +1 -12
- package/dist/bundle/LikeC4View.js +2 -2
- package/dist/bundle/LikeC4View.props.d.ts +7 -7
- package/dist/hooks/useCurrentViewId.js +8 -2
- package/dist/hooks/useDiagram.d.ts +1522 -685
- package/dist/hooks/useDiagram.js +21 -24
- package/dist/likec4diagram/DiagramXYFlow.js +6 -6
- package/dist/likec4diagram/ui/notation/NotationPanel.css.js +3 -3
- package/dist/likec4diagram/ui/notation/NotationPanel.js +10 -4
- package/dist/node_modules/.pnpm/mnemonist@0.40.3_patch_hash_5c12abb43fcff6fd81e53021b89075d53249640d165a2556cc1e58d71201a13a/node_modules/mnemonist/set.js +369 -0
- package/dist/overlays/Overlays.js +3 -1
- package/dist/overlays/element-details/actor.d.ts +2769 -173
- package/dist/overlays/overlay/Overlay.css.d.ts +26 -2
- package/dist/overlays/overlay/Overlay.css.js +66 -18
- package/dist/overlays/overlay/Overlay.d.ts +7 -6
- package/dist/overlays/overlay/Overlay.js +12 -10
- package/dist/overlays/overlaysActor.js +2 -2
- package/dist/overlays/relationship-details/RelationshipDetails.js +113 -70
- package/dist/overlays/relationship-details/SelectEdge.d.ts +1 -1
- package/dist/overlays/relationship-details/SelectEdge.js +15 -9
- package/dist/overlays/relationship-details/_types.d.ts +4 -1
- package/dist/overlays/relationship-details/actor.d.ts +425 -128
- package/dist/overlays/relationship-details/actor.js +157 -53
- package/dist/overlays/relationship-details/compute.d.ts +12 -0
- package/dist/overlays/relationship-details/compute.js +139 -0
- package/dist/overlays/relationship-details/custom/ElementActions.js +27 -5
- package/dist/overlays/relationship-details/custom/edgeTypes.js +1 -1
- package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +2 -1
- package/dist/overlays/relationship-details/hooks.d.ts +336 -6
- package/dist/overlays/relationship-details/hooks.js +11 -12
- package/dist/overlays/relationship-details/layout-to-xyflow.d.ts +12 -0
- package/dist/overlays/relationship-details/layout-to-xyflow.js +145 -0
- package/dist/overlays/relationship-details/layout.d.ts +22 -0
- package/dist/overlays/relationship-details/layout.js +314 -0
- package/dist/overlays/relationships-browser/RelationshipsBrowser.d.ts +3 -1
- package/dist/overlays/relationships-browser/RelationshipsBrowser.js +2 -2
- package/dist/overlays/relationships-browser/_types.d.ts +2 -0
- package/dist/overlays/relationships-browser/actor.d.ts +130 -14
- package/dist/overlays/relationships-browser/actor.js +30 -16
- package/dist/overlays/relationships-browser/custom/ElementActions.js +5 -3
- package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +3 -1
- package/dist/overlays/relationships-browser/custom/edgeTypes.js +1 -1
- package/dist/overlays/relationships-browser/hooks.d.ts +3 -1
- package/dist/overlays/relationships-browser/hooks.js +6 -9
- package/dist/overlays/relationships-browser/{-useRelationshipsView.d.ts → layout.d.ts} +3 -1
- package/dist/overlays/relationships-browser/{-useRelationshipsView.js → layout.js} +21 -8
- package/dist/overlays/relationships-browser/useViewToNodesEdges.d.ts +1 -1
- package/dist/overlays/relationships-browser/useViewToNodesEdges.js +3 -1
- package/dist/packages/core/src/compute-view/relationships-view/compute.js +1 -1
- package/dist/packages/core/src/model/connection/model/ConnectionModel.js +121 -0
- package/dist/packages/core/src/model/connection/model/find.js +39 -0
- package/dist/packages/core/src/model/connection/ops.js +7 -0
- package/dist/packages/core/src/utils/const.js +3 -0
- package/dist/packages/core/src/utils/fqn.js +9 -1
- package/dist/packages/core/src/utils/iterable/find.js +21 -0
- package/dist/packages/core/src/utils/iterable/some.js +21 -0
- package/dist/packages/core/src/utils/set.js +48 -0
- package/dist/packages/core/src/utils/string-hash.js +13 -0
- package/dist/state/diagram-machine.d.ts +1552 -703
- package/dist/state/diagram-machine.js +39 -3
- package/dist/state/syncManualLayoutActor.d.ts +1 -1
- package/dist/styles.css.js +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/package.json +11 -11
- package/src/LikeC4Diagram.props.ts +7 -3
- package/src/LikeC4Diagram.tsx +1 -1
- package/src/StaticLikeC4Diagram.tsx +1 -1
- package/src/base/BaseXYFlow.tsx +2 -1
- package/src/base/primitives/compound/CompoundNodeContainer.tsx +0 -2
- package/src/base/primitives/edge/EdgeLabelContainer.tsx +7 -5
- package/src/base/primitives/element/ElementActionButtons.tsx +10 -11
- package/src/base/primitives/element/ElementNodeContainer.css.ts +4 -4
- package/src/base/updateEdges.ts +8 -8
- package/src/base/updateNodes.ts +11 -11
- package/src/bundle/LikeC4View.props.ts +7 -7
- package/src/bundle/LikeC4View.tsx +2 -2
- package/src/hooks/useCurrentViewId.ts +4 -2
- package/src/hooks/useDiagram.ts +22 -24
- package/src/likec4diagram/DiagramXYFlow.tsx +6 -6
- package/src/likec4diagram/ui/notation/NotationPanel.css.ts +2 -2
- package/src/likec4diagram/ui/notation/NotationPanel.tsx +8 -6
- package/src/overlays/Overlays.tsx +4 -2
- package/src/overlays/overlay/Overlay.css.ts +67 -17
- package/src/overlays/overlay/Overlay.tsx +27 -24
- package/src/overlays/overlaysActor.ts +1 -1
- package/src/overlays/relationship-details/RelationshipDetails.tsx +131 -68
- package/src/overlays/relationship-details/SelectEdge.tsx +19 -12
- package/src/overlays/relationship-details/_types.ts +3 -1
- package/src/overlays/relationship-details/actor.ts +212 -68
- package/src/overlays/relationship-details/compute.ts +186 -0
- package/src/overlays/relationship-details/custom/ElementActions.tsx +27 -18
- package/src/overlays/relationship-details/custom/edgeTypes.tsx +1 -1
- package/src/overlays/relationship-details/hooks.ts +12 -13
- package/src/overlays/relationship-details/layout-to-xyflow.ts +172 -0
- package/src/overlays/relationship-details/layout.ts +470 -0
- package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +2 -2
- package/src/overlays/relationships-browser/_types.ts +2 -0
- package/src/overlays/relationships-browser/actor.ts +39 -14
- package/src/overlays/relationships-browser/custom/ElementActions.tsx +5 -3
- package/src/overlays/relationships-browser/custom/edgeTypes.tsx +1 -1
- package/src/overlays/relationships-browser/hooks.ts +7 -10
- package/src/overlays/relationships-browser/{-useRelationshipsView.ts → layout.ts} +26 -33
- package/src/overlays/relationships-browser/useViewToNodesEdges.ts +3 -1
- package/src/state/diagram-machine.ts +51 -6
- package/src/utils/index.ts +0 -1
- package/dist/overlays/relationship-details/useLayoutedDetails.d.ts +0 -19
- package/dist/overlays/relationship-details/useLayoutedDetails.js +0 -267
- package/dist/utils/types.d.ts +0 -8
- package/src/overlays/relationship-details/useLayoutedDetails.ts +0 -376
- package/src/utils/types.ts +0 -6
|
@@ -26,10 +26,11 @@ import { Base } from '../../base'
|
|
|
26
26
|
import { MinZoom, ZIndexes } from '../../base/const'
|
|
27
27
|
import { updateEdges } from '../../base/updateEdges'
|
|
28
28
|
import { updateNodes } from '../../base/updateNodes'
|
|
29
|
+
import { typedSystem } from '../../state/utils'
|
|
29
30
|
import { centerXYInternalNode } from '../../utils'
|
|
30
|
-
import type { LayoutRelationshipsViewResult } from './-useRelationshipsView'
|
|
31
31
|
import type { RelationshipsBrowserTypes } from './_types'
|
|
32
32
|
import { ViewPadding } from './const'
|
|
33
|
+
import type { LayoutRelationshipsViewResult } from './layout'
|
|
33
34
|
import { viewToNodesEdge } from './useViewToNodesEdges'
|
|
34
35
|
|
|
35
36
|
type XYFLowInstance = ReactFlowInstance<RelationshipsBrowserTypes.Node, RelationshipsBrowserTypes.Edge>
|
|
@@ -247,6 +248,7 @@ export const relationshipsBrowserLogic = setup({
|
|
|
247
248
|
layouter,
|
|
248
249
|
},
|
|
249
250
|
guards: {
|
|
251
|
+
hasViewId: ({ context }) => context.viewId !== null,
|
|
250
252
|
isReady: ({ context }) => context.xyflow !== null && context.xystore !== null && context.layouted !== null,
|
|
251
253
|
anotherSubject: ({ context, event }) => {
|
|
252
254
|
if (event.type === 'update.view') {
|
|
@@ -393,10 +395,27 @@ export const relationshipsBrowserLogic = setup({
|
|
|
393
395
|
}
|
|
394
396
|
}),
|
|
395
397
|
},
|
|
398
|
+
'xyflow.edgeClick': {
|
|
399
|
+
guard: 'hasViewId',
|
|
400
|
+
actions: enqueueActions(({ event, context, system, enqueue }) => {
|
|
401
|
+
if (
|
|
402
|
+
event.edge.selected || event.edge.data.relations.length > 1
|
|
403
|
+
// (context.xyedges.some(e => e.data.dimmed === true || e.data.dimmed === 'immediate') && !event.edge.data.dimmed)
|
|
404
|
+
) {
|
|
405
|
+
enqueue.sendTo(typedSystem(system).overlaysActorRef!, {
|
|
406
|
+
type: 'open.relationshipDetails',
|
|
407
|
+
viewId: context.viewId!,
|
|
408
|
+
source: event.edge.data.sourceFqn,
|
|
409
|
+
target: event.edge.data.targetFqn,
|
|
410
|
+
})
|
|
411
|
+
}
|
|
412
|
+
}),
|
|
413
|
+
},
|
|
396
414
|
'navigate.to': {
|
|
397
415
|
actions: [
|
|
398
416
|
assign({
|
|
399
417
|
subject: ({ event }) => event.subject,
|
|
418
|
+
viewId: ({ event, context }) => event.viewId ?? context.viewId ?? null,
|
|
400
419
|
navigateFromNode: ({ event }) => event.fromNode ?? null,
|
|
401
420
|
}),
|
|
402
421
|
],
|
|
@@ -443,7 +462,7 @@ export const relationshipsBrowserLogic = setup({
|
|
|
443
462
|
actions: [
|
|
444
463
|
assign({
|
|
445
464
|
xyedges: ({ context, event }) => {
|
|
446
|
-
const hasDimmed = context.xyedges.some(edge => edge.data.dimmed
|
|
465
|
+
const hasDimmed = context.xyedges.some(edge => edge.data.dimmed !== false || edge.selected)
|
|
447
466
|
return context.xyedges.map(edge => {
|
|
448
467
|
if (edge.id === event.edge.id) {
|
|
449
468
|
return Base.setData(edge, {
|
|
@@ -451,25 +470,26 @@ export const relationshipsBrowserLogic = setup({
|
|
|
451
470
|
dimmed: false,
|
|
452
471
|
})
|
|
453
472
|
}
|
|
454
|
-
return hasDimmed && !edge.
|
|
473
|
+
return hasDimmed && !edge.selected ? Base.setDimmed(edge, 'immediate') : edge
|
|
455
474
|
})
|
|
456
475
|
},
|
|
457
476
|
}),
|
|
458
477
|
cancel('undim.edges'),
|
|
459
478
|
cancel('dim.nonhovered.edges'),
|
|
460
|
-
raise({ type: 'dim.nonhovered.edges' }, { id: 'dim.nonhovered.edges', delay:
|
|
479
|
+
raise({ type: 'dim.nonhovered.edges' }, { id: 'dim.nonhovered.edges', delay: 200 }),
|
|
461
480
|
],
|
|
462
481
|
},
|
|
463
482
|
'xyflow.edgeMouseLeave': {
|
|
464
483
|
actions: [
|
|
465
484
|
assign({
|
|
466
|
-
xyedges: ({ context, event }) =>
|
|
467
|
-
context.xyedges.map(edge => {
|
|
485
|
+
xyedges: ({ context, event }) => {
|
|
486
|
+
return context.xyedges.map(edge => {
|
|
468
487
|
if (edge.id === event.edge.id) {
|
|
469
488
|
return Base.setHovered(edge, false)
|
|
470
489
|
}
|
|
471
490
|
return edge
|
|
472
|
-
})
|
|
491
|
+
})
|
|
492
|
+
},
|
|
473
493
|
}),
|
|
474
494
|
cancel('dim.nonhovered.edges'),
|
|
475
495
|
raise({ type: 'undim.edges' }, { id: 'undim.edges', delay: 400 }),
|
|
@@ -477,18 +497,23 @@ export const relationshipsBrowserLogic = setup({
|
|
|
477
497
|
},
|
|
478
498
|
'dim.nonhovered.edges': {
|
|
479
499
|
actions: assign({
|
|
480
|
-
xyedges: ({ context }) =>
|
|
500
|
+
xyedges: ({ context }) =>
|
|
501
|
+
context.xyedges.map(edge =>
|
|
502
|
+
edge.data.hovered
|
|
503
|
+
? edge
|
|
504
|
+
: Base.setDimmed(edge, edge.data.dimmed === 'immediate' ? 'immediate' : true)
|
|
505
|
+
),
|
|
481
506
|
}),
|
|
482
507
|
},
|
|
483
508
|
'undim.edges': {
|
|
484
509
|
actions: assign({
|
|
485
510
|
xyedges: ({ context }) => {
|
|
486
|
-
const hasSelected = context.xyedges.some(edge => edge.selected === true)
|
|
487
|
-
if (hasSelected) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
511
|
+
// const hasSelected = context.xyedges.some(edge => edge.selected === true)
|
|
512
|
+
// if (hasSelected) {
|
|
513
|
+
// return context.xyedges.map(edge =>
|
|
514
|
+
// Base.setDimmed(edge, edge.selected !== true ? 'immediate' : false)
|
|
515
|
+
// )
|
|
516
|
+
// }
|
|
492
517
|
return context.xyedges.map(Base.setDimmed(false))
|
|
493
518
|
},
|
|
494
519
|
}),
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { IconFileSymlink, IconTransform, IconZoomScan } from '@tabler/icons-react'
|
|
2
2
|
import { ElementActionButtons } from '../../../base/primitives'
|
|
3
3
|
import type { NodeProps } from '../../../base/types'
|
|
4
|
-
import {
|
|
4
|
+
import { useEnabledFeatures } from '../../../context/DiagramFeatures'
|
|
5
|
+
import { useCurrentViewId } from '../../../hooks/useCurrentViewId'
|
|
5
6
|
import { useDiagram } from '../../../hooks/useDiagram'
|
|
6
7
|
import type { RelationshipsBrowserTypes as Types } from '../_types'
|
|
7
8
|
import { useRelationshipsBrowser, useRelationshipsBrowserState } from '../hooks'
|
|
8
9
|
|
|
9
10
|
type ElementActionsProps = NodeProps<Types.ElementNodeData>
|
|
10
11
|
export const ElementActions = (props: ElementActionsProps) => {
|
|
11
|
-
const { enableNavigateTo, enableVscode } =
|
|
12
|
+
const { enableNavigateTo, enableVscode } = useEnabledFeatures()
|
|
12
13
|
const diagram = useDiagram()
|
|
14
|
+
const currentViewId = useCurrentViewId()
|
|
13
15
|
const browser = useRelationshipsBrowser()
|
|
14
16
|
const subject = useRelationshipsBrowserState(s => s.context.subject)
|
|
15
17
|
|
|
16
18
|
const buttons = [] as ElementActionButtons.Item[]
|
|
17
19
|
|
|
18
20
|
const { navigateTo, fqn } = props.data
|
|
19
|
-
if (navigateTo && enableNavigateTo) {
|
|
21
|
+
if (navigateTo && enableNavigateTo && currentViewId !== navigateTo) {
|
|
20
22
|
buttons.push({
|
|
21
23
|
key: 'navigate',
|
|
22
24
|
icon: <IconZoomScan />,
|
|
@@ -67,7 +67,7 @@ export const RelationshipEdge = customEdge<RelationshipsBrowserTypes.EdgeData>((
|
|
|
67
67
|
label="This relationship is not included in the current view"
|
|
68
68
|
// withinPortal={false}
|
|
69
69
|
portalProps={{
|
|
70
|
-
target: `#${browser.rootElementId
|
|
70
|
+
target: `#${browser.rootElementId}`,
|
|
71
71
|
}}
|
|
72
72
|
openDelay={800}
|
|
73
73
|
>
|
|
@@ -2,10 +2,10 @@ import { type Fqn, nonNullable } from '@likec4/core'
|
|
|
2
2
|
import { useCallbackRef } from '@mantine/hooks'
|
|
3
3
|
import { useSelector } from '@xstate/react'
|
|
4
4
|
import { shallowEqual } from 'fast-equals'
|
|
5
|
-
import { createContext, useContext, useMemo
|
|
5
|
+
import { createContext, useContext, useMemo } from 'react'
|
|
6
6
|
import type { OverlaysActorRef } from '../overlaysActor'
|
|
7
|
-
import type { LayoutRelationshipsViewResult } from './-useRelationshipsView'
|
|
8
7
|
import type { RelationshipsBrowserActorRef, RelationshipsBrowserSnapshot } from './actor'
|
|
8
|
+
import type { LayoutRelationshipsViewResult } from './layout'
|
|
9
9
|
|
|
10
10
|
export const RelationshipsBrowserActorContext = createContext<RelationshipsBrowserActorRef | null>(null)
|
|
11
11
|
|
|
@@ -23,11 +23,10 @@ export function useRelationshipsBrowserState<T>(
|
|
|
23
23
|
|
|
24
24
|
export function useRelationshipsBrowser() {
|
|
25
25
|
const actor = useRelationshipsBrowserActor()
|
|
26
|
-
const [, startTransition] = useTransition()
|
|
27
26
|
return useMemo(() => ({
|
|
28
27
|
actor,
|
|
29
28
|
get rootElementId(): string {
|
|
30
|
-
return `relationships-browser-${actor.sessionId}`
|
|
29
|
+
return `relationships-browser-${actor.sessionId.replaceAll(':', '_')}`
|
|
31
30
|
},
|
|
32
31
|
getState: () => actor.getSnapshot().context,
|
|
33
32
|
send: actor.send,
|
|
@@ -44,12 +43,10 @@ export function useRelationshipsBrowser() {
|
|
|
44
43
|
})
|
|
45
44
|
},
|
|
46
45
|
navigateTo: (subject: Fqn, fromNode?: string) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fromNode,
|
|
52
|
-
})
|
|
46
|
+
actor.send({
|
|
47
|
+
type: 'navigate.to',
|
|
48
|
+
subject,
|
|
49
|
+
fromNode,
|
|
53
50
|
})
|
|
54
51
|
},
|
|
55
52
|
fitDiagram: () => {
|
|
@@ -55,7 +55,7 @@ const Sizes = {
|
|
|
55
55
|
edgesep: 25,
|
|
56
56
|
} satisfies GraphLabel,
|
|
57
57
|
edgeLabel: {
|
|
58
|
-
width:
|
|
58
|
+
width: 140,
|
|
59
59
|
height: 10,
|
|
60
60
|
minlen: 1,
|
|
61
61
|
weight: 1,
|
|
@@ -97,19 +97,6 @@ function createGraph() {
|
|
|
97
97
|
g.setDefaultEdgeLabel(() => ({ ...Sizes.edgeLabel }))
|
|
98
98
|
g.setDefaultNodeLabel(() => ({}))
|
|
99
99
|
|
|
100
|
-
// columns.reduce((prev, column) => {
|
|
101
|
-
// const c = graphColumn(column)
|
|
102
|
-
// g.setNode(c.id, {})
|
|
103
|
-
// g.setNode(c.anchor, { width: 40, height: 2 })
|
|
104
|
-
// g.setParent(c.anchor, c.id)
|
|
105
|
-
// if (prev) {
|
|
106
|
-
// g.setEdge(prev, c.anchor, {
|
|
107
|
-
// width: 0
|
|
108
|
-
// })
|
|
109
|
-
// }
|
|
110
|
-
// return c.anchor
|
|
111
|
-
// }, null as string | null)
|
|
112
|
-
|
|
113
100
|
return g
|
|
114
101
|
}
|
|
115
102
|
type G = ReturnType<typeof createGraph>
|
|
@@ -212,12 +199,14 @@ export type LayoutRelationshipsViewResult = {
|
|
|
212
199
|
export namespace LayoutRelationshipsViewResult {
|
|
213
200
|
export const Empty = '@empty' as ElementKind
|
|
214
201
|
|
|
215
|
-
export type Node = DiagramNode & {
|
|
202
|
+
export type Node = Omit<DiagramNode, 'deploymentRef' | 'inEdges' | 'outEdges'> & {
|
|
216
203
|
column: RelationshipsBrowserTypes.Column
|
|
217
204
|
ports: RelationshipsBrowserTypes.Ports
|
|
218
205
|
existsInCurrentView: boolean
|
|
219
206
|
}
|
|
220
207
|
export type Edge = DiagramEdge & {
|
|
208
|
+
sourceFqn: Fqn
|
|
209
|
+
targetFqn: Fqn
|
|
221
210
|
sourceHandle: string
|
|
222
211
|
targetHandle: string
|
|
223
212
|
existsInCurrentView: boolean
|
|
@@ -239,6 +228,8 @@ export function layoutRelationshipsView(
|
|
|
239
228
|
name: string
|
|
240
229
|
source: string // node id
|
|
241
230
|
target: string // node id
|
|
231
|
+
sourceFqn: Fqn
|
|
232
|
+
targetFqn: Fqn
|
|
242
233
|
sourceHandle: string
|
|
243
234
|
targetHandle: string
|
|
244
235
|
relations: RelationshipModel[]
|
|
@@ -250,6 +241,8 @@ export function layoutRelationshipsView(
|
|
|
250
241
|
toArray(data.incoming),
|
|
251
242
|
map(r => ({
|
|
252
243
|
id: r.source.id,
|
|
244
|
+
sourceFqn: r.source.id,
|
|
245
|
+
targetFqn: r.target.id,
|
|
253
246
|
source: incomers.byId(r.source.id).graph,
|
|
254
247
|
target: subjects.byId(r.target.id).graph,
|
|
255
248
|
relation: r,
|
|
@@ -259,6 +252,8 @@ export function layoutRelationshipsView(
|
|
|
259
252
|
toArray(data.outgoing),
|
|
260
253
|
map(r => ({
|
|
261
254
|
id: r.target.id,
|
|
255
|
+
sourceFqn: r.source.id,
|
|
256
|
+
targetFqn: r.target.id,
|
|
262
257
|
source: subjects.byId(r.source.id).graph,
|
|
263
258
|
target: outgoers.byId(r.target.id).graph,
|
|
264
259
|
relation: r,
|
|
@@ -284,6 +279,8 @@ export function layoutRelationshipsView(
|
|
|
284
279
|
}, name)
|
|
285
280
|
edges.push({
|
|
286
281
|
name,
|
|
282
|
+
sourceFqn: grouped[0].sourceFqn,
|
|
283
|
+
targetFqn: grouped[0].targetFqn,
|
|
287
284
|
source: source.id,
|
|
288
285
|
sourceHandle: source.id + '_out' + (g.node(source.id).outPorts.length - 1),
|
|
289
286
|
target: target.id,
|
|
@@ -358,7 +355,7 @@ export function layoutRelationshipsView(
|
|
|
358
355
|
for (const edge of g.edges()) {
|
|
359
356
|
g.setEdge(edge, {
|
|
360
357
|
...Sizes.edgeLabel,
|
|
361
|
-
width: edgeCount >
|
|
358
|
+
width: edgeCount > 25 ? 800 : 400,
|
|
362
359
|
})
|
|
363
360
|
}
|
|
364
361
|
}
|
|
@@ -444,17 +441,6 @@ export function layoutRelationshipsView(
|
|
|
444
441
|
const [subject] = [...subjects.root]
|
|
445
442
|
invariant(subject, 'Subjects should not be empty')
|
|
446
443
|
let subjectBounds = nodeBounds(subjects.graphNodes.get(subject.id).id)
|
|
447
|
-
// let subjectBounds = rest.reduce((bounds, el) => {
|
|
448
|
-
// const elBounds = nodeBounds(subjects.graphNodes.get(el.id).id)
|
|
449
|
-
// return {
|
|
450
|
-
// position: {
|
|
451
|
-
// x: Math.min(bounds.position.x, elBounds.position.x),
|
|
452
|
-
// y: Math.min(bounds.position.y, elBounds.position.y),
|
|
453
|
-
// },
|
|
454
|
-
// width: Math.max(bounds.width, elBounds.width),
|
|
455
|
-
// height: Math.max(bounds.height, elBounds.height),
|
|
456
|
-
// }
|
|
457
|
-
// }, nodeBounds(subjects.graphNodes.get(subject.id).id))
|
|
458
444
|
|
|
459
445
|
const nodes = nodeIds.map(({ id }): LayoutRelationshipsViewResult.Node => {
|
|
460
446
|
const { element, inPorts, outPorts, column } = g.node(id)
|
|
@@ -493,8 +479,6 @@ export function layoutRelationshipsView(
|
|
|
493
479
|
width: width,
|
|
494
480
|
height: height,
|
|
495
481
|
},
|
|
496
|
-
inEdges: [],
|
|
497
|
-
outEdges: [],
|
|
498
482
|
children: [],
|
|
499
483
|
width,
|
|
500
484
|
height,
|
|
@@ -513,7 +497,7 @@ export function layoutRelationshipsView(
|
|
|
513
497
|
minX = Math.min(minX, position.x)
|
|
514
498
|
minY = Math.min(minY, position.y)
|
|
515
499
|
|
|
516
|
-
const navigateTo = element.
|
|
500
|
+
const navigateTo = scope ? ifind(element.scopedViews(), v => v.id !== scope.id)?.id ?? null : null
|
|
517
501
|
|
|
518
502
|
const inheritFromNode = scope?.findNodeWithElement(element.id)
|
|
519
503
|
const scopedAncestor = scope && !inheritFromNode
|
|
@@ -547,8 +531,6 @@ export function layoutRelationshipsView(
|
|
|
547
531
|
...element.$element.style,
|
|
548
532
|
},
|
|
549
533
|
navigateTo,
|
|
550
|
-
inEdges: [],
|
|
551
|
-
outEdges: [],
|
|
552
534
|
...(children.length > 0 && { depth: nodeDepth(id) }),
|
|
553
535
|
children,
|
|
554
536
|
width,
|
|
@@ -577,7 +559,16 @@ export function layoutRelationshipsView(
|
|
|
577
559
|
if (!ename) {
|
|
578
560
|
return acc
|
|
579
561
|
}
|
|
580
|
-
const {
|
|
562
|
+
const {
|
|
563
|
+
name,
|
|
564
|
+
source,
|
|
565
|
+
sourceFqn,
|
|
566
|
+
target,
|
|
567
|
+
targetFqn,
|
|
568
|
+
relations,
|
|
569
|
+
sourceHandle,
|
|
570
|
+
targetHandle,
|
|
571
|
+
} = find(edges, e => e.name === ename)!
|
|
581
572
|
const onlyRelation = only(relations)
|
|
582
573
|
const label = onlyRelation?.title ?? 'untitled'
|
|
583
574
|
const isMultiple = relations.length > 1
|
|
@@ -587,8 +578,10 @@ export function layoutRelationshipsView(
|
|
|
587
578
|
// const edge = g.edge(name)
|
|
588
579
|
acc.push({
|
|
589
580
|
id: name as EdgeId,
|
|
581
|
+
sourceFqn,
|
|
590
582
|
source: source as NodeId,
|
|
591
583
|
sourceHandle,
|
|
584
|
+
targetFqn,
|
|
592
585
|
target: target as NodeId,
|
|
593
586
|
targetHandle,
|
|
594
587
|
label: isMultiple ? `${relations.length} relationships` : label,
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
import { useDeepCompareMemo } from '@react-hookz/web'
|
|
10
10
|
import { hasAtLeast } from 'remeda'
|
|
11
11
|
import { ZIndexes } from '../../base/const'
|
|
12
|
-
import { LayoutRelationshipsViewResult } from './-useRelationshipsView'
|
|
13
12
|
import type { RelationshipsBrowserTypes } from './_types'
|
|
13
|
+
import { LayoutRelationshipsViewResult } from './layout'
|
|
14
14
|
|
|
15
15
|
// const nodeZIndex = (node: DiagramNode) => node.level - (node.children.length > 0 ? 1 : 0)
|
|
16
16
|
export function viewToNodesEdge(
|
|
@@ -183,6 +183,8 @@ export function viewToNodesEdge(
|
|
|
183
183
|
// hidden: !visiblePredicate(edge),
|
|
184
184
|
deletable: false,
|
|
185
185
|
data: {
|
|
186
|
+
sourceFqn: edge.sourceFqn,
|
|
187
|
+
targetFqn: edge.targetFqn,
|
|
186
188
|
relations: edge.relations,
|
|
187
189
|
color: edge.color ?? 'gray',
|
|
188
190
|
label: edge.label,
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
type BBox,
|
|
3
3
|
type DiagramView,
|
|
4
4
|
type EdgeId,
|
|
5
|
+
type ElementNotation,
|
|
5
6
|
type Fqn,
|
|
6
7
|
type NodeId,
|
|
7
8
|
type StepEdgeId,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
useStoreApi,
|
|
24
25
|
} from '@xyflow/react'
|
|
25
26
|
import { type EdgeChange, type NodeChange, type Rect, type Viewport, nodeToRect } from '@xyflow/system'
|
|
26
|
-
import { clamp, first, hasAtLeast, prop } from 'remeda'
|
|
27
|
+
import { clamp, first, hasAtLeast, prop, reduce } from 'remeda'
|
|
27
28
|
import {
|
|
28
29
|
type ActorLogicFrom,
|
|
29
30
|
type ActorRef,
|
|
@@ -44,7 +45,7 @@ import {
|
|
|
44
45
|
import { MinZoom } from '../base/const'
|
|
45
46
|
import { Base } from '../base/types'
|
|
46
47
|
import { type EnabledFeatures, type FeatureName, AllDisabled } from '../context/DiagramFeatures'
|
|
47
|
-
import type { OpenSourceParams } from '../LikeC4Diagram.props'
|
|
48
|
+
import type { OpenSourceParams, PaddingWithUnit } from '../LikeC4Diagram.props'
|
|
48
49
|
import type { Types } from '../likec4diagram/types'
|
|
49
50
|
import { createLayoutConstraints } from '../likec4diagram/useLayoutConstraints'
|
|
50
51
|
import { overlaysActorLogic } from '../overlays/overlaysActor'
|
|
@@ -83,7 +84,7 @@ export interface Input {
|
|
|
83
84
|
xystore: XYStoreApi
|
|
84
85
|
zoomable: boolean
|
|
85
86
|
pannable: boolean
|
|
86
|
-
fitViewPadding:
|
|
87
|
+
fitViewPadding: PaddingWithUnit
|
|
87
88
|
nodesSelectable: boolean
|
|
88
89
|
}
|
|
89
90
|
|
|
@@ -156,7 +157,7 @@ export type Events =
|
|
|
156
157
|
| { type: 'fitDiagram'; duration?: number; bounds?: BBox }
|
|
157
158
|
| ({ type: 'open.source' } & OpenSourceParams)
|
|
158
159
|
| { type: 'open.elementDetails'; fqn: Fqn; fromNode?: NodeId | undefined }
|
|
159
|
-
| { type: 'open.relationshipDetails'; edgeId: EdgeId }
|
|
160
|
+
| { type: 'open.relationshipDetails'; params: { edgeId: EdgeId } | { source: Fqn; target: Fqn } }
|
|
160
161
|
| { type: 'open.relationshipsBrowser'; fqn: Fqn }
|
|
161
162
|
// | { type: 'close.overlay' }
|
|
162
163
|
| { type: 'navigate.to'; viewId: ViewId; fromNode?: NodeId | undefined }
|
|
@@ -170,6 +171,8 @@ export type Events =
|
|
|
170
171
|
| { type: 'walkthrough.start'; stepId?: StepEdgeId }
|
|
171
172
|
| { type: 'walkthrough.step'; direction: 'next' | 'previous' }
|
|
172
173
|
| { type: 'walkthrough.end' }
|
|
174
|
+
| { type: 'notations.highlight'; notation: ElementNotation; kind?: string }
|
|
175
|
+
| { type: 'notations.unhighlight' }
|
|
173
176
|
| { type: 'toggle.feature'; feature: FeatureName; forceValue?: boolean }
|
|
174
177
|
|
|
175
178
|
export type ActionArg = { context: Context; event: Events }
|
|
@@ -440,6 +443,26 @@ export const diagramMachine = setup({
|
|
|
440
443
|
}),
|
|
441
444
|
}
|
|
442
445
|
}),
|
|
446
|
+
'notations.highlight': assign(({ context }, params: { notation: ElementNotation; kind?: string }) => {
|
|
447
|
+
const kinds = params.kind ? [params.kind] : params.notation.kinds
|
|
448
|
+
const xynodes = context.xynodes.map((n) => {
|
|
449
|
+
const node = findDiagramNode(context, n.id)
|
|
450
|
+
if (
|
|
451
|
+
node &&
|
|
452
|
+
node.notation === params.notation.title &&
|
|
453
|
+
node.shape === params.notation.shape &&
|
|
454
|
+
node.color === params.notation.color &&
|
|
455
|
+
kinds.includes(node.kind)
|
|
456
|
+
) {
|
|
457
|
+
return Base.setDimmed(n, false)
|
|
458
|
+
}
|
|
459
|
+
return Base.setDimmed(n, 'immediate')
|
|
460
|
+
})
|
|
461
|
+
return {
|
|
462
|
+
xynodes,
|
|
463
|
+
xyedges: context.xyedges.map(Base.setDimmed('immediate')),
|
|
464
|
+
}
|
|
465
|
+
}),
|
|
443
466
|
},
|
|
444
467
|
}).createMachine({
|
|
445
468
|
initial: 'initializing',
|
|
@@ -617,8 +640,8 @@ export const diagramMachine = setup({
|
|
|
617
640
|
'open.relationshipDetails': {
|
|
618
641
|
actions: sendTo(({ system }) => typedSystem(system).overlaysActorRef!, ({ context, event }) => ({
|
|
619
642
|
type: 'open.relationshipDetails',
|
|
620
|
-
|
|
621
|
-
|
|
643
|
+
viewId: context.view.id,
|
|
644
|
+
...event.params,
|
|
622
645
|
})),
|
|
623
646
|
},
|
|
624
647
|
'open.source': {
|
|
@@ -666,6 +689,18 @@ export const diagramMachine = setup({
|
|
|
666
689
|
params: prop('event'),
|
|
667
690
|
},
|
|
668
691
|
},
|
|
692
|
+
'notations.highlight': {
|
|
693
|
+
actions: {
|
|
694
|
+
type: 'notations.highlight',
|
|
695
|
+
params: prop('event'),
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
'notations.unhighlight': {
|
|
699
|
+
actions: assign(({ context }) => ({
|
|
700
|
+
xynodes: context.xynodes.map(Base.setDimmed(false)),
|
|
701
|
+
xyedges: context.xyedges.map(Base.setDimmed(false)),
|
|
702
|
+
})),
|
|
703
|
+
},
|
|
669
704
|
'saveManualLayout.*': {
|
|
670
705
|
guard: 'not readonly',
|
|
671
706
|
actions: sendTo((c) => c.context.syncLayoutActorRef!, ({ event }) => {
|
|
@@ -794,6 +829,11 @@ export const diagramMachine = setup({
|
|
|
794
829
|
}),
|
|
795
830
|
target: 'idle',
|
|
796
831
|
},
|
|
832
|
+
'notations.unhighlight': {
|
|
833
|
+
actions: assign(s => ({
|
|
834
|
+
...focusNodesEdges(s),
|
|
835
|
+
})),
|
|
836
|
+
},
|
|
797
837
|
},
|
|
798
838
|
},
|
|
799
839
|
walkthrough: {
|
|
@@ -845,6 +885,11 @@ export const diagramMachine = setup({
|
|
|
845
885
|
enqueue('xyflow:fitFocusedBounds')
|
|
846
886
|
}),
|
|
847
887
|
},
|
|
888
|
+
'notations.unhighlight': {
|
|
889
|
+
actions: assign(s => ({
|
|
890
|
+
...updateActiveWalkthrough(s),
|
|
891
|
+
})),
|
|
892
|
+
},
|
|
848
893
|
'walkthrough.end': {
|
|
849
894
|
target: 'idle',
|
|
850
895
|
},
|
package/src/utils/index.ts
CHANGED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { DiagramEdge, DiagramView, EdgeId } from '@likec4/core';
|
|
2
|
-
import { RelationshipDetailsTypes } from './_types';
|
|
3
|
-
export declare const ZIndexes: {
|
|
4
|
-
compound: number;
|
|
5
|
-
edge: number;
|
|
6
|
-
element: number;
|
|
7
|
-
max: number;
|
|
8
|
-
};
|
|
9
|
-
export declare function useLayoutedDetails(edgeId: EdgeId, view: DiagramView): {
|
|
10
|
-
edge: DiagramEdge;
|
|
11
|
-
xynodes: RelationshipDetailsTypes.Node[];
|
|
12
|
-
xyedges: RelationshipDetailsTypes.Edge[];
|
|
13
|
-
bounds: {
|
|
14
|
-
x: number;
|
|
15
|
-
y: number;
|
|
16
|
-
width: number;
|
|
17
|
-
height: number;
|
|
18
|
-
};
|
|
19
|
-
};
|