mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: use defineModel
This commit is contained in:
parent
2ba27d6c33
commit
d2cf9522b1
13 changed files with 43 additions and 57 deletions
|
@ -19,7 +19,6 @@ import { isDisplayComponent, isWritableComponent } from '@/types/form'
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
id?: string
|
id?: string
|
||||||
modelValue?: MV
|
|
||||||
fields?: FFD
|
fields?: FFD
|
||||||
validations?: FormValidation<MV>
|
validations?: FormValidation<MV>
|
||||||
submitText?: string
|
submitText?: string
|
||||||
|
@ -31,7 +30,6 @@ const props = withDefaults(
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
id: 'ynh-form',
|
id: 'ynh-form',
|
||||||
modelValue: undefined,
|
|
||||||
fields: undefined,
|
fields: undefined,
|
||||||
validations: undefined,
|
validations: undefined,
|
||||||
submitText: undefined,
|
submitText: undefined,
|
||||||
|
@ -71,6 +69,8 @@ const slots = defineSlots<
|
||||||
}
|
}
|
||||||
>()
|
>()
|
||||||
|
|
||||||
|
const modelValue = defineModel<MV>()
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const globalErrorFeedback = computed(() => {
|
const globalErrorFeedback = computed(() => {
|
||||||
|
@ -94,7 +94,7 @@ const sections = computed(() => {
|
||||||
|
|
||||||
function onModelUpdate(key: keyof MV, value: MV[keyof MV]) {
|
function onModelUpdate(key: keyof MV, value: MV[keyof MV]) {
|
||||||
emit('update:modelValue', {
|
emit('update:modelValue', {
|
||||||
...props.modelValue!,
|
...modelValue.value!,
|
||||||
[key]: value,
|
[key]: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ const Fields = createReusableTemplate<{
|
||||||
<FormField
|
<FormField
|
||||||
v-if="!field.readonly"
|
v-if="!field.readonly"
|
||||||
v-bind="field"
|
v-bind="field"
|
||||||
:model-value="props.modelValue![k]"
|
:model-value="modelValue![k]"
|
||||||
:validation="props.validations?.form[k]"
|
:validation="props.validations?.form[k]"
|
||||||
@update:model-value="onModelUpdate(k, $event)"
|
@update:model-value="onModelUpdate(k, $event)"
|
||||||
>
|
>
|
||||||
|
@ -130,7 +130,7 @@ const Fields = createReusableTemplate<{
|
||||||
<FormFieldReadonly
|
<FormFieldReadonly
|
||||||
v-else
|
v-else
|
||||||
v-bind="field"
|
v-bind="field"
|
||||||
:model-value="props.modelValue![k]"
|
:model-value="modelValue![k]"
|
||||||
/>
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
<slot
|
<slot
|
||||||
|
|
|
@ -36,7 +36,6 @@ const props = withDefaults(defineProps<FormFieldProps<C, MV>>(), {
|
||||||
prepend: undefined,
|
prepend: undefined,
|
||||||
rules: undefined,
|
rules: undefined,
|
||||||
|
|
||||||
modelValue: undefined,
|
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ const slots = defineSlots<{
|
||||||
description?: any
|
description?: any
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const model = defineModel<MV>()
|
const modelValue = defineModel<MV>()
|
||||||
|
|
||||||
const attrs = useAttrs()
|
const attrs = useAttrs()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
@ -137,7 +136,6 @@ const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
|
||||||
v-bind="{
|
v-bind="{
|
||||||
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
|
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
|
||||||
ariaDescribedby,
|
ariaDescribedby,
|
||||||
modelValue: props.modelValue,
|
|
||||||
state,
|
state,
|
||||||
validation: validation,
|
validation: validation,
|
||||||
}"
|
}"
|
||||||
|
@ -146,7 +144,7 @@ const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
|
||||||
<Component
|
<Component
|
||||||
v-bind="props.cProps"
|
v-bind="props.cProps"
|
||||||
:is="component"
|
:is="component"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:aria-describedby="ariaDescribedby"
|
:aria-describedby="ariaDescribedby"
|
||||||
:state="state"
|
:state="state"
|
||||||
:validation="validation"
|
:validation="validation"
|
||||||
|
|
|
@ -44,13 +44,12 @@ const props = withDefaults(
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
addBtnText: undefined,
|
addBtnText: undefined,
|
||||||
|
|
||||||
modelValue: undefined,
|
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'update:modelValue': [value: MV]
|
'update:modelValue': [modelValue: MV]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const slots = defineSlots<{
|
const slots = defineSlots<{
|
||||||
|
@ -62,6 +61,8 @@ const slots = defineSlots<{
|
||||||
description?: () => any
|
description?: () => any
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const modelValue = defineModel<MV>()
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const attrs = useAttrs()
|
const attrs = useAttrs()
|
||||||
|
@ -104,7 +105,7 @@ const error = computed(() => {
|
||||||
|
|
||||||
const subProps = computed<FormFieldProps<C, ArrInnerType<MV>>[]>(() => {
|
const subProps = computed<FormFieldProps<C, ArrInnerType<MV>>[]>(() => {
|
||||||
return (
|
return (
|
||||||
props.modelValue?.map((modelValue: ArrInnerType<MV>, i) => {
|
modelValue.value?.map((modelValue: ArrInnerType<MV>, i) => {
|
||||||
return {
|
return {
|
||||||
cProps: {
|
cProps: {
|
||||||
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
|
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
|
||||||
|
@ -143,22 +144,22 @@ const errorMessage = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
function addElement() {
|
function addElement() {
|
||||||
const value = [...(props?.modelValue || []), props.defaultValue!()] as MV
|
const value = [...(modelValue.value || []), props.defaultValue!()] as MV
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
|
|
||||||
// FIXME: Focus newly inserted form item
|
// FIXME: Focus newly inserted form item
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeElement(index: number) {
|
function removeElement(index: number) {
|
||||||
if (!props.modelValue) return
|
if (!modelValue.value) return
|
||||||
const value = [...props.modelValue] as MV
|
const value = [...modelValue.value] as MV
|
||||||
value.splice(index, 1)
|
value.splice(index, 1)
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateElement(index: number, newValue: ArrInnerType<MV>) {
|
function updateElement(index: number, newValue: ArrInnerType<MV>) {
|
||||||
if (!props.modelValue) return
|
if (!modelValue.value) return
|
||||||
const value = [...props.modelValue] as MV
|
const value = [...modelValue.value] as MV
|
||||||
value.splice(index, 1, newValue)
|
value.splice(index, 1, newValue)
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@ defineOptions({
|
||||||
|
|
||||||
const props = withDefaults(defineProps<FormFieldReadonlyProps<C, MV>>(), {
|
const props = withDefaults(defineProps<FormFieldReadonlyProps<C, MV>>(), {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
cols: () => ({ md: 4, lg: 3 }),
|
cols: () => ({ md: 4, lg: 3 }),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const modelValue = defineModel<MV>()
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const cols = computed<Cols>(() => ({
|
const cols = computed<Cols>(() => ({
|
||||||
|
@ -32,7 +33,7 @@ const cols = computed<Cols>(() => ({
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const text = computed(() => {
|
const text = computed(() => {
|
||||||
return parseValue(props.modelValue)
|
return parseValue(modelValue.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
function parseValue(value: any) {
|
function parseValue(value: any) {
|
||||||
|
|
|
@ -9,11 +9,9 @@ const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
items?: T[] | null
|
items?: T[] | null
|
||||||
itemsName: string | null
|
itemsName: string | null
|
||||||
modelValue?: string
|
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
items: undefined,
|
items: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ withDefaults(
|
||||||
touchKey: undefined,
|
touchKey: undefined,
|
||||||
type: 'email',
|
type: 'email',
|
||||||
|
|
||||||
modelValue: undefined,
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
|
|
|
@ -12,23 +12,18 @@ withDefaults(
|
||||||
labels: () => ({ true: 'yes', false: 'no' }),
|
labels: () => ({ true: 'yes', false: 'no' }),
|
||||||
|
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
defineEmits<{
|
const modelValue = defineModel<boolean>()
|
||||||
'update:modelValue': [value: boolean]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const model = defineModel<boolean>()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BFormCheckbox
|
<BFormCheckbox
|
||||||
:id="id"
|
:id="id"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:name="name"
|
:name="name"
|
||||||
:aria-describedby="ariaDescribedby"
|
:aria-describedby="ariaDescribedby"
|
||||||
:state="state"
|
:state="state"
|
||||||
|
|
|
@ -21,7 +21,6 @@ const props = withDefaults(
|
||||||
dropPlaceholder: undefined,
|
dropPlaceholder: undefined,
|
||||||
|
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
modelValue: () => ({ file: null }),
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
|
@ -31,13 +30,17 @@ const emit = defineEmits<{
|
||||||
'update:modelValue': [value: FileModelValue]
|
'update:modelValue': [value: FileModelValue]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const modelValue = defineModel<FileModelValue>({
|
||||||
|
default: () => ({ file: null }),
|
||||||
|
})
|
||||||
|
|
||||||
const touch = inject(ValidationTouchSymbol)
|
const touch = inject(ValidationTouchSymbol)
|
||||||
const inputElem = ref<InstanceType<typeof BFormFile> | null>(null)
|
const inputElem = ref<InstanceType<typeof BFormFile> | null>(null)
|
||||||
|
|
||||||
const placeholder = computed(() => {
|
const placeholder = computed(() => {
|
||||||
return props.modelValue.file === null
|
return modelValue.value.file === null
|
||||||
? props.placeholder
|
? props.placeholder
|
||||||
: props.modelValue.file.name
|
: modelValue.value.file.name
|
||||||
})
|
})
|
||||||
|
|
||||||
function onInput(file: File | File[] | null) {
|
function onInput(file: File | File[] | null) {
|
||||||
|
|
|
@ -20,18 +20,12 @@ const props = withDefaults(
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
defineEmits<{
|
|
||||||
'update:modelValue': [value: string | number | null]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const touch = inject(ValidationTouchSymbol)
|
const modelValue = defineModel<string | number | null>({
|
||||||
|
|
||||||
const model = defineModel<string | number | null>({
|
|
||||||
set(value) {
|
set(value) {
|
||||||
if (props.type === 'number' && typeof value === 'string') {
|
if (props.type === 'number' && typeof value === 'string') {
|
||||||
if (value === '') return ''
|
if (value === '') return ''
|
||||||
|
@ -41,6 +35,8 @@ const model = defineModel<string | number | null>({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const touch = inject(ValidationTouchSymbol)
|
||||||
|
|
||||||
const autocomplete = computed(() => {
|
const autocomplete = computed(() => {
|
||||||
const typeToAutocomplete = {
|
const typeToAutocomplete = {
|
||||||
password: 'new-password',
|
password: 'new-password',
|
||||||
|
@ -64,7 +60,7 @@ const fromValidation = computed(() => {
|
||||||
<BFormInput
|
<BFormInput
|
||||||
:id="id"
|
:id="id"
|
||||||
v-bind="fromValidation"
|
v-bind="fromValidation"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:name="name"
|
:name="name"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:autocomplete="autocomplete"
|
:autocomplete="autocomplete"
|
||||||
|
|
|
@ -15,7 +15,6 @@ const props = withDefaults(
|
||||||
// options: undefined,
|
// options: undefined,
|
||||||
|
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
|
@ -23,7 +22,7 @@ const props = withDefaults(
|
||||||
|
|
||||||
const touch = inject(ValidationTouchSymbol)
|
const touch = inject(ValidationTouchSymbol)
|
||||||
|
|
||||||
const model = defineModel<string[]>()
|
const modelValue = defineModel<string[]>()
|
||||||
|
|
||||||
const required = computed(() => 'required' in (props?.validation ?? {}))
|
const required = computed(() => 'required' in (props?.validation ?? {}))
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ const required = computed(() => 'required' in (props?.validation ?? {}))
|
||||||
<template>
|
<template>
|
||||||
<BFormTags
|
<BFormTags
|
||||||
:id="id"
|
:id="id"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:name="name"
|
:name="name"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:limit="limit"
|
:limit="limit"
|
||||||
|
|
|
@ -30,18 +30,17 @@ const props = withDefaults(
|
||||||
tagIcon: undefined,
|
tagIcon: undefined,
|
||||||
|
|
||||||
ariaDescribedby: undefined,
|
ariaDescribedby: undefined,
|
||||||
modelValue: undefined,
|
|
||||||
state: undefined,
|
state: undefined,
|
||||||
validation: undefined,
|
validation: undefined,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'update:modelValue': [value: string[]]
|
|
||||||
'tag-update': [value: TagUpdateArgs]
|
'tag-update': [value: TagUpdateArgs]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const model = defineModel<string[]>()
|
const modelValue = defineModel<string[]>()
|
||||||
|
|
||||||
const searchElem = ref<InstanceType<typeof BDropdown> | null>(null)
|
const searchElem = ref<InstanceType<typeof BDropdown> | null>(null)
|
||||||
const dropdownElem = ref<InstanceType<typeof BFormInput> | null>(null)
|
const dropdownElem = ref<InstanceType<typeof BFormInput> | null>(null)
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ const availableOptions = computed(() => {
|
||||||
return props.options.filter((opt) => {
|
return props.options.filter((opt) => {
|
||||||
const tag = typeof opt === 'string' ? opt : opt.value
|
const tag = typeof opt === 'string' ? opt : opt.value
|
||||||
let filterIn =
|
let filterIn =
|
||||||
model.value?.indexOf(tag) === -1 &&
|
modelValue.value?.indexOf(tag) === -1 &&
|
||||||
!(props.disabledItems?.includes(tag) ?? false)
|
!(props.disabledItems?.includes(tag) ?? false)
|
||||||
if (filterIn && criteria.value) {
|
if (filterIn && criteria.value) {
|
||||||
filterIn = tag.toLowerCase().indexOf(criteria.value) > -1
|
filterIn = tag.toLowerCase().indexOf(criteria.value) > -1
|
||||||
|
@ -120,7 +119,7 @@ function onDropdownKeydown(e: KeyboardEvent) {
|
||||||
<BFormTags
|
<BFormTags
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:id="id"
|
:id="id"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:name="name"
|
:name="name"
|
||||||
:aria-describedby="ariaDescribedby"
|
:aria-describedby="ariaDescribedby"
|
||||||
:state="state"
|
:state="state"
|
||||||
|
|
|
@ -24,7 +24,7 @@ defineEmits<{
|
||||||
'update:modelValue': [value: string | null]
|
'update:modelValue': [value: string | null]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const model = defineModel<string>()
|
const modelValue = defineModel<string>()
|
||||||
|
|
||||||
const touch = inject(ValidationTouchSymbol)
|
const touch = inject(ValidationTouchSymbol)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ const required = computed(() => 'required' in (props?.validation ?? {}))
|
||||||
<template>
|
<template>
|
||||||
<BFormTextarea
|
<BFormTextarea
|
||||||
:id="id"
|
:id="id"
|
||||||
v-model="model"
|
v-model="modelValue"
|
||||||
:name="name"
|
:name="name"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:aria-describedby="ariaDescribedby"
|
:aria-describedby="ariaDescribedby"
|
||||||
|
|
|
@ -55,7 +55,6 @@ type BaseWritableItemProps = {
|
||||||
|
|
||||||
export type BaseItemComputedProps<MV extends any = any> = {
|
export type BaseItemComputedProps<MV extends any = any> = {
|
||||||
ariaDescribedby?: string | string[]
|
ariaDescribedby?: string | string[]
|
||||||
modelValue?: MV
|
|
||||||
state?: StateValidation
|
state?: StateValidation
|
||||||
validation?: BaseValidation
|
validation?: BaseValidation
|
||||||
}
|
}
|
||||||
|
@ -238,8 +237,7 @@ type FormFieldRules<MV extends any> = MV extends object
|
||||||
: ValidationArgs<MV | Partial<MV>>
|
: ValidationArgs<MV | Partial<MV>>
|
||||||
: ValidationRuleCollection<MV>
|
: ValidationRuleCollection<MV>
|
||||||
|
|
||||||
type BaseFormFieldComputedProps<MV extends any = any> = {
|
type BaseFormFieldComputedProps = {
|
||||||
modelValue?: MV
|
|
||||||
validation?: BaseValidation
|
validation?: BaseValidation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,14 +293,13 @@ export type FormFieldProps<
|
||||||
C extends AnyWritableComponents,
|
C extends AnyWritableComponents,
|
||||||
MV extends any,
|
MV extends any,
|
||||||
> = Omit<FormField<C, MV>, 'hr' | 'visible' | 'readonly'> &
|
> = Omit<FormField<C, MV>, 'hr' | 'visible' | 'readonly'> &
|
||||||
BaseFormFieldComputedProps<MV>
|
BaseFormFieldComputedProps
|
||||||
|
// BaseFormFieldComputedProps<MV>
|
||||||
|
|
||||||
export type FormFieldReadonlyProps<
|
export type FormFieldReadonlyProps<
|
||||||
C extends AnyWritableComponents,
|
C extends AnyWritableComponents,
|
||||||
MV extends any,
|
MV extends any,
|
||||||
> = Omit<FormFieldReadonly<C>, 'hr' | 'visible' | 'readonly' | 'rules'> & {
|
> = Omit<FormFieldReadonly<C>, 'hr' | 'visible' | 'readonly' | 'rules'>
|
||||||
modelValue?: MV
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FormFieldDict<T extends Obj = Obj> = {
|
export type FormFieldDict<T extends Obj = Obj> = {
|
||||||
[k in keyof T | string]: k extends keyof T
|
[k in keyof T | string]: k extends keyof T
|
||||||
|
|
Loading…
Add table
Reference in a new issue