PluginProbe
The Innovative Form Builder – IvyForms / 0.9.1
The Innovative Form Builder – IvyForms v0.9.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 / IvyFormAPI.ts

IvyFormAPI.ts in The Innovative Form Builder – IvyForms 0.9.1, at frontend/src/composables/IvyFormAPI.ts

142 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import * as Vue from 'vue'
2 import { markRaw, ref } from 'vue'
3 import type { Component } from 'vue'
4 import type { FieldOptionConfig } from '@/types/field-options'
5
6 export type ComponentType = Component
7
8 export interface IvyFormAPIHooks {
9 actions: Record<string, Array<(...args: unknown[]) => void>>
10 filters: Record<string, Array<(...args: unknown[]) => unknown>>
11 fieldInit?: Array<(field: unknown, context: unknown) => void>
12 beforeSaveFields?: Array<(fields: unknown[]) => unknown[]>
13 getTemplatePreviewField?: Array<(fieldType: string) => unknown | null>
14
15 addAction: (hook: string, cb: (...args: unknown[]) => void) => void
16 doAction: (hook: string, ...args: unknown[]) => void
17
18 addFilter: (hook: string, cb: (...args: unknown[]) => unknown) => void
19 applyFilters: <T = unknown>(hook: string, value: T, ...args: unknown[]) => T
20
21 registerFieldInit: (callback: (field: unknown, context: unknown) => void) => void
22 registerBeforeSaveFields: (callback: (fields: unknown[]) => unknown[]) => void
23
24 triggerUpdate: () => void
25 updateCounter: { value: number }
26 }
27
28 export interface IvyFormAPIFields {
29 admin: Record<string, ComponentType>
30 public: Record<string, ComponentType>
31 registerAdmin: (name: string, component: ComponentType) => void
32 registerPublic: (name: string, component: ComponentType) => void
33 }
34
35 export interface IvyFormAPIFieldOptions {
36 registry: Record<string, FieldOptionConfig>
37 register: (config: FieldOptionConfig) => void
38 unregister: (id: string) => void
39 getForFieldType: (fieldType: string, tab?: 'general' | 'advanced') => FieldOptionConfig[]
40 }
41
42 export interface IvyFormAPI {
43 fields: IvyFormAPIFields
44 hooks: IvyFormAPIHooks
45 fieldOptions: IvyFormAPIFieldOptions
46 }
47
48 const hooksUpdateCounter = ref(0)
49 const fieldOptionsRegistry: Record<string, FieldOptionConfig> = {}
50
51 const api: IvyFormAPI = {
52 fields: {
53 admin: {},
54 public: {},
55 registerAdmin(name, component) {
56 this.admin[name] = markRaw(component)
57 },
58 registerPublic(name, component) {
59 this.public[name] = markRaw(component)
60 },
61 },
62
63 hooks: {
64 actions: {},
65 filters: {},
66 fieldInit: [],
67 beforeSaveFields: [],
68 updateCounter: hooksUpdateCounter,
69 addAction(hook, cb) {
70 if (!this.actions[hook]) this.actions[hook] = []
71 this.actions[hook].push(cb)
72 },
73 doAction(hook, ...args) {
74 if (this.actions[hook]) this.actions[hook].forEach((cb) => cb(...args))
75 },
76 addFilter(hook, cb) {
77 if (!this.filters[hook]) this.filters[hook] = []
78 this.filters[hook].push(cb)
79 this.triggerUpdate()
80 },
81 applyFilters(hook: string, value: unknown, ...args: unknown[]) {
82 if (!this.filters[hook]) return value
83 return this.filters[hook].reduce(
84 (v: unknown, cb: (...args: unknown[]) => unknown) => cb(v, ...args),
85 value,
86 )
87 },
88 registerFieldInit(callback) {
89 if (!this.fieldInit) this.fieldInit = []
90 this.fieldInit.push(callback)
91 },
92 registerBeforeSaveFields(callback) {
93 if (!this.beforeSaveFields) this.beforeSaveFields = []
94 this.beforeSaveFields.push(callback)
95 },
96 triggerUpdate() {
97 hooksUpdateCounter.value++
98 },
99 },
100
101 fieldOptions: {
102 registry: fieldOptionsRegistry,
103 register(config: FieldOptionConfig) {
104 fieldOptionsRegistry[config.id] = markRaw(config) as FieldOptionConfig
105 api.hooks.triggerUpdate()
106 },
107 unregister(id: string) {
108 delete fieldOptionsRegistry[id]
109 api.hooks.triggerUpdate()
110 },
111 getForFieldType(fieldType: string, tab?: 'general' | 'advanced'): FieldOptionConfig[] {
112 return Object.values(fieldOptionsRegistry)
113 .filter((config) => {
114 // Filter by field type
115 if (!config.fieldTypes.includes(fieldType)) return false
116 // Filter by tab if specified
117 if (tab && config.tab && config.tab !== tab) return false
118 return true
119 })
120 .sort((a, b) => a.order - b.order)
121 },
122 },
123 }
124
125 // Ready event helpers
126 export const IVY_READY_EVENT = 'ivyforms:ready' as const
127 export function dispatchIvyReady(detail?: Record<string, unknown>) {
128 const evt = new CustomEvent(IVY_READY_EVENT, { detail })
129 window.dispatchEvent(evt)
130 document.dispatchEvent(evt)
131 }
132
133 export function installIvyGlobals() {
134 const w = window
135 if (!w.Vue) w.Vue = Vue
136 w.IvyFormsApi = api
137
138 return api
139 }
140
141 export default api
142