1
0
mirror of synced 2024-11-25 06:46:02 +03:00

refactor: Moved components options to components classes, additional typehints

This commit is contained in:
Zaytsev Kirill 2020-10-11 15:10:21 +03:00
parent 713a2bab51
commit 0274ccd58a
4 changed files with 41 additions and 50 deletions

View File

@ -17,10 +17,12 @@ import {
Watch, Watch,
} from 'vue-property-decorator' } from 'vue-property-decorator'
import { arrayify, getNested, has, setNested, shallowEqualObjects } from './libs/utils' import { arrayify, getNested, has, setNested, shallowEqualObjects } from './libs/utils'
import { ObjectType } from '@/common.types'
import Registry from './libs/registry' import Registry from './libs/registry'
import FormSubmission from './FormSubmission' import FormSubmission from './FormSubmission'
import FormularioInput from '@/FormularioInput.vue'
@Component() @Component
export default class FormularioForm extends Vue { export default class FormularioForm extends Vue {
@Provide() formularioFieldValidation (errorObject) { @Provide() formularioFieldValidation (errorObject) {
return this.$emit('validation', errorObject) return this.$emit('validation', errorObject)
@ -37,16 +39,16 @@ export default class FormularioForm extends Vue {
this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer) this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer)
} }
@Prop({
type: [String, Boolean],
default: false
}) public readonly name!: string | boolean
@Model('input', { @Model('input', {
type: Object, type: Object,
default: () => ({}) default: () => ({})
}) readonly formularioValue!: Object }) readonly formularioValue!: Object
@Prop({
type: [String, Boolean],
default: false
}) public readonly name!: string | boolean
@Prop({ @Prop({
type: [Object, Boolean], type: [Object, Boolean],
default: false default: false
@ -173,8 +175,7 @@ export default class FormularioForm extends Vue {
this.$formulario.deregister(this) this.$formulario.deregister(this)
} }
// @TODO: Check FormularioForm, seems need an interface public register (field: string, component: FormularioInput) {
public register (field: string, component: FormularioForm) {
this.registry.register(field, component) this.registry.register(field, component)
} }
@ -229,6 +230,7 @@ export default class FormularioForm extends Vue {
setFieldValue (field, value) { setFieldValue (field, value) {
if (value === undefined) { if (value === undefined) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { [field]: value, ...proxy } = this.proxy const { [field]: value, ...proxy } = this.proxy
this.proxy = proxy this.proxy = proxy
} else { } else {
@ -238,7 +240,7 @@ export default class FormularioForm extends Vue {
} }
hasValidationErrors () { hasValidationErrors () {
return Promise.all(this.registry.reduce((resolvers, cmp, name) => { return Promise.all(this.registry.reduce((resolvers, cmp) => {
resolvers.push(cmp.performValidation() && cmp.getValidationErrors()) resolvers.push(cmp.performValidation() && cmp.getValidationErrors())
return resolvers return resolvers
}, [])).then(errorObjects => errorObjects.some(item => item.hasErrors)) }, [])).then(errorObjects => errorObjects.some(item => item.hasErrors))
@ -259,13 +261,15 @@ export default class FormularioForm extends Vue {
}) })
} }
setValues (values) { setValues (values: ObjectType) {
// Collect all keys, existing and incoming // Collect all keys, existing and incoming
const keys = Array.from(new Set(Object.keys(values).concat(Object.keys(this.proxy)))) const keys = Array.from(new Set(Object.keys(values).concat(Object.keys(this.proxy))))
keys.forEach(field => { keys.forEach(field => {
const fieldComponent = this.registry.get(field) as FormularioInput
if (this.registry.has(field) && if (this.registry.has(field) &&
!shallowEqualObjects(getNested(values, field), getNested(this.proxy, field)) && !shallowEqualObjects(getNested(values, field), getNested(this.proxy, field)) &&
!shallowEqualObjects(getNested(values, field), this.registry.get(field).proxy) !shallowEqualObjects(getNested(values, field), fieldComponent.proxy)
) { ) {
this.setFieldValue(field, getNested(values, field)) this.setFieldValue(field, getNested(values, field))
this.registry.get(field).context.model = getNested(values, field) this.registry.get(field).context.model = getNested(values, field)

View File

@ -9,25 +9,24 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator' import {
Component,
Inject,
Prop,
Provide,
} from 'vue-property-decorator'
@Component({ @Component
provide () {
return {
path: this.groupPath,
}
},
inject: ['path'],
})
export default class FormularioGrouping extends Vue { export default class FormularioGrouping extends Vue {
@Inject({ default: '' }) path!: string
@Prop({ required: true }) @Prop({ required: true })
readonly name!: string readonly name!: string
@Prop({ default: false }) @Prop({ default: false })
readonly isArrayItem!: boolean readonly isArrayItem!: boolean
get groupPath () { @Provide('path') get groupPath (): string {
if (this.isArrayItem) { if (this.isArrayItem) {
return `${this.path}[${this.name}]` return `${this.path}[${this.name}]`
} }

View File

@ -34,29 +34,15 @@ const ERROR_BEHAVIOR = {
SUBMIT: 'submit', SUBMIT: 'submit',
} }
@Component({ @Component({ inheritAttrs: false })
inheritAttrs: false,
props: {
imageBehavior: {
type: String,
default: 'preview'
},
uploader: {
type: [Function, Object, Boolean],
default: false
},
},
})
export default class FormularioInput extends Vue { export default class FormularioInput extends Vue {
@Inject({ default: undefined }) formularioSetter!: Function | undefined @Inject({ default: undefined }) formularioSetter!: Function|undefined
@Inject({ default: () => () => ({}) }) formularioFieldValidation!: Function @Inject({ default: () => () => ({}) }) formularioFieldValidation!: Function
@Inject({ default: undefined }) formularioRegister!: Function | undefined @Inject({ default: undefined }) formularioRegister!: Function|undefined
@Inject({ default: undefined }) formularioDeregister!: Function | undefined @Inject({ default: undefined }) formularioDeregister!: Function|undefined
@Inject({ default: () => () => ({}) }) getFormValues!: Function @Inject({ default: () => () => ({}) }) getFormValues!: Function
@Inject({ default: undefined }) observeErrors!: Function | undefined @Inject({ default: undefined }) observeErrors!: Function|undefined
@Inject({ default: undefined }) removeErrorObserver!: Function | undefined @Inject({ default: undefined }) removeErrorObserver!: Function|undefined
@Inject({ default: '' }) path!: string @Inject({ default: '' }) path!: string
@Provide() formularioRegisterRule = this.registerRule @Provide() formularioRegisterRule = this.registerRule
@ -69,10 +55,10 @@ export default class FormularioInput extends Vue {
@Prop({ @Prop({
type: [String, Number, Boolean], type: [String, Number, Boolean],
default: false, default: false,
}) id!: string | number | boolean }) id!: string|number|boolean
@Prop({ default: 'text' }) type!: string @Prop({ default: 'text' }) type!: string
@Prop({ required: true }) name: string | boolean @Prop({ required: true }) name: string|boolean
@Prop({ default: false }) value!: any @Prop({ default: false }) value!: any
@Prop({ @Prop({
@ -83,7 +69,7 @@ export default class FormularioInput extends Vue {
@Prop({ @Prop({
type: [String, Boolean], type: [String, Boolean],
default: false, default: false,
}) validationName!: string | boolean }) validationName!: string|boolean
@Prop({ @Prop({
type: Object, type: Object,
@ -98,7 +84,7 @@ export default class FormularioInput extends Vue {
@Prop({ @Prop({
type: [Array, String, Boolean], type: [Array, String, Boolean],
default: false, default: false,
}) errors!: [] | string | boolean }) errors!: []|string|boolean
@Prop({ @Prop({
type: String, type: String,
@ -108,9 +94,11 @@ export default class FormularioInput extends Vue {
@Prop({ default: false }) showErrors!: boolean @Prop({ default: false }) showErrors!: boolean
@Prop({ default: false }) disableErrors!: boolean @Prop({ default: false }) disableErrors!: boolean
@Prop({ default: false }) uploadUrl!: string | boolean
@Prop({ default: 'live' }) uploadBehavior!: string
@Prop({ default: true }) preventWindowDrops!: boolean @Prop({ default: true }) preventWindowDrops!: boolean
@Prop({ default: 'preview' }) imageBehavior!: string
@Prop({ default: false }) uploader!: Function|Object|boolean
@Prop({ default: false }) uploadUrl!: string|boolean
@Prop({ default: 'live' }) uploadBehavior!: string
defaultId: string = this.$formulario.nextId(this) defaultId: string = this.$formulario.nextId(this)
localAttributes: ObjectType = {} localAttributes: ObjectType = {}
@ -119,7 +107,7 @@ export default class FormularioInput extends Vue {
behavioralErrorVisibility: boolean = this.errorBehavior === 'live' behavioralErrorVisibility: boolean = this.errorBehavior === 'live'
formShouldShowErrors: boolean = false formShouldShowErrors: boolean = false
validationErrors: [] = [] validationErrors: [] = []
pendingValidation: Promise = Promise.resolve() pendingValidation: Promise<any> = Promise.resolve()
// These registries are used for injected messages registrants only (mostly internal). // These registries are used for injected messages registrants only (mostly internal).
ruleRegistry: [] = [] ruleRegistry: [] = []
messageRegistry: ObjectType = {} messageRegistry: ObjectType = {}

View File

@ -117,7 +117,7 @@ export default class Registry {
* @param {function} callback * @param {function} callback
* @param accumulator * @param accumulator
*/ */
reduce (callback: Function, accumulator: any) { reduce<U> (callback: Function, accumulator: U): U {
this.registry.forEach((component, field) => { this.registry.forEach((component, field) => {
accumulator = callback(accumulator, component, field) accumulator = callback(accumulator, component, field)
}) })