@likec4/diagram 1.27.1 → 1.27.2

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.
Files changed (115) hide show
  1. package/bundle/index.js +2147 -6730
  2. package/dist/LikeC4Diagram.js +1 -1
  3. package/dist/LikeC4Diagram.props.d.ts +5 -3
  4. package/dist/StaticLikeC4Diagram.js +1 -1
  5. package/dist/_virtual/set.js +5 -0
  6. package/dist/_virtual/set2.js +3 -0
  7. package/dist/base/BaseXYFlow.d.ts +2 -1
  8. package/dist/base/primitives/compound/CompoundNodeContainer.d.ts +1 -1
  9. package/dist/base/primitives/compound/CompoundNodeContainer.js +0 -1
  10. package/dist/base/primitives/element/ElementActionButtons.js +5 -10
  11. package/dist/base/primitives/element/ElementNodeContainer.css.js +4 -4
  12. package/dist/base/updateEdges.js +1 -9
  13. package/dist/base/updateNodes.js +1 -12
  14. package/dist/bundle/LikeC4View.js +2 -2
  15. package/dist/bundle/LikeC4View.props.d.ts +7 -7
  16. package/dist/hooks/useCurrentViewId.js +8 -2
  17. package/dist/hooks/useDiagram.d.ts +1517 -684
  18. package/dist/hooks/useDiagram.js +16 -8
  19. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +3 -3
  20. package/dist/likec4diagram/ui/notation/NotationPanel.js +10 -4
  21. package/dist/node_modules/.pnpm/mnemonist@0.40.3_patch_hash_5c12abb43fcff6fd81e53021b89075d53249640d165a2556cc1e58d71201a13a/node_modules/mnemonist/set.js +369 -0
  22. package/dist/overlays/Overlays.js +3 -1
  23. package/dist/overlays/element-details/actor.d.ts +2769 -173
  24. package/dist/overlays/overlay/Overlay.css.d.ts +26 -2
  25. package/dist/overlays/overlay/Overlay.css.js +66 -18
  26. package/dist/overlays/overlay/Overlay.d.ts +7 -6
  27. package/dist/overlays/overlay/Overlay.js +12 -8
  28. package/dist/overlays/overlaysActor.js +2 -2
  29. package/dist/overlays/relationship-details/RelationshipDetails.js +113 -70
  30. package/dist/overlays/relationship-details/SelectEdge.d.ts +1 -1
  31. package/dist/overlays/relationship-details/SelectEdge.js +15 -9
  32. package/dist/overlays/relationship-details/_types.d.ts +4 -1
  33. package/dist/overlays/relationship-details/actor.d.ts +415 -128
  34. package/dist/overlays/relationship-details/actor.js +162 -53
  35. package/dist/overlays/relationship-details/compute.d.ts +12 -0
  36. package/dist/overlays/relationship-details/compute.js +139 -0
  37. package/dist/overlays/relationship-details/custom/ElementActions.js +27 -5
  38. package/dist/overlays/relationship-details/custom/edgeTypes.js +1 -1
  39. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +2 -1
  40. package/dist/overlays/relationship-details/hooks.d.ts +336 -6
  41. package/dist/overlays/relationship-details/hooks.js +9 -7
  42. package/dist/overlays/relationship-details/layout-to-xyflow.d.ts +12 -0
  43. package/dist/overlays/relationship-details/layout-to-xyflow.js +149 -0
  44. package/dist/overlays/relationship-details/layout.d.ts +22 -0
  45. package/dist/overlays/relationship-details/layout.js +314 -0
  46. package/dist/overlays/relationships-browser/RelationshipsBrowser.d.ts +3 -1
  47. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +2 -2
  48. package/dist/overlays/relationships-browser/_types.d.ts +2 -0
  49. package/dist/overlays/relationships-browser/actor.d.ts +130 -14
  50. package/dist/overlays/relationships-browser/actor.js +30 -16
  51. package/dist/overlays/relationships-browser/custom/ElementActions.js +5 -3
  52. package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +3 -1
  53. package/dist/overlays/relationships-browser/custom/edgeTypes.js +1 -1
  54. package/dist/overlays/relationships-browser/hooks.d.ts +3 -1
  55. package/dist/overlays/relationships-browser/hooks.js +1 -1
  56. package/dist/overlays/relationships-browser/{-useRelationshipsView.d.ts → layout.d.ts} +2 -0
  57. package/dist/overlays/relationships-browser/{-useRelationshipsView.js → layout.js} +19 -2
  58. package/dist/overlays/relationships-browser/useViewToNodesEdges.d.ts +1 -1
  59. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +3 -1
  60. package/dist/packages/core/src/compute-view/relationships-view/compute.js +1 -1
  61. package/dist/packages/core/src/model/connection/model/ConnectionModel.js +121 -0
  62. package/dist/packages/core/src/model/connection/model/find.js +39 -0
  63. package/dist/packages/core/src/model/connection/ops.js +7 -0
  64. package/dist/packages/core/src/utils/const.js +3 -0
  65. package/dist/packages/core/src/utils/fqn.js +9 -1
  66. package/dist/packages/core/src/utils/iterable/find.js +21 -0
  67. package/dist/packages/core/src/utils/iterable/some.js +21 -0
  68. package/dist/packages/core/src/utils/set.js +48 -0
  69. package/dist/packages/core/src/utils/string-hash.js +13 -0
  70. package/dist/state/diagram-machine.d.ts +1552 -703
  71. package/dist/state/diagram-machine.js +39 -3
  72. package/dist/state/syncManualLayoutActor.d.ts +1 -1
  73. package/dist/styles.css.js +1 -1
  74. package/package.json +11 -11
  75. package/src/LikeC4Diagram.props.ts +7 -3
  76. package/src/LikeC4Diagram.tsx +1 -1
  77. package/src/StaticLikeC4Diagram.tsx +1 -1
  78. package/src/base/BaseXYFlow.tsx +2 -1
  79. package/src/base/primitives/compound/CompoundNodeContainer.tsx +0 -2
  80. package/src/base/primitives/element/ElementActionButtons.tsx +6 -7
  81. package/src/base/primitives/element/ElementNodeContainer.css.ts +4 -4
  82. package/src/base/updateEdges.ts +8 -8
  83. package/src/base/updateNodes.ts +11 -11
  84. package/src/bundle/LikeC4View.props.ts +7 -7
  85. package/src/bundle/LikeC4View.tsx +2 -2
  86. package/src/hooks/useCurrentViewId.ts +4 -2
  87. package/src/hooks/useDiagram.ts +18 -9
  88. package/src/likec4diagram/ui/notation/NotationPanel.css.ts +2 -2
  89. package/src/likec4diagram/ui/notation/NotationPanel.tsx +8 -6
  90. package/src/overlays/Overlays.tsx +3 -1
  91. package/src/overlays/overlay/Overlay.css.ts +67 -17
  92. package/src/overlays/overlay/Overlay.tsx +26 -21
  93. package/src/overlays/overlaysActor.ts +1 -1
  94. package/src/overlays/relationship-details/RelationshipDetails.tsx +131 -68
  95. package/src/overlays/relationship-details/SelectEdge.tsx +19 -12
  96. package/src/overlays/relationship-details/_types.ts +3 -1
  97. package/src/overlays/relationship-details/actor.ts +217 -68
  98. package/src/overlays/relationship-details/compute.ts +186 -0
  99. package/src/overlays/relationship-details/custom/ElementActions.tsx +27 -18
  100. package/src/overlays/relationship-details/custom/edgeTypes.tsx +1 -1
  101. package/src/overlays/relationship-details/hooks.ts +10 -8
  102. package/src/overlays/relationship-details/layout-to-xyflow.ts +195 -0
  103. package/src/overlays/relationship-details/layout.ts +470 -0
  104. package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +2 -2
  105. package/src/overlays/relationships-browser/_types.ts +2 -0
  106. package/src/overlays/relationships-browser/actor.ts +39 -14
  107. package/src/overlays/relationships-browser/custom/ElementActions.tsx +5 -3
  108. package/src/overlays/relationships-browser/custom/edgeTypes.tsx +1 -1
  109. package/src/overlays/relationships-browser/hooks.ts +2 -2
  110. package/src/overlays/relationships-browser/{-useRelationshipsView.ts → layout.ts} +23 -13
  111. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +3 -1
  112. package/src/state/diagram-machine.ts +51 -6
  113. package/dist/overlays/relationship-details/useLayoutedDetails.d.ts +0 -19
  114. package/dist/overlays/relationship-details/useLayoutedDetails.js +0 -267
  115. package/src/overlays/relationship-details/useLayoutedDetails.ts +0 -376
