qdadm 0.45.1 → 0.46.1
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/package.json
CHANGED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
/**
|
|
3
|
+
* FormInput - Auto-renders the appropriate input based on field config
|
|
4
|
+
*
|
|
5
|
+
* Takes a field config object and renders the matching PrimeVue component.
|
|
6
|
+
* Supports hint override but field.type takes precedence if specified.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <FormInput :field="f" v-model="form.data.value[f.name]" />
|
|
10
|
+
*/
|
|
11
|
+
import { computed } from 'vue'
|
|
12
|
+
import InputText from 'primevue/inputtext'
|
|
13
|
+
import InputNumber from 'primevue/inputnumber'
|
|
14
|
+
import Textarea from 'primevue/textarea'
|
|
15
|
+
import Select from 'primevue/select'
|
|
16
|
+
import Checkbox from 'primevue/checkbox'
|
|
17
|
+
import Password from 'primevue/password'
|
|
18
|
+
import DatePicker from 'primevue/datepicker'
|
|
19
|
+
|
|
20
|
+
const props = defineProps({
|
|
21
|
+
field: { type: Object, required: true },
|
|
22
|
+
modelValue: { default: null },
|
|
23
|
+
hint: { type: String, default: null } // Optional type hint override
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const emit = defineEmits(['update:modelValue'])
|
|
27
|
+
|
|
28
|
+
const value = computed({
|
|
29
|
+
get: () => props.modelValue,
|
|
30
|
+
set: (v) => emit('update:modelValue', v)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
// Resolve component type: field.type > hint > 'text'
|
|
34
|
+
const inputType = computed(() => props.field?.type || props.hint || 'text')
|
|
35
|
+
|
|
36
|
+
// Date value with string ↔ Date conversion for DatePicker
|
|
37
|
+
const dateValue = computed({
|
|
38
|
+
get: () => {
|
|
39
|
+
const v = props.modelValue
|
|
40
|
+
if (!v) return null
|
|
41
|
+
if (v instanceof Date) return v
|
|
42
|
+
// Convert ISO string to Date
|
|
43
|
+
return new Date(v)
|
|
44
|
+
},
|
|
45
|
+
set: (v) => {
|
|
46
|
+
// Convert Date back to ISO string for storage
|
|
47
|
+
emit('update:modelValue', v ? v.toISOString() : null)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<InputText
|
|
54
|
+
v-if="inputType === 'text' || inputType === 'email'"
|
|
55
|
+
v-model="value"
|
|
56
|
+
:placeholder="field.placeholder"
|
|
57
|
+
:disabled="field.disabled"
|
|
58
|
+
:readonly="field.readonly"
|
|
59
|
+
class="w-full"
|
|
60
|
+
/>
|
|
61
|
+
<Password
|
|
62
|
+
v-else-if="inputType === 'password'"
|
|
63
|
+
v-model="value"
|
|
64
|
+
:placeholder="field.placeholder"
|
|
65
|
+
:disabled="field.disabled"
|
|
66
|
+
:feedback="false"
|
|
67
|
+
toggleMask
|
|
68
|
+
class="w-full"
|
|
69
|
+
/>
|
|
70
|
+
<InputNumber
|
|
71
|
+
v-else-if="inputType === 'number'"
|
|
72
|
+
v-model="value"
|
|
73
|
+
:placeholder="field.placeholder"
|
|
74
|
+
:disabled="field.disabled"
|
|
75
|
+
:readonly="field.readonly"
|
|
76
|
+
:useGrouping="false"
|
|
77
|
+
class="w-full"
|
|
78
|
+
/>
|
|
79
|
+
<Textarea
|
|
80
|
+
v-else-if="inputType === 'textarea'"
|
|
81
|
+
v-model="value"
|
|
82
|
+
:placeholder="field.placeholder"
|
|
83
|
+
:disabled="field.disabled"
|
|
84
|
+
:readonly="field.readonly"
|
|
85
|
+
rows="3"
|
|
86
|
+
class="w-full"
|
|
87
|
+
/>
|
|
88
|
+
<Select
|
|
89
|
+
v-else-if="inputType === 'select'"
|
|
90
|
+
v-model="value"
|
|
91
|
+
:options="field.options"
|
|
92
|
+
:optionLabel="field.optionLabel"
|
|
93
|
+
:optionValue="field.optionValue"
|
|
94
|
+
:placeholder="field.placeholder"
|
|
95
|
+
:disabled="field.disabled"
|
|
96
|
+
class="w-full"
|
|
97
|
+
/>
|
|
98
|
+
<Checkbox
|
|
99
|
+
v-else-if="inputType === 'boolean'"
|
|
100
|
+
v-model="value"
|
|
101
|
+
:disabled="field.disabled"
|
|
102
|
+
binary
|
|
103
|
+
/>
|
|
104
|
+
<DatePicker
|
|
105
|
+
v-else-if="inputType === 'date' || inputType === 'datetime'"
|
|
106
|
+
v-model="dateValue"
|
|
107
|
+
:placeholder="field.placeholder"
|
|
108
|
+
:disabled="field.disabled"
|
|
109
|
+
:showTime="inputType === 'datetime'"
|
|
110
|
+
class="w-full"
|
|
111
|
+
/>
|
|
112
|
+
<!-- Fallback to text -->
|
|
113
|
+
<InputText
|
|
114
|
+
v-else
|
|
115
|
+
v-model="value"
|
|
116
|
+
:placeholder="field.placeholder"
|
|
117
|
+
:disabled="field.disabled"
|
|
118
|
+
class="w-full"
|
|
119
|
+
/>
|
|
120
|
+
</template>
|
|
@@ -234,7 +234,7 @@ function onGuardStay() {
|
|
|
234
234
|
<!-- Unsaved Changes Dialog -->
|
|
235
235
|
<UnsavedChangesDialog
|
|
236
236
|
v-if="guardDialog"
|
|
237
|
-
|
|
237
|
+
:visible="guardDialog.visible.value"
|
|
238
238
|
:saving="saving"
|
|
239
239
|
:hasOnSave="!!guardDialog.onSave"
|
|
240
240
|
@saveAndLeave="onGuardSaveAndLeave"
|
package/src/components/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export { default as DefaultToaster } from './layout/defaults/DefaultToaster.vue'
|
|
|
22
22
|
// Forms
|
|
23
23
|
export { default as FormPage } from './forms/FormPage.vue'
|
|
24
24
|
export { default as FormField } from './forms/FormField.vue'
|
|
25
|
+
export { default as FormInput } from './forms/FormInput.vue'
|
|
25
26
|
export { default as FormActions } from './forms/FormActions.vue'
|
|
26
27
|
export { default as FormTabs } from './forms/FormTabs.vue'
|
|
27
28
|
export { default as FormTab } from './forms/FormTab.vue'
|
|
@@ -495,9 +495,36 @@ export function useFormPageBuilder(config = {}) {
|
|
|
495
495
|
fieldOrder.value.push(name)
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
+
// Auto-resolve reference options (async, non-blocking)
|
|
499
|
+
resolveReferences()
|
|
500
|
+
|
|
498
501
|
return builderApi
|
|
499
502
|
}
|
|
500
503
|
|
|
504
|
+
/**
|
|
505
|
+
* Resolve reference options for all fields with reference config
|
|
506
|
+
*
|
|
507
|
+
* Called automatically by generateFields(). Loads options from
|
|
508
|
+
* referenced entities and updates field configs reactively.
|
|
509
|
+
*
|
|
510
|
+
* @returns {Promise<void>}
|
|
511
|
+
*/
|
|
512
|
+
async function resolveReferences() {
|
|
513
|
+
for (const [name, config] of fieldsMap.value.entries()) {
|
|
514
|
+
// Skip if field has static options or no reference
|
|
515
|
+
if (config.options || !config.reference) continue
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
const options = await manager.resolveReferenceOptions(name)
|
|
519
|
+
// Update field config reactively
|
|
520
|
+
const updatedConfig = { ...config, options }
|
|
521
|
+
fieldsMap.value.set(name, updatedConfig)
|
|
522
|
+
} catch (error) {
|
|
523
|
+
console.warn(`[useFormPageBuilder] Failed to resolve options for field '${name}':`, error)
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
501
528
|
/**
|
|
502
529
|
* Resolve field configuration from schema definition
|
|
503
530
|
*
|
|
@@ -512,6 +539,8 @@ export function useFormPageBuilder(config = {}) {
|
|
|
512
539
|
required = false,
|
|
513
540
|
default: defaultValue,
|
|
514
541
|
options = null,
|
|
542
|
+
optionLabel = 'label',
|
|
543
|
+
optionValue = 'value',
|
|
515
544
|
placeholder = null,
|
|
516
545
|
disabled = false,
|
|
517
546
|
readonly = false,
|
|
@@ -532,6 +561,8 @@ export function useFormPageBuilder(config = {}) {
|
|
|
532
561
|
required,
|
|
533
562
|
default: defaultValue,
|
|
534
563
|
options,
|
|
564
|
+
optionLabel,
|
|
565
|
+
optionValue,
|
|
535
566
|
placeholder,
|
|
536
567
|
disabled,
|
|
537
568
|
readonly,
|
|
@@ -1108,6 +1139,7 @@ export function useFormPageBuilder(config = {}) {
|
|
|
1108
1139
|
// Field management
|
|
1109
1140
|
fields,
|
|
1110
1141
|
generateFields,
|
|
1142
|
+
resolveReferences,
|
|
1111
1143
|
addField,
|
|
1112
1144
|
removeField,
|
|
1113
1145
|
excludeField,
|