PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
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
← All changes | frontend/src/assets/js/admin/admin.ts +93 -18 0.6 → 1.5 View file →
@@ -3,9 +3,11 @@
3 3 import * as Vue from 'vue'
4 4 import { createApp } from 'vue'
5 5 import { createPinia } from 'pinia'
6 6 import App from '../../../views/admin/App.vue'
7 +import EntryPage from '@/views/admin/entries/entry-page/EntryPage.vue'
7 8 import router from '@/router'
9 +import '@/assets/scss/main.scss'
8 10 import 'element-plus/dist/index.css'
9 11 import { useLabelsStore } from '@/stores/labels'
10 12 import { useLabels } from '@/composables/useLabels'
11 13 import api, { dispatchIvyReady, installIvyGlobals } from '@/composables/IvyFormAPI'
@@ -10,10 +12,14 @@
10 12 import { useLabels } from '@/composables/useLabels'
11 13 import api, { dispatchIvyReady, installIvyGlobals } from '@/composables/IvyFormAPI'
12 14 import { useProFeatures } from '@/composables/useProFeatures'
13 15 import { useFormBuilder } from '@/stores/useFormBuilder'
16 +import { useEntry } from '@/stores/useEntry'
17 +import { useNavigation } from '@/composables/useNavigation'
14 18 import { registerLiteComponents } from '@/composables/registerLiteComponents'
15 19 import { registerLiteFieldOptions } from '@/views/admin/form-builder/form-builder-page/form-builder/panel/tabs/field-options/registerLiteFieldOptions'
20 +import { registerSquareIntegration } from '@/integrations/registerSquare'
21 +import { registerLiteStyleSectionPromos } from '@/views/admin/form-builder/form-builder-page/form-builder/panel/tabs/style-controls/registerLiteStyleSectionPromos'
16 22 import * as LiteTypes from '@/types/index'
17 23 import type { IvyProFeatures } from '@/types/global'
18 24 import { useWcagColors } from '@/composables/useWcagColors'
19 25 import { useSettingsStore } from '@/stores/useSettingsStore'
@@ -18,8 +24,27 @@
18 24 import { useWcagColors } from '@/composables/useWcagColors'
19 25 import { useSettingsStore } from '@/stores/useSettingsStore'
20 26 import IvyMessage from '@/views/_components/message/ivyMessage'
21 27 import { useApiClient } from '@/composables/useApiClient'
28 +import { useActionEntityStore } from '@/stores/actionEntityStore'
29 +import { useUnsavedChangesStore } from '@/stores/useUnsavedChangesStore'
30 +import { useProUpgradeDialogStore } from '@/stores/proUpgradeDialogStore'
31 +import { useGlobalState } from '@/stores/useGlobalState'
32 +import { denormalizeFieldsForApi } from '@/utils/fieldsNormalization'
33 +import { countryList } from '@/constants/countries'
34 +import { isSecurityField } from '@/constants/securityFields'
35 +import { useProFeatureUpgrade } from '@/composables/useProFeatureUpgrade'
36 +import { useConfirmationMultiSetting } from '@/stores/useConfirmationMultiSetting'
37 +import { useGoogleSheetsFormIntegrations } from '@/integrations/google-sheets/composables/useGoogleSheetsFormIntegrations'
38 +import {
39 + registerFormBuilderExtension,
40 + getFormBuilderExtensions,
41 +} from '@/extensions/formBuilderExtensions'
42 +import { useAllEntries } from '@/stores/useAllEntries'
43 +import { getPreviewFieldComponent } from '@/composables/useFieldPreviewComponents'
44 +import { normalizeFieldsForBuilder } from '@/utils/fieldsNormalization'
45 +import { registerLitePublicFieldComponents } from '@/entries/publicFieldComponentRegistry'
46 +import { registerGoogleSheetsAdmin } from '@/integrations/google-sheets/registerGoogleSheetsAdmin'
22 47
23 48 // Note: Window interface extensions are now defined in src/types/global.d.ts
24 49 // No need to duplicate declarations here
25 50
@@ -27,8 +52,12 @@
27 52 const pinia = createPinia()
28 53 app.use(pinia)
29 54 app.use(router)
30 55
56 +// Shared settings store: must exist before mount so Pro views (e.g. Zapier) can read the same
57 +// `settings/all` payload as the rest of admin via `window.IvyForms.settingsStore`.
58 +const settingsStore = useSettingsStore()
59 +
31 60 // Initialize the labels store with WordPress data
32 61 const labelsStore = useLabelsStore()
33 62 labelsStore.initialize()
34 63
@@ -41,8 +70,9 @@
41 70 installIvyGlobals()
42 71 const w = window
43 72 const { getLabel } = useLabels()
44 73 const formBuilder = useFormBuilder()
74 + const globalState = useGlobalState()
45 75
46 76 // Proxy to resolve labels dynamically via getLabel
47 77 const labelsProxy = new Proxy(
48 78 {},
@@ -58,29 +88,22 @@
58 88 )
59 89
60 90 w.IvyForms = w.IvyForms || { api, hooks: api.hooks, fields: api.fields }
61 91 w.IvyForms.api = api
62 - // Expose hooks & fields for external (Pro / add-ons) integration.
63 - // These were previously commented out which prevented Pro from registering filters via IvyForms.hooks.*
64 - // Keep backward compatibility by only setting if not already provided.
65 - if (!w.IvyForms.hooks) {
66 - w.IvyForms.hooks = api.hooks
67 - }
92 + // Always sync to canonical api.hooks so third-party registrations land on the same registry.
93 + w.IvyForms.hooks = api.hooks
68 94
69 - // Add triggerUpdate method for Pro plugins to notify when they add hooks
70 - if (!w.IvyForms.hooks.triggerUpdate) {
71 - w.IvyForms.hooks.triggerUpdate = () => {
72 - // This is a no-op by default, but components can override it
73 - // to trigger re-computation when Pro plugins register
74 - }
95 + // Ensure hook registration triggers reactive updates in Lite components
96 + if (w.IvyForms.hooks === api.hooks && api.hooks.triggerUpdate) {
97 + w.IvyForms.hooks.triggerUpdate = api.hooks.triggerUpdate.bind(api.hooks)
75 98 }
76 99
77 - if (!w.IvyForms.fields) {
78 - w.IvyForms.fields = api.fields
79 - }
100 + w.IvyForms.fields = api.fields
80 101 // Expose label helpers for Pro plugin and other extenders
81 102 w.IvyForms.getLabel = getLabel
82 103 w.IvyForms.labels = labelsProxy
104 + // Set WordPress admin URL
105 + w.IvyForms.adminUrl = w.wpIvyApiSettings?.root?.replace(/\/wp-json\/?$/, '') + '/wp-admin/'
83 106 // Expose Vue for pro plugins with guaranteed compatibility
84 107 w.IvyForms.Vue = Vue
85 108 //w.Vue = w.Vue || Vue // Global fallback for compatibility with other plugins
86 109 // Expose IvyMessage utility for Pro plugin
@@ -86,12 +109,44 @@
86 109 // Expose IvyMessage utility for Pro plugin
87 110 w.IvyForms.IvyMessage = IvyMessage
88 111 // Expose useApiClient for Pro plugin (call it once to prevent tree-shaking)
89 112 w.IvyForms.useApiClient = useApiClient
113 + // Shared Google Sheets form-builder CRUD for Lite single + Pro multi shells
114 + w.IvyForms.useGoogleSheetsFormIntegrations = useGoogleSheetsFormIntegrations
115 + // Expose stores for Pro plugin to use dialogs and entity actions
116 + w.IvyForms.useActionEntityStore = useActionEntityStore
117 + // Expose the actual store instance (not the function) so Pro uses the same instance
118 + w.IvyForms.unsavedChangesStore = useUnsavedChangesStore()
119 + w.IvyForms.useProUpgradeDialogStore = useProUpgradeDialogStore
90 120 // Expose the form builder store so external components can read/write fields
91 121 w.IvyForms.formBuilder = formBuilder
122 + w.IvyForms.registerFormBuilderExtension = registerFormBuilderExtension
123 + w.IvyForms.getFormBuilderExtensions = getFormBuilderExtensions
124 + w.IvyForms.useEntry = useEntry
125 + // Expose global state for Pro plugins to set page title and active page
126 + w.IvyForms.globalState = globalState
92 127 // Expose shared types for Pro plugin and other extenders
93 128 w.IvyForms.types = LiteTypes
129 + // Expose shared utility helpers for Pro plugin and other extenders
130 + const { showUpgradeDialog } = useProFeatureUpgrade()
131 + w.IvyForms.helpers = {
132 + isSecurityField,
133 + showUpgradeDialog,
134 + getPreviewFieldComponent: getPreviewFieldComponent as (fieldType: string) => unknown,
135 + normalizeFieldsForBuilder: normalizeFieldsForBuilder as (fields: unknown[]) => unknown[],
136 + denormalizeFieldsForApi,
137 + countryList,
138 + registerLitePublicFieldComponents,
139 + }
140 + w.IvyForms.confirmationMulti = {
141 + refreshTable: async (formId: number) => {
142 + await useConfirmationMultiSetting().searchConfirmations({ formId })
143 + },
144 + }
145 +
146 + // Expose entry stores so Pro can read/refresh entries (add-entry is a Pro feature).
147 + w.IvyForms.useAllEntries = useAllEntries
148 + w.IvyForms.useEntry = useEntry
94 149 // Create a callable components registry:
95 150 // - Use as function: w.IvyForms.components('MyComp', Comp)
96 151 // - Or as object map: w.IvyForms.components.MyComp
97 152 // - Or helper alias: w.IvyForms.registerComponent('MyComp', Comp)
@@ -104,8 +159,12 @@
104 159 app.component(name, component)
105 160 ;(componentsRegistry as Record<string, Component>)[name] = component
106 161 return component
107 162 }
163 + // If only name is provided, return the component
164 + if (name) {
165 + return (componentsRegistry as Record<string, Component>)[name]
166 + }
108 167 return componentsRegistry
109 168 }) as ComponentRegistry
110 169
111 170 // Register all Lite components for Pro plugin access
@@ -113,9 +172,14 @@
113 172
114 173 w.IvyForms.components = componentsRegistry
115 174 w.IvyForms.registerComponent = (name: string, component: Component) =>
116 175 componentsRegistry(name, component)
176 + w.IvyForms.registerComponent('EntryPage', EntryPage)
117 177
178 + registerSquareIntegration((name, component) => {
179 + componentsRegistry(name, component)
180 + })
181 +
118 182 // Expose router for Pro plugins to add routes dynamically
119 183 w.IvyForms._router = router
120 184
121 185 // Initialize pro features bridge if not already provided by Pro plugin
@@ -201,17 +265,28 @@
201 265 return false
202 266 }
203 267 }
204 268 }
269 +
270 + // Pinia settings store (same instance as Lite admin) — Pro reads `integrations.*` here.
271 + w.IvyForms.settingsStore = settingsStore
205 272 })()
206 273
274 +// Register Google Sheets after hooks + router are exposed
275 +registerGoogleSheetsAdmin()
276 +
207 277 // Register Lite field options
208 278 registerLiteFieldOptions()
209 279
280 +// Register Lite advanced style section promos (replaced by Pro via hook when available)
281 +registerLiteStyleSectionPromos()
282 +
283 +// Bind navigation helper under app context so useRouter() resolves correctly.
284 +app.runWithContext(() => {
285 + window.IvyForms.navigateToAdminPage = useNavigation().navigateToAdminPage
286 +})
287 +
210 288 app.mount('#ivyforms-app')
211 -
212 -// Initialize settings store and load settings before starting WCAG watcher
213 -const settingsStore = useSettingsStore()
214 289
215 290 // Load settings from backend first, then initialize WCAG colors
216 291 settingsStore
217 292 .loadAllSettings()