@@ -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 === true)
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.data.dimmed && !edge.selected ? Base.setDimmed(edge, 'immediate') : 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: 100 }),
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 }) => context.xyedges.map(edge => Base.setDimmed(edge, edge.data.hovered !== true)),
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
- return context.xyedges.map(edge =>
489
- Base.setDimmed(edge, edge.selected !== true ? edge.data.dimmed || 'immediate' : false)
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 { useEnabledFeature } from '../../../context/DiagramFeatures'
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 } = useEnabledFeature('NavigateTo', 'Vscode')
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.replaceAll(':', '\\:')}`,
70
+ target: `#${browser.rootElementId}`,
71
71
  }}
72
72
  openDelay={800}
73
73
  >
@@ -4,8 +4,8 @@ import { useSelector } from '@xstate/react'
4
4
  import { shallowEqual } from 'fast-equals'
5
5
  import { createContext, useContext, useMemo, useTransition } 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
 
@@ -27,7 +27,7 @@ export function useRelationshipsBrowser() {
27
27
  return useMemo(() => ({
28
28
  actor,
29
29
  get rootElementId(): string {
30
- return `relationships-browser-${actor.sessionId}`
30
+ return `relationships-browser-${actor.sessionId.replaceAll(':', '_')}`
31
31
  },
32
32
  getState: () => actor.getSnapshot().context,
33
33
  send: actor.send,
@@ -218,6 +218,8 @@ export namespace LayoutRelationshipsViewResult {
218
218
  existsInCurrentView: boolean
219
219
  }
220
220
  export type Edge = DiagramEdge & {
221
+ sourceFqn: Fqn
222
+ targetFqn: Fqn
221
223
  sourceHandle: string
222
224
  targetHandle: string
223
225
  existsInCurrentView: boolean
@@ -239,6 +241,8 @@ export function layoutRelationshipsView(
239
241
  name: string
240
242
  source: string // node id
241
243
  target: string // node id
244
+ sourceFqn: Fqn
245
+ targetFqn: Fqn
242
246
  sourceHandle: string
243
247
  targetHandle: string
244
248
  relations: RelationshipModel[]
@@ -250,6 +254,8 @@ export function layoutRelationshipsView(
250
254
  toArray(data.incoming),
251
255
  map(r => ({
252
256
  id: r.source.id,
257
+ sourceFqn: r.source.id,
258
+ targetFqn: r.target.id,
253
259
  source: incomers.byId(r.source.id).graph,
254
260
  target: subjects.byId(r.target.id).graph,
255
261
  relation: r,
@@ -259,6 +265,8 @@ export function layoutRelationshipsView(
259
265
  toArray(data.outgoing),
260
266
  map(r => ({
261
267
  id: r.target.id,
268
+ sourceFqn: r.source.id,
269
+ targetFqn: r.target.id,
262
270
  source: subjects.byId(r.source.id).graph,
263
271
  target: outgoers.byId(r.target.id).graph,
264
272
  relation: r,
@@ -284,6 +292,8 @@ export function layoutRelationshipsView(
284
292
  }, name)
285
293
  edges.push({
286
294
  name,
295
+ sourceFqn: grouped[0].sourceFqn,
296
+ targetFqn: grouped[0].targetFqn,
287
297
  source: source.id,
288
298
  sourceHandle: source.id + '_out' + (g.node(source.id).outPorts.length - 1),
289
299
  target: target.id,
@@ -444,17 +454,6 @@ export function layoutRelationshipsView(
444
454
  const [subject] = [...subjects.root]
445
455
  invariant(subject, 'Subjects should not be empty')
446
456
  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
457
 
459
458
  const nodes = nodeIds.map(({ id }): LayoutRelationshipsViewResult.Node => {
460
459
  const { element, inPorts, outPorts, column } = g.node(id)
@@ -513,7 +512,7 @@ export function layoutRelationshipsView(
513
512
  minX = Math.min(minX, position.x)
514
513
  minY = Math.min(minY, position.y)
515
514
 
516
- const navigateTo = element.defaultView?.id ?? null
515
+ const navigateTo = scope ? ifind(element.scopedViews(), v => v.id !== scope.id)?.id ?? null : null
517
516
 
518
517
  const inheritFromNode = scope?.findNodeWithElement(element.id)
519
518
  const scopedAncestor = scope && !inheritFromNode
@@ -577,7 +576,16 @@ export function layoutRelationshipsView(
577
576
  if (!ename) {
578
577
  return acc
579
578
  }
580
- const { name, source, target, relations, sourceHandle, targetHandle } = find(edges, e => e.name === ename)!
579
+ const {
580
+ name,
581
+ source,
582
+ sourceFqn,
583
+ target,
584
+ targetFqn,
585
+ relations,
586
+ sourceHandle,
587
+ targetHandle,
588
+ } = find(edges, e => e.name === ename)!
581
589
  const onlyRelation = only(relations)
582
590
  const label = onlyRelation?.title ?? 'untitled'
583
591
  const isMultiple = relations.length > 1
@@ -587,8 +595,10 @@ export function layoutRelationshipsView(
587
595
  // const edge = g.edge(name)
588
596
  acc.push({
589
597
  id: name as EdgeId,
598
+ sourceFqn,
590
599
  source: source as NodeId,
591
600
  sourceHandle,
601
+ targetFqn,
592
602
  target: target as NodeId,
593
603
  targetHandle,
594
604
  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: number
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
- view: context.view,
621
- edgeId: event.edgeId,
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
  },
@@ -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
- };