PluginProbe
The Innovative Form Builder – IvyForms / 0.8.1
The Innovative Form Builder – IvyForms v0.8.1
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 / useIntegrations.ts

useIntegrations.ts in The Innovative Form Builder – IvyForms 0.8.1, at frontend/src/composables/useIntegrations.ts

157 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { computed, ref } from 'vue'
2 import { getIntegrations, type Integration, type integrationType } from '@/constants/integrations'
3 import { useProFeatures } from '@/composables/useProFeatures'
4 import { useProFeatureUpgrade } from '@/composables/useProFeatureUpgrade'
5 import { useSettingsStore } from '@/stores/useSettingsStore'
6
7 /**
8 * Integrations Composable
9 *
10 * Manages integration status and dynamically updates types based on:
11 * - Pro installation status
12 * - Current license plan
13 * - Connection/activation state
14 */
15
16 interface IntegrationState {
17 [key: string]: {
18 enabled: boolean
19 connected: boolean
20 }
21 }
22
23 export function useIntegrations() {
24 const pro = useProFeatures()
25 const settingsStore = useSettingsStore()
26 const { isProInstalled: checkProInstalled, isProLicenseActive: checkProLicenseActive } =
27 useProFeatureUpgrade()
28 const integrationState = ref<IntegrationState>({})
29
30 /**
31 * Load integration states from settings store
32 */
33 const loadIntegrationStates = async () => {
34 // Load from the settings store's integrationsSettings
35 const storeSettings = settingsStore.integrationsSettings || {}
36
37 // Transform to match our IntegrationState interface
38 const transformed: IntegrationState = {}
39 for (const [key, value] of Object.entries(storeSettings)) {
40 if (value && typeof value === 'object') {
41 transformed[key] = {
42 enabled: (value as { enabled?: boolean }).enabled || false,
43 connected: (value as { connected?: boolean }).connected || false,
44 }
45 }
46 }
47
48 integrationState.value = transformed
49 }
50
51 /**
52 * Check if Pro is installed and meets minimum plan requirement
53 * Also checks if license is active
54 */
55 const meetsRequirement = (requiredPlan?: string): boolean => {
56 if (!requiredPlan) return true
57
58 // First check: Is Pro installed and license active?
59 if (!checkProInstalled() || !checkProLicenseActive()) {
60 return false
61 }
62
63 const currentPlan = pro.plan.value
64 const isProInstalledCheck = currentPlan !== 'lite' && currentPlan !== 'error'
65
66 if (!isProInstalledCheck) return false
67
68 const planHierarchy = ['essentials', 'growth', 'agency']
69 const currentIndex = planHierarchy.indexOf(currentPlan)
70 const requiredIndex = planHierarchy.indexOf(requiredPlan)
71
72 return currentIndex >= requiredIndex && currentIndex !== -1
73 }
74
75 /**
76 * Determine integration type dynamically
77 */
78 const getIntegrationType = (integration: Integration): integrationType => {
79 const state = integrationState.value[integration.value] || { enabled: false, connected: false }
80
81 // Check if this is a Pro integration (plan is not 'lite')
82 const isProIntegration = integration.searchCategory !== 'lite'
83
84 if (isProIntegration) {
85 if (!meetsRequirement(integration.requiredPlan)) {
86 // If Pro is NOT installed at all, show 'upgrade' type (with Pro banner)
87 // If Pro IS installed but license not active, show 'proDisabled' type (no banner)
88 const proInstalled = checkProInstalled()
89 return proInstalled ? 'proDisabled' : 'upgrade'
90 }
91
92 // Pro is installed and plan is sufficient
93 // If not enabled, return 'proDisabled' to show "Learn More" button
94 if (!state.enabled) {
95 return 'proDisabled'
96 }
97
98 // If enabled but not connected, return 'proDisabled' to show "Go to Settings"
99 if (!state.connected) {
100 return 'proDisabled'
101 }
102
103 return 'proActive'
104 }
105
106 // Lite integrations
107 // PRIORITY 1: Check if plugin is installed (connected)
108 // If installed, ALWAYS show "Learn More" regardless of toggle state
109 if (state.connected) {
110 return 'active'
111 }
112
113 // PRIORITY 2: Plugin is NOT installed
114 return 'disabled'
115 }
116
117 /**
118 * Get all integrations with dynamic types
119 * Now async - loads from backend registry
120 */
121 const integrations = ref<Integration[]>([])
122 const integrationsLoaded = ref(false)
123
124 const loadIntegrations = async () => {
125 if (integrationsLoaded.value) {
126 return integrations.value
127 }
128
129 // Call getIntegrations() to get filtered list from backend at runtime
130 const loaded = await getIntegrations()
131 integrations.value = loaded.map((integration) => ({
132 ...integration,
133 type: getIntegrationType(integration),
134 }))
135
136 integrationsLoaded.value = true
137 return integrations.value
138 }
139
140 /**
141 * Update integration state
142 */
143 const updateIntegrationState = (name: string, enabled: boolean, connected = false) => {
144 integrationState.value[name] = { enabled, connected }
145 }
146
147 return {
148 integrations: computed(() => integrations.value),
149 integrationsLoaded: computed(() => integrationsLoaded.value),
150 integrationState,
151 loadIntegrations,
152 loadIntegrationStates,
153 updateIntegrationState,
154 getIntegrationType,
155 }
156 }
157