Refactor to use FormSchema

That way we can re-use the code for slug validation in the
CreateUserAccount component
This commit is contained in:
roschaefer 2019-09-20 00:42:09 +02:00
parent efe9c96edb
commit be6c4a6f7c
2 changed files with 86 additions and 65 deletions

View File

@ -0,0 +1,30 @@
import { debounce } from 'lodash'
import { checkSlugAvailableQuery } from '~/graphql/User.js'
export default function UniqueSlugForm({ translate, apollo, currentUser }) {
return {
formSchema: {
slug: [
{
asyncValidator(rule, value, callback) {
debounce(() => {
const variables = { slug: value }
apollo.query({ query: checkSlugAvailableQuery, variables }).then(response => {
const {
data: { User },
} = response
const existingSlug = User && User[0] && User[0].slug
const available = !existingSlug || existingSlug === currentUser.slug
if (!available) {
callback(new Error(translate('settings.validation.slug.alreadyTaken')))
} else {
callback()
}
})
}, 500)()
},
},
],
},
}
}

View File

@ -1,56 +1,49 @@
<template>
<ds-form v-model="form" @submit="submit">
<ds-card :header="$t('settings.data.name')">
<ds-input
id="name"
model="name"
icon="user"
:label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')"
/>
<ds-input
id="slug"
model="slug"
icon="at"
:label="$t('settings.data.labelSlug')"
@input.native="validateSlug"
/>
<ds-text v-if="!slugAvailable" color="danger">
{{ $t('settings.validation.slug.alreadyTaken') }}
</ds-text>
<!-- eslint-disable vue/use-v-on-exact -->
<ds-select
id="city"
model="locationName"
icon="map-marker"
:options="cities"
:label="$t('settings.data.labelCity')"
:placeholder="$t('settings.data.labelCity')"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
<!-- eslint-enable vue/use-v-on-exact -->
<ds-input
id="bio"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<template slot="footer">
<ds-button
style="float: right;"
icon="check"
:disabled="!slugAvailable"
type="submit"
:loading="loadingData"
primary
>
{{ $t('actions.save') }}
</ds-button>
</template>
</ds-card>
<ds-form v-model="form" :schema="formSchema" @submit="submit">
<template slot-scope="{ errors }">
<ds-card :header="$t('settings.data.name')">
<ds-input
id="name"
model="name"
icon="user"
:label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')"
/>
<ds-input id="slug" model="slug" icon="at" :label="$t('settings.data.labelSlug')" />
<!-- eslint-disable vue/use-v-on-exact -->
<ds-select
id="city"
model="locationName"
icon="map-marker"
:options="cities"
:label="$t('settings.data.labelCity')"
:placeholder="$t('settings.data.labelCity')"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
<!-- eslint-enable vue/use-v-on-exact -->
<ds-input
id="bio"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<template slot="footer">
<ds-button
style="float: right;"
icon="check"
:disabled="errors"
type="submit"
:loading="loadingData"
primary
>
{{ $t('actions.save') }}
</ds-button>
</template>
</ds-card>
</template>
</ds-form>
</template>
@ -59,8 +52,7 @@ import gql from 'graphql-tag'
import { mapGetters, mapMutations } from 'vuex'
import { CancelToken } from 'axios'
import { checkSlugAvailableQuery } from '~/graphql/User.js'
import { debounce } from 'lodash'
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
let timeout
const mapboxToken = process.env.MAPBOX_TOKEN
@ -98,13 +90,22 @@ export default {
loadingData: false,
loadingGeo: false,
formData: {},
slugAvailable: true,
}
},
computed: {
...mapGetters({
currentUser: 'auth/user',
}),
formSchema() {
const uniqueSlugForm = UniqueSlugForm({
apollo: this.$apollo,
currentUser: this.currentUser,
translate: this.$t,
})
return {
...uniqueSlugForm.formSchema,
}
},
form: {
get: function() {
const { name, slug, locationName, about } = this.currentUser
@ -115,16 +116,6 @@ export default {
},
},
},
created() {
this.validateSlug = debounce(async () => {
const variables = { slug: this.formData.slug }
const {
data: { User },
} = await this.$apollo.query({ query: checkSlugAvailableQuery, variables })
const existingSlug = User && User[0] && User[0].slug
this.slugAvailable = !existingSlug || existingSlug === this.currentUser.slug
}, 500)
},
methods: {
...mapMutations({
setCurrentUser: 'auth/SET_USER',