update ToolWebAdmin and AppInstall with validations

This commit is contained in:
Axolotle 2020-11-01 17:03:06 +01:00
parent 7a2d8017f3
commit 6e5d11ce36
9 changed files with 99 additions and 139 deletions

View file

@ -30,7 +30,9 @@ async function _getResponseContent (response) {
* @return {(Object|String)} Parsed response's json, response's text or an error. * @return {(Object|String)} Parsed response's json, response's text or an error.
*/ */
export function handleResponse (response, method) { export function handleResponse (response, method) {
if (method !== 'GET') {
store.dispatch('SERVER_RESPONDED', response.ok) store.dispatch('SERVER_RESPONDED', response.ok)
}
if (!response.ok) return handleError(response, method) if (!response.ok) return handleError(response, method)
// FIXME the api should always return json objects // FIXME the api should always return json objects
return _getResponseContent(response) return _getResponseContent(response)
@ -43,7 +45,6 @@ export function handleResponse (response, method) {
* @throws Will throw a custom error with response data. * @throws Will throw a custom error with response data.
*/ */
export async function handleError (response, method) { export async function handleError (response, method) {
console.log(response.url)
const message = await _getResponseContent(response) const message = await _getResponseContent(response)
const errorCode = response.status in errors ? response.status : undefined const errorCode = response.status in errors ? response.status : undefined
const error = new errors[errorCode](method, response, message) const error = new errors[errorCode](method, response, message)

View file

@ -1,10 +1,10 @@
<template> <template>
<b-card class="card-form"> <b-card class="card-form">
<template v-slot:header> <template v-slot:header>
<h2><icon v-if="icon" :iname="icon" /> {{ title }}</h2> <component :is="titleTag"><icon v-if="icon" :iname="icon" /> {{ title }}</component>
</template> </template>
<slot name="disclaimer"></slot> <slot name="disclaimer" />
<b-form :id="id" @submit.prevent="onSubmit" novalidate> <b-form :id="id" @submit.prevent="onSubmit" novalidate>
<slot name="default" /> <slot name="default" />
@ -35,6 +35,7 @@ export default {
props: { props: {
id: { type: String, default: 'ynh-form' }, id: { type: String, default: 'ynh-form' },
title: { type: String, required: true }, title: { type: String, required: true },
titleTag: { type: String, default: 'h2' },
icon: { type: String, default: null }, icon: { type: String, default: null },
submitText: { type: String, default: null }, submitText: { type: String, default: null },
noFooter: { type: Boolean, default: false }, noFooter: { type: Boolean, default: false },

View file

@ -71,10 +71,14 @@ export default {
'label-cols-lg': 2, 'label-cols-lg': 2,
'label-class': 'font-weight-bold' 'label-class': 'font-weight-bold'
} }
if ('label-cols' in attrs) {
attrs['label-class'] = defaultAttrs['label-class']
} else {
for (const attr in defaultAttrs) { for (const attr in defaultAttrs) {
if (!(attr in attrs)) attrs[attr] = defaultAttrs[attr] if (!(attr in attrs)) attrs[attr] = defaultAttrs[attr]
} }
} }
}
return attrs return attrs
}, },

View file

@ -6,7 +6,7 @@
:aria-describedby="$parent.id + '__BV_description_'" :aria-describedby="$parent.id + '__BV_description_'"
switch switch
> >
{{ $t(checked ? 'yes' : 'no') }} {{ $t(labels[checked]) }}
</b-checkbox> </b-checkbox>
</template> </template>
@ -16,7 +16,8 @@ export default {
props: { props: {
value: { type: Boolean, required: true }, value: { type: Boolean, required: true },
id: { type: String, default: null } id: { type: String, default: null },
labels: { type: Object, default: () => ({ true: 'yes', false: 'no' }) }
}, },
data () { data () {

View file

@ -63,7 +63,7 @@ export function isObjectLiteral (value) {
* @return {Boolean} * @return {Boolean}
*/ */
export function isEmptyValue (value) { export function isEmptyValue (value) {
if (value === 0) return false if (typeof value === 'number') return false
return !value || value.length === 0 || Object.keys(value).length === 0 return !value || value.length === 0 || Object.keys(value).length === 0
} }

View file

@ -79,7 +79,7 @@ function initDefaultLocales () {
const [locale, fallbackLocale] = getDefaultLocales() const [locale, fallbackLocale] = getDefaultLocales()
store.dispatch('UPDATE_LOCALE', locale) store.dispatch('UPDATE_LOCALE', locale)
store.dispatch('UPDATE_FALLBACK_LOCALE', fallbackLocale || 'en') store.dispatch('UPDATE_FALLBACKLOCALE', fallbackLocale || 'en')
loadLocaleMessages('en') loadLocaleMessages('en')
} }

View file

@ -23,7 +23,7 @@ export default {
state.locale = locale state.locale = locale
}, },
'SET_FALLBACK_LOCALE' (state, locale) { 'SET_FALLBACKLOCALE' (state, locale) {
localStorage.setItem('fallbackLocale', locale) localStorage.setItem('fallbackLocale', locale)
state.fallbackLocale = locale state.fallbackLocale = locale
}, },
@ -55,9 +55,9 @@ export default {
loadDateFnsLocale(locale) loadDateFnsLocale(locale)
}, },
'UPDATE_FALLBACK_LOCALE' ({ commit }, locale) { 'UPDATE_FALLBACKLOCALE' ({ commit }, locale) {
loadLocaleMessages(locale).then(() => { loadLocaleMessages(locale).then(() => {
commit('SET_FALLBACK_LOCALE', locale) commit('SET_FALLBACKLOCALE', locale)
i18n.fallbackLocale = [locale, 'en'] i18n.fallbackLocale = [locale, 'en']
}) })
} }

View file

@ -22,8 +22,8 @@
</b-card> </b-card>
<!-- INSTALL FORM --> <!-- INSTALL FORM -->
<basic-form <card-form
:title="$t('operations')" icon="wrench" :title="$t('operations')" icon="wrench" :submit-text="$t('install')"
:validation="$v" :server-error="serverError" :validation="$v" :server-error="serverError"
@submit.prevent="beforeInstall" @submit.prevent="beforeInstall"
> >
@ -32,12 +32,10 @@
</template> </template>
<form-field <form-field
v-for="(field, fname) in fields" :key="fname" v-for="(field, fname) in fields" :key="fname" label-cols="0"
v-bind="field" v-model="form[fname]" v-bind="field" v-model="form[fname]" :validation="$v.form[fname]"
:validation="$v.form[fname]"
/> />
</card-form>
</basic-form>
<!-- CONFIRM INSTALL DOMAIN ROOT MODAL --> <!-- CONFIRM INSTALL DOMAIN ROOT MODAL -->
<b-modal <b-modal

View file

@ -1,140 +1,95 @@
<template> <template>
<basic-form :header="$t('tools_webadmin_settings')" @submit.prevent="onSubmit" no-footer> <card-form
<!-- LOCALE --> :title="$t('tools_webadmin_settings')" icon="cog"
<b-form-group no-footer
label-cols-md="4" label-cols-lg="2" label-class="font-weight-bold"
:label="$t('tools_webadmin.locale')" label-for="locale"
> >
<b-select <template v-for="(field, fname) in fields">
id="locale" <form-field
:options="availableLocales" v-bind="field" v-model="self[fname]" :key="fname"
v-model="currentLocale"
/> />
</b-form-group> <hr :key="fname + 'hr'">
<hr>
<!-- FALLBACK LOCALE -->
<b-form-group
label-cols-md="4" label-cols-lg="2" label-class="font-weight-bold"
:label="$t('tools_webadmin.fallback_locale')" label-for="fallback-locale"
>
<b-select
id="fallback-locale"
:options="availableLocales"
v-model="currentFallbackLocale"
/>
</b-form-group>
<hr>
<!-- CACHE -->
<b-form-group
label-cols-md="4" label-cols-lg="2"
:label="$t('tools_webadmin.cache')" label-for="cache" label-class="font-weight-bold"
>
<b-checkbox v-model="currentCache" id="cache" switch>
{{ $t(currentCache ? 'enabled' : 'disabled') }}
</b-checkbox>
<template v-slot:description>
{{ $t('tools_webadmin.cache_description') }}
</template> </template>
</b-form-group> </card-form>
<hr>
<!-- TRANSITIONS -->
<b-form-group
label-cols-md="4" label-cols-lg="2"
:label="$t('tools_webadmin.transitions')" label-for="transitions" label-class="font-weight-bold"
>
<b-checkbox v-model="currentTransitions" id="transitions" switch>
{{ $t(currentTransitions ? 'enabled' : 'disabled') }}
</b-checkbox>
</b-form-group>
<hr>
<!-- EXPERIMENTAL MODE (dev environment only)-->
<b-form-group
v-if="isDev"
label-cols-md="4" label-cols-lg="2" label-class="font-weight-bold"
label-for="experimental"
>
<template v-slot:label>
{{ $t('tools_webadmin.experimental') }}
<icon iname="flask" />
</template>
<b-checkbox v-model="currentExperimental" id="experimental" switch>
{{ $t(currentExperimental ? 'enabled' : 'disabled') }}
</b-checkbox>
<template v-slot:description>
<span v-html="$t('tools_webadmin.experimental_description')" />
</template>
</b-form-group>
</basic-form>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' // FIXME move into helpers ?
import BasicForm from '@/components/BasicForm' // Dynamicly generate computed properties from store with get/set and automatic commit/dispatch
function mapStoreGetSet (props = [], action = 'commit') {
return props.reduce((obj, prop) => {
obj[prop] = {
get () {
return this.$store.getters[prop]
},
set (value) {
const key = (action === 'commit' ? 'SET_' : 'UPDATE_') + prop.toUpperCase()
this.$store[action](key, value)
}
}
return obj
}, {})
}
export default { export default {
name: 'ToolWebadmin', name: 'ToolWebadmin',
data () {
return {
// Hacky way to be able to dynamicly point to a computed property `self['computedProp']`
self: this,
fields: {
locale: {
label: this.$i18n.t('tools_webadmin.locale'),
component: 'SelectItem',
props: { id: 'locale', choices: [] }
},
fallbackLocale: {
label: this.$i18n.t('tools_webadmin.fallback_locale'),
component: 'SelectItem',
props: { id: 'fallback-locale', choices: [] }
},
cache: {
id: 'cache',
label: this.$i18n.t('tools_webadmin.cache'),
description: this.$i18n.t('tools_webadmin.cache_description'),
component: 'CheckboxItem',
props: { labels: { true: 'enabled', false: 'disabled' } }
},
transitions: {
id: 'transitions',
label: this.$i18n.t('tools_webadmin.transitions'),
component: 'CheckboxItem',
props: { labels: { true: 'enabled', false: 'disabled' } }
}
// experimental: added in `created()`
}
}
},
computed: { computed: {
...mapGetters([ // Those are set/get computed properties
'locale', ...mapStoreGetSet(['locale', 'fallbackLocale'], 'dispatch'),
'fallbackLocale', ...mapStoreGetSet(['cache', 'transitions', 'experimental'])
'cache',
'transitions',
'experimental',
'availableLocales'
]),
currentLocale: {
get: function () { return this.locale },
set: function (newValue) {
this.$store.dispatch('UPDATE_LOCALE', newValue)
}
}, },
currentFallbackLocale: { created () {
get: function () { return this.fallbackLocale }, const availableLocales = this.$store.getters.availableLocales
set: function (newValue) { this.fields.locale.props.choices = availableLocales
this.$store.dispatch('UPDATE_FALLBACK_LOCALE', newValue) this.fields.fallbackLocale.props.choices = availableLocales
} if (process.env.NODE_ENV === 'development') {
}, this.fields.experimental = {
id: 'experimental',
currentCache: { label: this.$i18n.t('tools_webadmin.experimental'),
get: function () { return this.cache }, description: this.$i18n.t('tools_webadmin.experimental_description'),
set: function (newValue) { component: 'CheckboxItem',
this.$store.commit('SET_CACHE', newValue) props: { labels: { true: 'enabled', false: 'disabled' } }
}
},
currentTransitions: {
get: function () { return this.transitions },
set: function (newValue) {
this.$store.commit('SET_TRANSITIONS', newValue)
}
},
// environment
isDev () {
return process.env.NODE_ENV === 'development'
},
// Only available in 'development' environment.
currentExperimental: {
get: function () { return this.experimental },
set: function (newValue) {
this.$store.commit('SET_EXPERIMENTAL', newValue)
} }
} }
},
components: {
BasicForm
} }
} }
</script> </script>