Fix AppConfigPanel and use helper components

This commit is contained in:
axolotle 2021-02-19 18:56:26 +01:00
parent 7c8dd388d8
commit 562fd3d1fe
3 changed files with 57 additions and 53 deletions

View file

@ -89,4 +89,7 @@ export default {
margin-left: .5rem; margin-left: .5rem;
} }
} }
.collapse:not(.show) + .card-footer {
display: none;
}
</style> </style>

View file

@ -88,7 +88,11 @@ export function formatYunoHostArgument (arg) {
// Checkbox // Checkbox
} else if (arg.type === 'boolean') { } else if (arg.type === 'boolean') {
field.component = 'CheckboxItem' field.component = 'CheckboxItem'
if (typeof arg.default === 'number') {
value = arg.default === 1
} else {
value = arg.default || false value = arg.default || false
}
// Special (store related) // Special (store related)
} else if (['user', 'domain'].includes(arg.type)) { } else if (['user', 'domain'].includes(arg.type)) {
field.component = 'SelectItem' field.component = 'SelectItem'
@ -106,8 +110,8 @@ export function formatYunoHostArgument (arg) {
if (field.component !== 'CheckboxItem' && arg.optional !== true) { if (field.component !== 'CheckboxItem' && arg.optional !== true) {
validation.required = validators.required validation.required = validators.required
} }
// Default value // Default value if still `null`
if (arg.default) { if (value === null && arg.default) {
value = arg.default value = arg.default
} }
// Help message // Help message

View file

@ -5,37 +5,26 @@
<icon iname="exclamation-triangle" /> {{ $t('experimental_warning') }} <icon iname="exclamation-triangle" /> {{ $t('experimental_warning') }}
</b-alert> </b-alert>
<!-- FIXME Rework with components --> <card-form
<b-form id="config-form" @submit.prevent="applyConfig"> v-for="{ name, id: id_, sections, help, serverError } in panels" :key="id_"
<b-card no-body v-for="panel in panels" :key="panel.id"> :title="name" icon="wrench" title-tag="h4"
<b-card-header class="d-flex align-items-center"> :validation="$v.forms[id_]" :id="id_ + '-form'" :server-error="serverError"
<h2>{{ panel.name }} <small v-if="panel.help">{{ panel.help }}</small></h2> collapsable
@submit.prevent="applyConfig(id_)"
>
<template v-if="help" #disclaimer>
<div class="alert alert-info" v-html="help" />
</template>
<div class="ml-auto"> <div v-for="section in sections" :key="section.id" class="mb-5">
<b-button v-b-toggle="[panel.id + '-collapse', panel.id + '-collapse-footer']" size="sm" variant="outline-secondary">
<icon iname="chevron-right" /><span class="sr-only">{{ $t('words.collapse') }}</span>
</b-button>
</div>
</b-card-header>
<b-collapse :id="panel.id + '-collapse'" visible>
<b-card-body v-for="section in panel.sections" :key="section.id">
<b-card-title>{{ section.name }} <small v-if="section.help">{{ section.help }}</small></b-card-title> <b-card-title>{{ section.name }} <small v-if="section.help">{{ section.help }}</small></b-card-title>
<form-item-helper v-for="arg in section.args" :key="arg.name" v-bind="arg" /> <form-field
</b-card-body> v-for="(field, fname) in section.fields" :key="fname" label-cols="0"
</b-collapse> v-bind="field" v-model="forms[id_][fname]" :validation="$v.forms[id_][fname]"
<b-collapse :id="panel.id + '-collapse-footer'" visible>
<b-card-footer>
<b-button
type="submit" form="config-form"
variant="success" class="ml-auto" v-t="'save'"
/> />
</b-card-footer> </div>
</b-collapse> </card-form>
</b-card>
</b-form>
</template> </template>
<!-- if no config panel --> <!-- if no config panel -->
@ -46,14 +35,18 @@
</template> </template>
<script> <script>
import { validationMixin } from 'vuelidate'
// FIXME needs test and rework // FIXME needs test and rework
import api from '@/api' import api from '@/api'
import { formatI18nField, formatYunoHostArgument } from '@/helpers/yunohostArguments' import { formatI18nField, formatYunoHostArguments, formatFormData } from '@/helpers/yunohostArguments'
import { objectToParams } from '@/helpers/commons' import { objectToParams } from '@/helpers/commons'
export default { export default {
name: 'AppConfigPanel', name: 'AppConfigPanel',
mixins: [validationMixin],
props: { props: {
id: { type: String, required: true } id: { type: String, required: true }
}, },
@ -66,10 +59,16 @@ export default {
['GET', { uri: 'domains/main', storeKey: 'main_domain' }], ['GET', { uri: 'domains/main', storeKey: 'main_domain' }],
['GET', { uri: 'users' }] ['GET', { uri: 'users' }]
], ],
panels: undefined panels: undefined,
forms: undefined,
validations: null
} }
}, },
validations () {
return this.validations
},
methods: { methods: {
onQueriesResponse (data) { onQueriesResponse (data) {
if (!data.config_panel || data.config_panel.length === 0) { if (!data.config_panel || data.config_panel.length === 0) {
@ -77,41 +76,39 @@ export default {
return return
} }
const forms = {}
const validations_ = {}
const panels_ = [] const panels_ = []
for (const { id, name, help, sections } of data.config_panel.panel) { for (const { id, name, help, sections } of data.config_panel.panel) {
const panel_ = { id, name, sections: [] } const panel_ = { id, name, sections: [] }
if (help) panel_.help = formatI18nField(help) if (help) panel_.help = formatI18nField(help)
forms[id] = {}
validations_[id] = {}
for (const { name, help, options } of sections) { for (const { name, help, options } of sections) {
const section_ = { name } const section_ = { name }
if (help) section_.help = formatI18nField(help) if (help) section_.help = formatI18nField(help)
section_.args = options.map(option => formatYunoHostArgument(option)) const { form, fields, validations } = formatYunoHostArguments(options)
panel_.sections.push(section_) Object.assign(forms[id], form)
Object.assign(validations_[id], validations)
panel_.sections.push({ name, fields })
} }
panels_.push(panel_) panels_.push(panel_)
} }
this.forms = forms
this.validations = { forms: validations_ }
this.panels = panels_ this.panels = panels_
}, },
applyConfig () { applyConfig (id_) {
// FIXME not tested const args = objectToParams(formatFormData(this.forms[id_]))
const args = {}
for (const panel of this.panels) {
for (const section of panel.sections) {
for (const arg of section.args) {
if (arg.component === 'CheckboxItem') {
args[arg.props.id] = arg.props.value ? 1 : 0
} else {
args[arg.props.id] = arg.props.value
}
}
}
}
// FIXME not tested at all, route is currently broken api.post(`apps/${this.id}/config`, { args }).then(response => {
api.post(`apps/${this.id}/config`, { args: objectToParams(args) }).then(response => {
console.log('SUCCESS', response) console.log('SUCCESS', response)
}).catch(err => { }).catch(err => {
console.log('ERROR', err) if (err.name !== 'APIBadRequestError') throw err
const panel = this.panels.find(({ id }) => id_ === id)
this.$set(panel, 'serverError', err.message)
}) })
} }
} }