@likec4/diagram 1.32.0 → 1.32.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 (54) hide show
  1. package/README.md +12 -5
  2. package/bundle/{chunk-BvTQaUYl.js → chunk-DlHyKoeo.js} +236 -210
  3. package/bundle/custom.js +50 -49
  4. package/bundle/index.js +144 -121
  5. package/dist/LikeC4Diagram.js +1 -1
  6. package/dist/LikeC4Diagram.props.d.ts +14 -3
  7. package/dist/bundle/LikeC4View.js +16 -15
  8. package/dist/bundle/ReactLikeC4.js +7 -6
  9. package/dist/bundle/index.js +1 -1
  10. package/dist/custom/customNodes.d.ts +5 -0
  11. package/dist/custom/hooks.d.ts +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/likec4diagram/DiagramXYFlow.js +3 -3
  14. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +5 -5
  15. package/dist/likec4model/index.d.ts +1 -1
  16. package/dist/likec4model/useLikeC4Model.d.ts +2 -1
  17. package/dist/likec4model/useLikeC4Model.js +13 -2
  18. package/dist/overlays/overlay/Overlay.js +24 -4
  19. package/dist/search/Search.d.ts +2 -3
  20. package/dist/search/Search.js +27 -46
  21. package/dist/search/components/ElementsColumn.js +12 -13
  22. package/dist/search/components/PickView.js +6 -6
  23. package/dist/search/components/SearchByTags.js +5 -2
  24. package/dist/search/components/SearchInput.js +16 -14
  25. package/dist/search/components/ViewsColum.js +16 -9
  26. package/dist/search/components/utils.d.ts +3 -2
  27. package/dist/search/components/utils.js +37 -5
  28. package/dist/search/hooks.d.ts +2 -8
  29. package/dist/search/hooks.js +4 -4
  30. package/dist/state/DiagramActorProvider.js +1 -1
  31. package/dist/state/diagram-machine.d.ts +216 -8
  32. package/dist/state/diagram-machine.js +8 -6
  33. package/package.json +17 -16
  34. package/panda.buildinfo.json +1 -1
  35. package/src/LikeC4Diagram.props.ts +14 -3
  36. package/src/LikeC4Diagram.tsx +1 -1
  37. package/src/bundle/LikeC4View.tsx +12 -19
  38. package/src/bundle/ReactLikeC4.tsx +2 -10
  39. package/src/custom/customNodes.tsx +5 -0
  40. package/src/custom/hooks.ts +1 -0
  41. package/src/likec4diagram/DiagramXYFlow.tsx +3 -3
  42. package/src/likec4model/index.ts +2 -0
  43. package/src/likec4model/useLikeC4Model.ts +16 -2
  44. package/src/overlays/overlay/Overlay.tsx +20 -5
  45. package/src/search/Search.tsx +34 -51
  46. package/src/search/components/ElementsColumn.tsx +12 -15
  47. package/src/search/components/PickView.tsx +41 -47
  48. package/src/search/components/SearchByTags.tsx +5 -2
  49. package/src/search/components/SearchInput.tsx +17 -14
  50. package/src/search/components/ViewsColum.tsx +18 -10
  51. package/src/search/components/utils.ts +41 -4
  52. package/src/search/hooks.ts +5 -8
  53. package/src/state/DiagramActorProvider.tsx +2 -1
  54. package/src/state/diagram-machine.ts +8 -6
@@ -10,14 +10,8 @@ import * as styles from './styles.css'
10
10
  import { ViewButton } from './ViewsColum'
11
11
 
12
12
  export function PickView({ elementFqn }: { elementFqn: Fqn }) {
13
- const { searchActorRef } = useSearchActor()
13
+ const searchActorRef = useSearchActor()
14
14
  const element = useLikeC4Model().element(elementFqn)
15
- // const pickview = usePickView()
16
- // const navigateTo = useCloseSearchAndNavigateTo()
17
- // const focusTrapRef = useFocusTrap(!!pickview)
18
- // useFocusReturn({
19
- // opened: !!pickview,
20
- // })
21
15
  const scoped = [] as LikeC4ViewModel[]
22
16
  const others = [] as LikeC4ViewModel[]
23
17
 
@@ -61,44 +55,44 @@ export function PickView({ elementFqn }: { elementFqn: Fqn }) {
61
55
  closePickView()
62
56
  }}>
