PluginProbe
The Innovative Form Builder – IvyForms / 0.5
The Innovative Form Builder – IvyForms v0.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
ivyforms / frontend / src / composables / IvyFormAPI.ts

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

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