PluginProbe
The Innovative Form Builder – IvyForms / 0.9
The Innovative Form Builder – IvyForms v0.9
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.9, at frontend/src/composables/useMenuNavigation.ts

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