63
57
  </m.div>
64
- <m.div
65
- key="pickview"
66
- initial={{
67
- opacity: 0,
68
- scale: 0.95,
69
- originY: 0,
70
- translateX: '-50%',
71
- translateY: -20,
72
- }}
73
- animate={{
74
- opacity: 1,
75
- scale: 1,
76
- translateY: 0,
77
- }}
78
- exit={{
79
- opacity: 0,
80
- scale: 0.98,
81
- translateY: -20,
82
- transition: {
83
- duration: 0.1,
84
- },
85
- }}
86
- className={styles.pickview}
87
- data-likec4-search-views>
88
- <Group px="sm" py="md" justify="space-between">
89
- <Title order={2} lh={1}>Select view</Title>
90
- <ActionIcon
91
- size={'md'}
92
- variant="default"
93
- onClick={(e) => {
94
- e.stopPropagation()
95
- closePickView()
96
- }}>
97
- <IconX />
98
- </ActionIcon>
99
- </Group>
100
- <FocusTrap>
101
- <ScrollAreaAutosize mah={'calc(100vh - 8rem - 50px)'} type="never">
58
+ <FocusTrap>
59
+ <m.div
60
+ key="pickview"
61
+ initial={{
62
+ opacity: 0,
63
+ scale: 0.95,
64
+ originY: 0,
65
+ translateX: '-50%',
66
+ translateY: -20,
67
+ }}
68
+ animate={{
69
+ opacity: 1,
70
+ scale: 1,
71
+ translateY: 0,
72
+ }}
73
+ exit={{
74
+ opacity: 0,
75
+ scale: 0.98,
76
+ translateY: -20,
77
+ transition: {
78
+ duration: 0.1,
79
+ },
80
+ }}
81
+ className={styles.pickview}
82
+ data-likec4-search-views>
83
+ <Group px="sm" py="md" justify="space-between">
84
+ <Title order={2} lh={1}>Select view</Title>
85
+ <ActionIcon
86
+ size={'md'}
87
+ variant="default"
88
+ onClick={(e) => {
89
+ e.stopPropagation()
90
+ closePickView()
91
+ }}>
92
+ <IconX />
93
+ </ActionIcon>
94
+ </Group>
95
+ <ScrollAreaAutosize mah={'calc(100vh - 110px)'} type="never">
102
96
  {scoped.length > 0 && (
103
97
  <Stack gap={'sm'} px={'sm'} className={styles.pickviewGroup}>
104
98
  <Title order={6} c={'dimmed'}>scoped views of the element</Title>
@@ -133,8 +127,8 @@ export function PickView({ elementFqn }: { elementFqn: Fqn }) {
133
127
  </Stack>
134
128
  )}
135
129
  </ScrollAreaAutosize>
136
- </FocusTrap>
137
- </m.div>
130
+ </m.div>
131
+ </FocusTrap>
138
132
  </>
139
133
  )
140
134
  }
@@ -2,12 +2,14 @@ import { css } from '@likec4/styles/css'
2
2
  import { HStack } from '@likec4/styles/jsx'
3
3
  import { Button } from '@mantine/core'
4
4
  import { IconX } from '@tabler/icons-react'
5
+ import { useRef } from 'react'
5
6
  import { ElementTag } from '../../base/primitives'
6
7
  import { useLikeC4Model } from '../../likec4model/useLikeC4Model'
7
8
  import { useNormalizedSearch, useUpdateSearch } from '../hooks'
8
9
  import { focusToFirstFoundElement, moveFocusToSearchInput } from './utils'
9
10
 
