@bagelink/vue 1.0.38 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DataTable/DataTable.vue.d.ts +2 -7
- package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/DataTable/useTableData.d.ts +2 -6
- package/dist/components/DataTable/useTableData.d.ts.map +1 -1
- package/dist/components/form/BagelForm.vue.d.ts +17 -11
- package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
- package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
- package/dist/composables/index.d.ts +1 -1
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/index.cjs +354 -284
- package/dist/index.mjs +355 -285
- package/dist/style.css +74 -74
- package/dist/types/BagelForm.d.ts +1 -1
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/DataTable/DataTable.vue +7 -3
- package/src/components/DataTable/useTableData.ts +66 -36
- package/src/components/Loading.vue +2 -2
- package/src/components/form/BagelForm.vue +138 -78
- package/src/components/form/FieldArray.vue +110 -75
- package/src/composables/index.ts +14 -4
- package/src/types/BagelForm.ts +1 -1
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T extends {[key:string]:any}">
|
|
2
|
-
import type { BglFormSchemaFnT, Field } from '@bagelink/vue'
|
|
2
|
+
import type { BglFormSchemaFnT, Field, BglFormSchemaT } from '@bagelink/vue'
|
|
3
3
|
import type { VNode } from 'vue'
|
|
4
|
-
import {
|
|
4
|
+
import { Loading } from '@bagelink/vue'
|
|
5
|
+
import { onMounted, watch, ref, toRef, computed } from 'vue'
|
|
5
6
|
import { useSchemaField } from '../../composables/useSchemaField'
|
|
6
7
|
import { getNestedValue } from '../../utils'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
modelValue?:
|
|
10
|
-
schema?: BglFormSchemaFnT<
|
|
9
|
+
const props = withDefaults(defineProps<{
|
|
10
|
+
modelValue?: T
|
|
11
|
+
schema?: BglFormSchemaFnT<T>
|
|
11
12
|
tag?: 'form' | 'template'
|
|
12
13
|
class?: string
|
|
13
|
-
onSubmit?: (data:
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const props = withDefaults(defineProps<BagelFormProps<T>>(), {
|
|
14
|
+
onSubmit?: (data: T) => Promise<void> | void
|
|
15
|
+
}>(), {
|
|
17
16
|
modelValue: undefined,
|
|
18
17
|
schema: undefined,
|
|
19
18
|
tag: 'form',
|
|
@@ -24,131 +23,192 @@ const emit = defineEmits<{
|
|
|
24
23
|
(e: 'update:modelValue', value: T): void
|
|
25
24
|
}>()
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
return JSON.parse(JSON.stringify(obj))
|
|
31
|
-
} catch (e) {
|
|
32
|
-
console.warn('Failed to clone object:', e)
|
|
33
|
-
return obj
|
|
34
|
-
}
|
|
35
|
-
}
|
|
26
|
+
// Clone helper
|
|
27
|
+
const clone = <T>(obj: T): T => !obj ? obj : JSON.parse(JSON.stringify(obj))
|
|
36
28
|
|
|
29
|
+
// Form state
|
|
37
30
|
const form = ref<HTMLFormElement>()
|
|
38
|
-
const formData = ref<T>(
|
|
39
|
-
const initialFormData = ref<T>(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
const formData = ref<T>(clone(props.modelValue ?? {}) as T)
|
|
32
|
+
const initialFormData = ref<T>(clone(props.modelValue ?? {}) as T)
|
|
33
|
+
const formState = ref<'success' | 'error' | 'idle' | 'submitting'>('idle')
|
|
34
|
+
const schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
|
|
35
|
+
const resolvedSchemaData = ref<BglFormSchemaT<T>>()
|
|
36
|
+
const schemaRef = toRef(props, 'schema')
|
|
37
|
+
const resolvedSchema = computed(() => resolvedSchemaData.value)
|
|
38
|
+
const isDirty = computed(() => {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(formData.value) !== JSON.stringify(initialFormData.value)
|
|
41
|
+
} catch {
|
|
42
|
+
return false
|
|
44
43
|
}
|
|
45
44
|
})
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
// Initialize on mount
|
|
47
|
+
onMounted(() => {
|
|
48
|
+
if (props.modelValue) initialFormData.value = clone(props.modelValue)
|
|
49
|
+
refreshSchema()
|
|
50
|
+
})
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
52
|
+
// Watch for model changes
|
|
53
|
+
watch(() => props.modelValue, (val) => {
|
|
54
|
+
if (val !== undefined) formData.value = clone(val)
|
|
53
55
|
}, { immediate: true, deep: true })
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// Schema resolution
|
|
58
|
+
async function resolveSchema(schema?: BglFormSchemaFnT<T>) {
|
|
59
|
+
if (!schema) {
|
|
60
|
+
resolvedSchemaData.value = undefined
|
|
61
|
+
schemaState.value = 'loaded'
|
|
62
|
+
return
|
|
63
|
+
}
|
|
59
64
|
|
|
60
|
-
const isDirty = $computed(() => {
|
|
61
65
|
try {
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
schemaState.value = 'loading'
|
|
67
|
+
const isPromise = (obj: any) => obj && typeof obj.then === 'function'
|
|
68
|
+
|
|
69
|
+
let result: any
|
|
70
|
+
if (typeof schema === 'function') {
|
|
71
|
+
result = schema()
|
|
72
|
+
result = isPromise(result) ? await result : result
|
|
73
|
+
} else {
|
|
74
|
+
result = isPromise(schema) ? await schema : schema
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
resolvedSchemaData.value = result
|
|
78
|
+
schemaState.value = 'loaded'
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error('Schema error:', error)
|
|
81
|
+
schemaState.value = 'error'
|
|
82
|
+
resolvedSchemaData.value = undefined
|
|
68
83
|
}
|
|
69
|
-
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Public refresh method
|
|
87
|
+
async function refreshSchema() {
|
|
88
|
+
await resolveSchema(props.schema)
|
|
89
|
+
return resolvedSchemaData.value
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Watch schema changes
|
|
93
|
+
watch(schemaRef, resolveSchema, { immediate: true, deep: true })
|
|
70
94
|
|
|
95
|
+
// Update form data
|
|
71
96
|
function updateFormData(fieldId: string, value: any) {
|
|
72
97
|
const keys = fieldId.split('.')
|
|
73
|
-
const newData =
|
|
98
|
+
const newData = clone(formData.value) as Record<string, any>
|
|
74
99
|
let current = newData
|
|
75
100
|
|
|
76
|
-
// Traverse the object, creating nested objects as needed
|
|
77
101
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
78
102
|
const key = keys[i]
|
|
79
|
-
|
|
80
|
-
if (!current[key] || typeof current[key] !== 'object') {
|
|
81
|
-
current[key] = {}
|
|
82
|
-
}
|
|
103
|
+
if (!current[key] || typeof current[key] !== 'object') current[key] = {}
|
|
83
104
|
current = current[key]
|
|
84
105
|
}
|
|
85
106
|
|
|
86
|
-
// Set the value at the final key
|
|
87
107
|
current[keys[keys.length - 1]] = value
|
|
88
108
|
formData.value = newData as T
|
|
89
109
|
emit('update:modelValue', formData.value)
|
|
90
110
|
}
|
|
91
111
|
|
|
112
|
+
// Form submission
|
|
92
113
|
async function handleSubmit() {
|
|
93
114
|
try {
|
|
94
115
|
if (formState.value === 'submitting') return
|
|
95
116
|
formState.value = 'submitting'
|
|
96
117
|
await props.onSubmit?.(formData.value)
|
|
97
|
-
initialFormData.value =
|
|
118
|
+
initialFormData.value = clone(formData.value)
|
|
98
119
|
formState.value = 'success'
|
|
99
|
-
// Notify parent window of successful submission
|
|
100
120
|
window.parent.postMessage({ type: 'BAGEL_FORM_SUCCESS', data: JSON.stringify(formData.value) }, '*')
|
|
101
121
|
} catch (error) {
|
|
102
|
-
console.error('
|
|
122
|
+
console.error('Submit error:', error)
|
|
103
123
|
formState.value = 'error'
|
|
104
124
|
}
|
|
105
125
|
}
|
|
106
126
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return form.value.reportValidity()
|
|
110
|
-
}
|
|
127
|
+
// Form validation
|
|
128
|
+
const validateForm = () => form.value?.reportValidity() ?? false
|
|
111
129
|
|
|
130
|
+
// Field rendering
|
|
112
131
|
const { renderField } = useSchemaField<T>({
|
|
113
132
|
mode: 'form',
|
|
114
|
-
getRowData: () => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
get: (path: string) => getNestedValue(formData.value, path, '')
|
|
119
|
-
}
|
|
120
|
-
},
|
|
133
|
+
getRowData: () => ({
|
|
134
|
+
...formData.value,
|
|
135
|
+
get: (path: string) => getNestedValue(formData.value, path, '')
|
|
136
|
+
}),
|
|
121
137
|
onUpdate: (field, value) => {
|
|
122
|
-
if (
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
if (field.id) {
|
|
139
|
+
updateFormData(field.id, value)
|
|
140
|
+
field.onUpdate?.(value, formData.value)
|
|
141
|
+
}
|
|
125
142
|
}
|
|
126
143
|
})
|
|
127
144
|
|
|
128
|
-
|
|
129
|
-
return renderField(field)
|
|
130
|
-
}
|
|
145
|
+
const renderSchemaField = (field: Field<T>): VNode | null => renderField(field)
|
|
131
146
|
|
|
132
|
-
defineExpose({ form, isDirty, validateForm })
|
|
147
|
+
defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema })
|
|
133
148
|
</script>
|
|
134
149
|
|
|
135
150
|
<template>
|
|
136
151
|
<template v-if="formState !== 'success' || !$slots.success">
|
|
137
152
|
<form v-if="props.tag === 'form'" ref="form" :class="props.class" @submit.prevent="handleSubmit">
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
153
|
+
<!-- Loading state -->
|
|
154
|
+
<slot v-if="schemaState === 'loading'" name="loading">
|
|
155
|
+
<div class="flex-center h-300px">
|
|
156
|
+
<Loading />
|
|
157
|
+
</div>
|
|
158
|
+
</slot>
|
|
159
|
+
|
|
160
|
+
<!-- Error state -->
|
|
161
|
+
<slot v-else-if="schemaState === 'error'" name="schema-error">
|
|
162
|
+
<div class="flex-center h-300px txt-red">
|
|
163
|
+
Error loading form
|
|
164
|
+
</div>
|
|
165
|
+
</slot>
|
|
166
|
+
|
|
167
|
+
<!-- Render fields -->
|
|
168
|
+
<component
|
|
169
|
+
:is="renderSchemaField(field)"
|
|
170
|
+
v-for="field in resolvedSchema"
|
|
171
|
+
v-else-if="resolvedSchema"
|
|
172
|
+
:key="field.id"
|
|
173
|
+
/>
|
|
174
|
+
|
|
175
|
+
<!-- Default slot -->
|
|
143
176
|
<slot v-else />
|
|
144
|
-
|
|
177
|
+
|
|
178
|
+
<!-- Submit slot -->
|
|
179
|
+
<slot
|
|
180
|
+
name="submit"
|
|
181
|
+
:submit="handleSubmit"
|
|
182
|
+
:isDirty="isDirty"
|
|
183
|
+
:validateForm="validateForm"
|
|
184
|
+
:formState="formState"
|
|
185
|
+
:schemaState="schemaState"
|
|
186
|
+
/>
|
|
145
187
|
</form>
|
|
188
|
+
|
|
189
|
+
<!-- Template mode -->
|
|
146
190
|
<template v-else>
|
|
147
|
-
<
|
|
148
|
-
<
|
|
149
|
-
</
|
|
191
|
+
<slot v-if="schemaState === 'loading'" name="loading">
|
|
192
|
+
<Loading />
|
|
193
|
+
</slot>
|
|
194
|
+
|
|
195
|
+
<slot v-else-if="schemaState === 'error'" name="schema-error">
|
|
196
|
+
<div class="flex-center h-300px txt-red">
|
|
197
|
+
Error loading form
|
|
198
|
+
</div>
|
|
199
|
+
</slot>
|
|
200
|
+
|
|
201
|
+
<component
|
|
202
|
+
:is="renderSchemaField(field)"
|
|
203
|
+
v-for="field in resolvedSchema"
|
|
204
|
+
v-else-if="resolvedSchema"
|
|
205
|
+
:key="field.id"
|
|
206
|
+
:class="props.class"
|
|
207
|
+
/>
|
|
150
208
|
</template>
|
|
151
209
|
</template>
|
|
210
|
+
|
|
211
|
+
<!-- Success/error slots -->
|
|
152
212
|
<slot v-if="formState === 'success'" name="success" />
|
|
153
213
|
<slot v-if="formState === 'error'" name="error" />
|
|
154
214
|
</template>
|
|
@@ -5,11 +5,10 @@ import type {
|
|
|
5
5
|
Attributes,
|
|
6
6
|
BagelFieldOptions,
|
|
7
7
|
BglFormSchemaFnT,
|
|
8
|
-
BglFormSchemaT,
|
|
9
8
|
Field,
|
|
10
9
|
} from '@bagelink/vue'
|
|
11
|
-
import { BagelForm, Btn } from '@bagelink/vue'
|
|
12
|
-
import {
|
|
10
|
+
import { BagelForm, Btn, Loading } from '@bagelink/vue'
|
|
11
|
+
import { ref, onMounted } from 'vue'
|
|
13
12
|
|
|
14
13
|
const props = withDefaults(
|
|
15
14
|
defineProps<{
|
|
@@ -40,61 +39,82 @@ const props = withDefaults(
|
|
|
40
39
|
|
|
41
40
|
const emit = defineEmits(['update:modelValue'])
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
// State
|
|
43
|
+
const minimizedItems = ref<boolean[]>([])
|
|
44
|
+
const internalData = ref<any[]>(props.modelValue || [])
|
|
45
|
+
const schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
|
|
46
|
+
const resolvedSchemaData = ref<any[]>([])
|
|
47
|
+
|
|
48
|
+
// Resolve schema (handles sync, async, function, and direct values)
|
|
49
|
+
async function resolveSchema() {
|
|
50
|
+
if (!props.schema) {
|
|
51
|
+
resolvedSchemaData.value = []
|
|
52
|
+
schemaState.value = 'loaded'
|
|
53
|
+
return
|
|
54
|
+
}
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
try {
|
|
57
|
+
schemaState.value = 'loading'
|
|
58
|
+
const isPromise = (obj: any) => obj && typeof obj.then === 'function'
|
|
59
|
+
|
|
60
|
+
let result: any
|
|
61
|
+
if (typeof props.schema === 'function') {
|
|
62
|
+
result = props.schema()
|
|
63
|
+
result = isPromise(result) ? await result : result
|
|
64
|
+
} else {
|
|
65
|
+
result = isPromise(props.schema) ? await props.schema : props.schema
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
resolvedSchemaData.value = result
|
|
69
|
+
schemaState.value = 'loaded'
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error('Schema error:', error)
|
|
72
|
+
schemaState.value = 'error'
|
|
73
|
+
resolvedSchemaData.value = []
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Initialize schema on mount
|
|
78
|
+
onMounted(() => {
|
|
79
|
+
resolveSchema()
|
|
80
|
+
})
|
|
46
81
|
|
|
82
|
+
// Event handlers
|
|
47
83
|
function emitValue() {
|
|
48
|
-
emit('update:modelValue',
|
|
84
|
+
emit('update:modelValue', internalData.value)
|
|
49
85
|
}
|
|
50
86
|
|
|
51
87
|
function deleteItem(i: number) {
|
|
52
|
-
|
|
88
|
+
internalData.value.splice(i, 1)
|
|
53
89
|
emitValue()
|
|
54
90
|
}
|
|
55
91
|
|
|
56
92
|
function addItem() {
|
|
57
|
-
|
|
93
|
+
internalData.value.push({})
|
|
58
94
|
emitValue()
|
|
59
95
|
}
|
|
60
96
|
|
|
61
97
|
function toggleMinimized(index: number) {
|
|
62
|
-
minimizedItems[index] = !minimizedItems[index]
|
|
98
|
+
minimizedItems.value[index] = !minimizedItems.value[index]
|
|
63
99
|
}
|
|
64
100
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
children: props.children,
|
|
70
|
-
// class: props.class,
|
|
71
|
-
attrs: props.attrs,
|
|
72
|
-
required: props.required,
|
|
73
|
-
disabled: props.disabled,
|
|
74
|
-
helptext: props.helptext,
|
|
75
|
-
options: props.options,
|
|
76
|
-
defaultValue: props.defaultValue,
|
|
77
|
-
transform: props.transform,
|
|
78
|
-
$el: props.el,
|
|
79
|
-
}) as Field<T>
|
|
80
|
-
) as Field<Record<string, any>>
|
|
81
|
-
|
|
82
|
-
const resolvedSchema = $computed<BglFormSchemaT<T>>(() => {
|
|
83
|
-
if (!props.schema) return [] as BglFormSchemaT<T>
|
|
84
|
-
return typeof props.schema === 'function' ? props.schema() : props.schema
|
|
85
|
-
})
|
|
101
|
+
function updateItem(index: number, value: any) {
|
|
102
|
+
internalData.value[index] = value
|
|
103
|
+
emitValue()
|
|
104
|
+
}
|
|
86
105
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
106
|
+
// // Field rendering
|
|
107
|
+
// const { renderField } = useSchemaField<any>({
|
|
108
|
+
// mode: 'form',
|
|
109
|
+
// getRowData: () => internalData.value,
|
|
110
|
+
// onUpdate: (field, value) => {
|
|
111
|
+
// if (!field.id) return
|
|
112
|
+
// const index = Number.parseInt(field.id)
|
|
113
|
+
// if (Number.isNaN(index)) return
|
|
114
|
+
// internalData.value[index] = value
|
|
115
|
+
// emitValue()
|
|
116
|
+
// }
|
|
117
|
+
// })
|
|
98
118
|
</script>
|
|
99
119
|
|
|
100
120
|
<template>
|
|
@@ -102,45 +122,60 @@ const { renderField } = useSchemaField<Record<string, any>>({
|
|
|
102
122
|
<p class="label mb-05">
|
|
103
123
|
{{ label }}
|
|
104
124
|
</p>
|
|
105
|
-
<div v-if="
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
<div v-if="resolvedSchemaData.length > 0" class="ps-025 border-start mb-05">
|
|
126
|
+
<!-- Loading state -->
|
|
127
|
+
<div v-if="schemaState === 'loading'" class="flex-center h-300px">
|
|
128
|
+
<Loading />
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<!-- Error state -->
|
|
132
|
+
<div v-else-if="schemaState === 'error'" class="flex-center h-300px txt-red">
|
|
133
|
+
Error
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<!-- Render items -->
|
|
137
|
+
<template v-else>
|
|
138
|
+
<div
|
|
139
|
+
v-for="(item, i) in internalData" :key="i" outline thin
|
|
140
|
+
class="mb-05 itemBox transition ps-05 pb-025 pt-025 radius-05 gap-05 overflow-hidden"
|
|
141
|
+
:class="{ minimized: minimizedItems[i] }"
|
|
142
|
+
>
|
|
143
|
+
<p v-if="minimizedItems[i]" class="minimizedText txt14 p-025 opacity-7">
|
|
144
|
+
{{ label }} {{ i + 1 }}
|
|
145
|
+
</p>
|
|
146
|
+
<BagelForm
|
|
147
|
+
v-else
|
|
148
|
+
:model-value="item"
|
|
149
|
+
:schema="resolvedSchemaData"
|
|
150
|
+
@update:model-value="val => updateItem(i, val)"
|
|
129
151
|
/>
|
|
152
|
+
<div class="bg-gray-80 -my-05 px-025 pt-065 pb-05 txt-center space-between flex column">
|
|
153
|
+
<Btn
|
|
154
|
+
v-if="resolvedSchemaData.length > 4"
|
|
155
|
+
class="block rotate-180 txt10 opacity-7 p-025"
|
|
156
|
+
flat thin icon="keyboard_arrow_down"
|
|
157
|
+
@click="toggleMinimized(i)"
|
|
158
|
+
/>
|
|
159
|
+
<Btn
|
|
160
|
+
v-if="props.delete"
|
|
161
|
+
icon="delete"
|
|
162
|
+
class="txt10 opacity-7"
|
|
163
|
+
thin
|
|
164
|
+
flat
|
|
165
|
+
@click="deleteItem(i)"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
130
168
|
</div>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
</
|
|
169
|
+
<Btn v-if="add" thin icon="add" color="gray" class="txt12" @click="addItem">
|
|
170
|
+
<p>{{ label }}</p>
|
|
171
|
+
</Btn>
|
|
172
|
+
</template>
|
|
135
173
|
</div>
|
|
136
174
|
|
|
137
175
|
<template v-else>
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
:key="i"
|
|
142
|
-
@update:model-value="emitValue"
|
|
143
|
-
/>
|
|
176
|
+
<div v-for="(_, i) in internalData" :key="i">
|
|
177
|
+
<p>No schema available</p>
|
|
178
|
+
</div>
|
|
144
179
|
</template>
|
|
145
180
|
</div>
|
|
146
181
|
</template>
|
package/src/composables/index.ts
CHANGED
|
@@ -10,13 +10,23 @@ interface useBglSchemaParamsT<T> {
|
|
|
10
10
|
data?: any[]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function useBglSchema<T = { [key: string]: unknown }>(
|
|
13
|
+
export async function useBglSchema<T = { [key: string]: unknown }>(
|
|
14
14
|
{ schema, columns, data }: useBglSchemaParamsT<T> = {}
|
|
15
|
-
): BglFormSchemaT<T
|
|
15
|
+
): Promise<BglFormSchemaT<T>> {
|
|
16
16
|
let _schema = schema
|
|
17
|
+
|
|
18
|
+
// Handle async schema functions
|
|
17
19
|
if (typeof _schema === 'function') {
|
|
18
|
-
|
|
20
|
+
const result = _schema()
|
|
21
|
+
if (result instanceof Promise) {
|
|
22
|
+
_schema = await result
|
|
23
|
+
} else {
|
|
24
|
+
_schema = result
|
|
25
|
+
}
|
|
26
|
+
} else if (_schema instanceof Promise) {
|
|
27
|
+
_schema = await _schema
|
|
19
28
|
}
|
|
29
|
+
|
|
20
30
|
if (_schema) {
|
|
21
31
|
return (
|
|
22
32
|
columns && columns.length > 0
|
|
@@ -41,7 +51,7 @@ export function localRef<T>(
|
|
|
41
51
|
localStorage.setItem(key, JSON.stringify(val))
|
|
42
52
|
}, { immediate: true, deep: true })
|
|
43
53
|
|
|
44
|
-
return value
|
|
54
|
+
return value as any
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
export const useLocalStorage = localRef
|
package/src/types/BagelForm.ts
CHANGED
|
@@ -73,4 +73,4 @@ export type BglFieldT<T = { [key: string]: any }> = Field<T>
|
|
|
73
73
|
|
|
74
74
|
export type BglFormSchemaT<T = { [key: string]: any }> = Field<T>[]
|
|
75
75
|
|
|
76
|
-
export type BglFormSchemaFnT<T = { [key: string]: any }> = (() => BglFormSchemaT<T>) | BglFormSchemaT<T>
|
|
76
|
+
export type BglFormSchemaFnT<T = { [key: string]: any }> = (() => BglFormSchemaT<T>) | BglFormSchemaT<T> | (() => Promise<BglFormSchemaT<T>>) | Promise<BglFormSchemaT<T>>
|