PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / composables / useMenuNavigation.ts

useMenuNavigation.ts in The Innovative Form Builder – IvyForms 0.8, at frontend/src/composables/useMenuNavigation.ts

177 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useRouter } from 'vue-router'
2 import { useUnsavedChangesStore } from '@/stores/useUnsavedChangesStore'
3 import { useActionEntityStore } from '@/stores/actionEntityStore.ts'
4 import { useFormBuilder } from '@/stores/useFormBuilder.ts'
5 import { useConfirmationSettingBuilder } from '@/stores/useConfirmationSettingBuilder.ts'
6 import { useNotificationSettingBuilder } from '@/stores/useNotificationSettingBuilder.ts'
7 import {
8 IVYFORMS_EDIT_NOTIFICATIONS,
9 IVYFORMS_NEW_NOTIFICATIONS,
10 IVYFORMS_SETTINGS,
11 IVYFORMS_ADD_FORM,
12 IVYFORMS_EDIT_FORM,
13 } from '@/constants/pages.ts'
14
15 export function useMenuNavigation() {
16 const router = useRouter()
17 const unsavedChangesStore = useUnsavedChangesStore()
18 const actionEntityStore = useActionEntityStore()
19 const formBuilderStore = useFormBuilder()
20 const confirmationStore = useConfirmationSettingBuilder()
21 const notificationStore = useNotificationSettingBuilder()
22
23 // Helper to get all unsaved changes states at once
24 function getUnsavedChangesStates() {
25 return {
26 hasFormBuilderUnsaved: unsavedChangesStore.hasUnsavedChanges('formBuilder', () =>
27 formBuilderStore.getCurrentState(),
28 ).value,
29 hasConfirmationUnsaved: unsavedChangesStore.hasUnsavedChanges('confirmationBuilder', () =>
30 confirmationStore.getCurrentState(),
31 ).value,
32 hasNotificationUnsaved: unsavedChangesStore.hasUnsavedChanges('notificationBuilder', () =>
33 notificationStore.getCurrentState(),
34 ).value,
35 }
36 }
37
38 async function getConfirmationIdForForm(formId) {
39 // Try to get confirmationId from store
40 if (confirmationStore.id && confirmationStore.formId == formId) {
41 return confirmationStore.id
42 }
43 // Try to fetch confirmation for this form
44 await confirmationStore.fetchAllConfirmations(formId)
45 if (confirmationStore.id) {
46 return confirmationStore.id
47 }
48 // If still not found, create one
49 confirmationStore.formId = formId
50 await confirmationStore.createConfirmation()
51 return confirmationStore.id
52 }
53
54 async function getMenuRoute(item, fallbackRouteName = null) {
55 const { hasFormBuilderUnsaved, hasConfirmationUnsaved, hasNotificationUnsaved } =
56 getUnsavedChangesStates()
57 if (hasFormBuilderUnsaved || hasConfirmationUnsaved || hasNotificationUnsaved) {
58 return item.routeName
59 ? { name: fallbackRouteName, params: { id: formBuilderStore.formId } }
60 : undefined
61 }
62
63 if (item.routeName === 'form-confirmation') {
64 const formId = formBuilderStore.formId
65 const confirmationId = await getConfirmationIdForForm(formId)
66 return { name: item.routeName, params: { formId, confirmationId } }
67 }
68 // Notifications table only needs formId
69 if (item.routeName === 'form-notifications') {
70 return { name: item.routeName, params: { formId: formBuilderStore.formId } }
71 }
72
73 // Default: use id for other routes
74 return item.routeName
75 ? { name: item.routeName, params: { id: formBuilderStore.formId } }
76 : undefined
77 }
78
79 async function onMenuClick(item, isActive) {
80 if (isActive(item.routeName, item.index)) return
81 const { hasFormBuilderUnsaved, hasConfirmationUnsaved, hasNotificationUnsaved } =
82 getUnsavedChangesStates()
83 const doNavigate = async () => {
84 // Handle items with sub-items (like Integrations)
85 if (item.subItems && item.subItems.length > 0 && item.autoNavigateToFirst) {
86 const firstSubItem = item.subItems[0]
87 const path = `/manage/${formBuilderStore.formId}/settings/${item.index}${firstSubItem.index}`
88 await router.push(path)
89 return
90 }
91
92 if (item.routeName === 'form-confirmation') {
93 const formId = formBuilderStore.formId
94 const confirmationId = await getConfirmationIdForForm(formId)
95 await router.push({ name: item.routeName, params: { formId, confirmationId } })
96 return
97 }
98 if (item.routeName === 'form-notifications') {
99 await router.push({ name: item.routeName, params: { formId: formBuilderStore.formId } })
100 return
101 }
102 // TODO integrations route
103 if (item.routeName === 'form-integrations') {
104 await router.push({
105 name: item.routeName,
106 params: { formId: formBuilderStore.formId, integration: 'wpdatatables' },
107 })
108 return
109 }
110 // Default: use id for other routes
111 await router.push({ name: item.routeName, params: { formId: formBuilderStore.formId } })
112 }
113 if (hasFormBuilderUnsaved || hasConfirmationUnsaved || hasNotificationUnsaved) {
114 actionEntityStore.showUnsavedChangesDialog(async () => {
115 if (hasFormBuilderUnsaved) {
116 unsavedChangesStore.resetUnsavedChanges('formBuilder', () =>
117 formBuilderStore.getCurrentState(),
118 )
119 }
120 if (hasConfirmationUnsaved) {
121 unsavedChangesStore.resetUnsavedChanges('confirmationBuilder', () =>
122 confirmationStore.getCurrentState(),
123 )
124 }
125 if (hasNotificationUnsaved) {
126 unsavedChangesStore.resetUnsavedChanges('notificationBuilder', () =>
127 notificationStore.getCurrentState(),
128 )
129 }
130 await doNavigate()
131 })
132 } else {
133 await doNavigate()
134 }
135 }
136
137 function isActive(routeName, index) {
138 const matched = router.currentRoute.value.matched
139 const currentPath = router.currentRoute.value.path
140
141 // Check if we're on the "build" tab (either add or edit form)
142 if (index === 'build') {
143 return matched.some(({ name }) => name === IVYFORMS_ADD_FORM || name === IVYFORMS_EDIT_FORM)
144 }
145
146 // Check if we're on an integrations sub-route (must include the full path)
147 if (index === 'integrations') {
148 return currentPath.includes('/settings/integrations/')
149 }
150
151 if (routeName && matched.some(({ name }) => name === routeName)) {
152 return true
153 }
154 if (matched.length > 1 && index === 'settings') {
155 const parent = matched[matched.length - 2]
156 if (parent && parent.name === IVYFORMS_SETTINGS) {
157 return true
158 }
159 }
160 if (
161 index === 'notifications' &&
162 matched.some(
163 ({ name }) => name === IVYFORMS_NEW_NOTIFICATIONS || name === IVYFORMS_EDIT_NOTIFICATIONS,
164 )
165 ) {
166 return true
167 }
168 return false
169 }
170
171 return {
172 getMenuRoute,
173 onMenuClick,
174 isActive,
175 }
176 }
177