10
11
  export function SearchByTags() {
12
+ const ref = useRef<HTMLDivElement>(null)
11
13
  let tags = useLikeC4Model().tagsSortedByUsage
12
14
  let setSearch = useUpdateSearch()
13
15
  let search = useNormalizedSearch()
@@ -24,6 +26,7 @@ export function SearchByTags() {
24
26
 
25
27
  return (
26
28
  <HStack
29
+ ref={ref}
27
30
  css={{
28
31
  gap: 'md',
29
32
  paddingLeft: 48,
@@ -84,7 +87,7 @@ export function SearchByTags() {
84
87
  setSearch(`#${tag}`)
85
88
  // Let react to display filtered elements
86
89
  setTimeout(() => {
87
- focusToFirstFoundElement()
90
+ focusToFirstFoundElement(ref.current)
88
91
  }, 350)
89
92
  }}
90
93
  />
@@ -97,7 +100,7 @@ export function SearchByTags() {
97
100
  onClick={(e) => {
98
101
  e.stopPropagation()
99
102
  setSearch('')
100
- moveFocusToSearchInput()
103
+ moveFocusToSearchInput(ref.current)
101
104
  }}
102
105
  rightSection={<IconX size={14} />}
103
106
  >
@@ -11,11 +11,10 @@ import {
11
11
  Text,
12
12
  useCombobox,
13
13
  } from '@mantine/core'
14
- import { useFocusWithin, useWindowEvent } from '@mantine/hooks'
15
- import { usePreviousDistinct } from '@react-hookz/web'
14
+ import { useFocusWithin, useMergedRef, useWindowEvent } from '@mantine/hooks'
16
15
  import { IconSearch } from '@tabler/icons-react'
17
- import { type ReactNode, memo } from 'react'
18
- import { keys, only } from 'remeda'
16
+ import { type ReactNode, memo, useRef } from 'react'
17
+ import { keys } from 'remeda'
19
18
  import { useLikeC4Model } from '../../likec4model/useLikeC4Model'
20
19
  import { useSearch, useSearchActor } from '../hooks'
21
20
  import * as css from './styles.css'
@@ -28,11 +27,12 @@ function startingWithKind(search: string) {
28
27
  const SEARCH_PREFIXES = ['#', 'kind:']
29
28
 
30
29
  export const LikeC4SearchInput = memo(() => {
31
- const { close, searchActorRef } = useSearchActor()
30
+ const searchActorRef = useSearchActor()
32
31
  const likec4model = useLikeC4Model()
32
+ const inputRef = useRef<HTMLInputElement>(null)
33
33
  const { ref, focused } = useFocusWithin<HTMLInputElement>()
34
34
  const [search, setSearch] = useSearch()
35
- const previous = usePreviousDistinct(search)
35
+ // const previous = usePreviousDistinct(search)
36
36
 
37
37
  // const [isEmptyForSomeTime, cancel] = useDebouncedValue(
38
38
  // focused ? search : 'rstrs',
@@ -60,7 +60,7 @@ export const LikeC4SearchInput = memo(() => {
60
60
  event.key.match(/^\p{L}$/u)
61
61
  )
62
62
  ) {
63
- moveFocusToSearchInput()
63
+ moveFocusToSearchInput(inputRef.current)
64
64
  }
65
65
  } catch (e) {
66
66
  console.warn(e)
@@ -84,14 +84,15 @@ export const LikeC4SearchInput = memo(() => {
84
84
  case search.startsWith('#'): {
85
85
  const searchTag = search.toLocaleLowerCase().slice(1)
86
86
  const alloptions = likec4model.tags.filter((tag) => tag.toLocaleLowerCase().includes(searchTag))
87
- isExactMatch = only(alloptions)?.toLocaleLowerCase() === searchTag
88
87
  if (alloptions.length === 0) {
88
+ isExactMatch = false
89
89
  options = [
90
90
  <ComboboxEmpty key="empty-tags">
91
91
  No tags found
92
92
  </ComboboxEmpty>,
93
93
  ]
94
94
  } else {
95
+ isExactMatch = likec4model.tags.some((tag) => tag.toLocaleLowerCase() === searchTag)
95
96
  options = alloptions.map((tag) => (
96
97
  <ComboboxOption value={`#${tag}`} key={tag}>
97
98
  <Text component="span" opacity={.5} mr={1} fz={'sm'}>#</Text>
@@ -107,15 +108,16 @@ export const LikeC4SearchInput = memo(() => {
107
108
  let alloptions = keys(likec4model.specification.elements)
108
109
  if (term) {
109
110
  alloptions = alloptions.filter((kind) => kind.toLocaleLowerCase().includes(term))
110
- isExactMatch = only(alloptions)?.toLocaleLowerCase() === term
111
111
  }
112
112
  if (alloptions.length === 0) {
113
+ isExactMatch = false
113
114
  options = [
114
115
  <ComboboxEmpty key="empty-kinds">
115
116
  No kinds found
116
117
  </ComboboxEmpty>,
117
118
  ]
118
119
  } else {
120
+ isExactMatch = alloptions.some((kind) => kind.toLocaleLowerCase() === term)
119
121
  options = alloptions.map((kind) => (
120
122
  <ComboboxOption value={`kind:${kind}`} key={kind}>
121
123
  <Text component="span" opacity={.5} mr={1} fz={'sm'}>kind:</Text>
@@ -136,7 +138,7 @@ export const LikeC4SearchInput = memo(() => {
136
138
  combobox.closeDropdown()
137
139
  // Let react to display filtered elements
138
140
  setTimeout(() => {
139
- focusToFirstFoundElement()
141
+ focusToFirstFoundElement(inputRef.current)
140
142
  }, 350)
141
143
  }
142
144
  }}
@@ -152,10 +154,11 @@ export const LikeC4SearchInput = memo(() => {
152
154
  >
153
155
  <ComboboxTarget>
154
156
  <Input
155
- ref={ref}
156
- id="likec4searchinput"
157
+ ref={useMergedRef(inputRef, ref)}
157
158
  placeholder="Search by title, description or start with # or kind:"
158
159
  autoFocus
160
+ data-autofocus
161
+ data-likec4-search-input
159
162
  tabIndex={0}
160
163
  classNames={{
161
164
  input: css.input,
@@ -169,7 +172,7 @@ export const LikeC4SearchInput = memo(() => {
169
172
  e.stopPropagation()
170
173
  const openedWithSearch = searchActorRef.getSnapshot().context.openedWithSearch
171
174
  if (search === '' || search === openedWithSearch) {
172
- close()
175
+ searchActorRef.send({ type: 'close' })
173
176
  } else {
174
177
  setSearch('')
175
178
  }
@@ -244,7 +247,7 @@ export const LikeC4SearchInput = memo(() => {
244
247
  ) {
245
248
  combobox.closeDropdown()
246
249
  stopAndPrevent(e)
247
- focusToFirstFoundElement()
250
+ focusToFirstFoundElement(inputRef.current)
248
251
  return
249
252
  }
250
253
  }} />
@@ -15,14 +15,14 @@ import {
15
15
  } from '@mantine/core'
16
16
  import { IconStack2, IconZoomScan } from '@tabler/icons-react'
17
17
  import * as m from 'motion/react-m'
18
- import { memo } from 'react'
18
+ import { memo, useRef } from 'react'
19
19
  import { first } from 'remeda'
20
20
  import { useCurrentViewId } from '../../hooks/useCurrentViewId'
21
21
  import { useDiagram } from '../../hooks/useDiagram'
22
22
  import { useLikeC4Model } from '../../likec4model/useLikeC4Model'
23
- import { useNormalizedSearch } from '../hooks'
23
+ import { useNormalizedSearch, useSearchActor } from '../hooks'
24
24
  import { buttonsva } from './_shared.css'
25
- import { centerY, moveFocusToSearchInput } from './utils'
25
+ import { centerY, moveFocusToSearchInput, queryAllFocusable } from './utils'
26
26
  import * as styles from './ViewsColumn.css'
27
27
 
28
28
  export const NothingFound = () => (
@@ -32,6 +32,7 @@ export const NothingFound = () => (
32
32
  )
33
33
 
34
34
  export const ViewsColumn = memo(() => {
35
+ const ref = useRef<HTMLDivElement>(null)
35
36
  let views = [...useLikeC4Model().views()]
36
37
  let search = useNormalizedSearch()
37
38
  if (search) {
@@ -49,15 +50,14 @@ export const ViewsColumn = memo(() => {
49
50
 
50
51
  return (
51
52
  <Stack
53
+ ref={ref}
52
54
  renderRoot={props => <m.div layout {...props} />}
53
55
  gap={8}
54
56
  data-likec4-search-views
55
57
  onKeyDown={(e) => {
56
58
  if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
57
59
  const maxY = (e.target as HTMLElement).getBoundingClientRect().y
58
- const elementButtons = [...document.querySelectorAll<HTMLButtonElement>(
59
- `[data-likec4-search-elements] .likec4-focusable`,
60
- )]
60
+ const elementButtons = queryAllFocusable(ref.current, 'elements', '.likec4-element-button')
61
61
  let elementButton = elementButtons.length > 1
62
62
  ? elementButtons.find((el, i, all) => centerY(el) > maxY || i === all.length - 1)
63
63
  : null
@@ -78,7 +78,7 @@ export const ViewsColumn = memo(() => {
78
78
  tabIndex={-1}
79
79
  onFocus={e => {
80
80
  e.stopPropagation()
81
- moveFocusToSearchInput()
81
+ moveFocusToSearchInput(ref.current)
82
82
  }} />
83
83
  </VisuallyHidden>
84
84
  )}
@@ -107,10 +107,18 @@ export function ViewButton(
107
107
  & UnstyledButtonProps
108
108
  & ElementProps<'button'>,
109
109
  ) {
110
+ const searchActorRef = useSearchActor()
110
111
  const diagram = useDiagram()
111
- // const navigateTo = useCloseSearchAndNavigateTo()
112
112
  const currentViewId = useCurrentViewId()
113
113
  const isCurrentView = view.id === currentViewId
114
+
115
+ const navigate = () => {
116
+ searchActorRef.send({ type: 'close' })
117
+ setTimeout(() => {
118
+ diagram.navigateTo(view.id)
119
+ }, 100)
120
+ }
121
+
114
122
  return (
115
123
  <UnstyledButton
116
124
  {...props}
@@ -119,7 +127,7 @@ export function ViewButton(
119
127
  {...isCurrentView && { 'data-disabled': true }}
120
128
  onClick={(e) => {
121
129
  e.stopPropagation()
122
- diagram.navigateTo(view.id)
130
+ navigate()
123
131
  }}
124
132
  onKeyDown={createScopedKeydownHandler({
125
133
  siblingSelector: '[data-likec4-view]',
@@ -130,7 +138,7 @@ export function ViewButton(
130
138
  onKeyDown: (e) => {
131
139
  if (e.nativeEvent.code === 'Space') {
132
140
  e.stopPropagation()
133
- diagram.navigateTo(view.id)
141
+ navigate()
134
142
  }
135
143
  },
136
144
  })}>
@@ -1,3 +1,4 @@
1
+ import { isFunction } from 'remeda'
1
2
  import { focusable } from './_shared.css'
2
3
 
3
4
  export function stopAndPrevent(e: React.KeyboardEvent | KeyboardEvent) {
@@ -12,8 +13,17 @@ export function centerY(element: HTMLElement) {
12
13
  return y
13
14
  }
14
15
 
15
- export function moveFocusToSearchInput() {
16
- const input = document.getElementById('likec4searchinput') as HTMLInputElement | null
16
+ export function moveFocusToSearchInput(from: HTMLElement | null | undefined) {
17
+ if (!from) {
18
+ console.error('moveFocusToSearchInput: from is null or undefined')
19
+ return
20
+ }
21
+ const root = from.getRootNode() as Document | ShadowRoot
22
+ if (!isFunction(root.querySelector)) {
23
+ console.error('moveFocusToSearchInput: root.querySelector is not a function')
24
+ return
25
+ }
26
+ let input = root.querySelector('[data-likec4-search-input]') as HTMLInputElement | null
17
27
  if (input) {
18
28
  const length = input.value.length
19
29
  input.focus()
@@ -21,7 +31,34 @@ export function moveFocusToSearchInput() {
21
31
  }
22
32
  }
23
33
 
24
- export function focusToFirstFoundElement() {
25
- let firstFoundElement = document.querySelector<HTMLButtonElement>(`[data-likec4-search] .${focusable}`)
34
+ export function focusToFirstFoundElement(from: HTMLElement | null | undefined) {
35
+ if (!from) {
36
+ console.error('focusToFirstFoundElement: from is null or undefined')
37
+ return
38
+ }
39
+ const root = from.getRootNode() as Document | ShadowRoot
40
+ if (!isFunction(root.querySelector)) {
41
+ console.error('focusToFirstFoundElement: root.querySelector is not a function')
42
+ return
43
+ }
44
+ let firstFoundElement = root.querySelector<HTMLButtonElement>(`[data-likec4-search] .${focusable}`)
26
45
  firstFoundElement?.focus()
27
46
  }
47
+
48
+ export function queryAllFocusable(
49
+ from: HTMLElement | null | undefined,
50
+ where: 'elements' | 'views',
51
+ selector: string = `.${focusable}`,
52
+ ): HTMLButtonElement[] {
53
+ if (!from) {
54
+ console.error('queryAllFocusable: from is null or undefined')
55
+ return []
56
+ }
57
+ const root = from.getRootNode() as Document | ShadowRoot
58
+ if (!isFunction(root.querySelectorAll)) {
59
+ console.error('queryAllFocusable: root.querySelectorAll is not a function')
60
+ return []
61
+ }
62
+ const elements = root.querySelectorAll<HTMLButtonElement>(`[data-likec4-search-${where}] ${selector}`)
63
+ return [...elements]
64
+ }
@@ -3,14 +3,11 @@ import { useSelector } from '@xstate/react'
3
3
  import { useCallback, useDeferredValue } from 'react'
4
4
  import type { SearchActorRef, SearchActorSnapshot } from './searchActor'
5
5
 
6
- export const [SearchActorContext, useSearchActor] = createSafeContext<{
7
- searchActorRef: SearchActorRef
8
- close: (cb?: () => void) => void
9
- }>('SearchActorContext')
6
+ export const [SearchActorContext, useSearchActor] = createSafeContext<SearchActorRef>('SearchActorContext')
10
7
 
11
8
  const selectSearchValue = (s: SearchActorSnapshot) => s.context.searchValue
12
9
  export function useSearch(): [string, (search: string) => void] {
13
- const { searchActorRef } = useSearchActor()
10
+ const searchActorRef = useSearchActor()
14
11
  const searchValue = useSelector(searchActorRef, selectSearchValue)
15
12
  const updateSearch = useCallback((search: string) => {
16
13
  searchActorRef.send({ type: 'change.search', search })
@@ -23,12 +20,12 @@ const selectNormalizedSearchValue = (s: SearchActorSnapshot) => {
23
20
  return v.length > 1 ? v : ''
24
21
  }
25
22
  export function useNormalizedSearch() {
26
- const { searchActorRef } = useSearchActor()
23
+ const searchActorRef = useSearchActor()
27
24
  return useDeferredValue(useSelector(searchActorRef, selectNormalizedSearchValue))
28
25
  }
29
26
 
30
27
  export function useUpdateSearch() {
31
- const { searchActorRef } = useSearchActor()
28
+ const searchActorRef = useSearchActor()
32
29
  return useCallback((search: string) => {
33
30
  searchActorRef.send({ type: 'change.search', search })
34
31
  }, [searchActorRef])
@@ -36,6 +33,6 @@ export function useUpdateSearch() {
36
33
 
37
34
  const selectPickViewFor = (s: SearchActorSnapshot) => s.context.pickViewFor
38
35
  export function usePickViewFor() {
39
- const { searchActorRef } = useSearchActor()
36
+ const searchActorRef = useSearchActor()
40
37
  return useSelector(searchActorRef, selectPickViewFor)
41
38
  }
@@ -1,4 +1,5 @@
1
1
  import type { DiagramView, WhereOperator } from '@likec4/core/types'
2
+ import { useLogger } from '@mantine/hooks'
2
3
  import { useActorRef, useSelector } from '@xstate/react'
3
4
  import { useStoreApi } from '@xyflow/react'
4
5
  import { shallowEqual } from 'fast-equals'
@@ -41,7 +42,7 @@ export function DiagramActorProvider({
41
42
  // Slightly defer callback for better responsiveness
42
43
  setTimeout(() => {
43
44
  handlersRef.current.onNavigateTo?.(viewId)
44
- }, 30)
45
+ }, 40)
45
46
  }),
46
47
 
47
48
  'trigger:OnChange': ((_, params) => {
@@ -1023,12 +1023,14 @@ const _diagramMachine = setup({
1023
1023
  'closeAllOverlays',
1024
1024
  'closeSearch',
1025
1025
  'stopSyncLayout',
1026
- {
1027
- type: 'trigger:NavigateTo',
1028
- params: ({ context }) => ({
1029
- viewId: nonNullable(context.lastOnNavigate, 'Invalid state, lastOnNavigate is null').toView,
1030
- }),
1031
- },
1026
+ enqueueActions(({ enqueue, context }) => {
1027
+ enqueue({
1028
+ type: 'trigger:NavigateTo',
1029
+ params: {
1030
+ viewId: nonNullable(context.lastOnNavigate, 'Invalid state, lastOnNavigate is null').toView,
1031
+ },
1032
+ })
1033
+ }),
1032
1034
  ],
1033
1035
  on: {
1034
1036
  'update.view': {