Fix UserImport validation and use component helpers in UserImport and UserList

(cherry picked from commit c80aad223e640d4d078c7cbe78acae3b0175b6fe)
This commit is contained in:
axolotle 2021-01-31 16:16:27 +01:00 committed by ljf
parent ada9a8d0b8
commit 5b6a1cdd74
4 changed files with 58 additions and 69 deletions

View file

@ -112,6 +112,11 @@ body {
top: 2px; top: 2px;
} }
// limit the size of toggle dropdown buttons to a square
.dropdown-toggle-split {
max-width: 2.5rem;
}
// Fork-awesome overrides // Fork-awesome overrides
.fa-fw { .fa-fw {
width: 1.25em !important; width: 1.25em !important;

View file

@ -146,6 +146,16 @@ export default {
return api.fetch('DELETE', param ? `${uri}/${param}` : uri, data, humanKey, options).then(() => { return api.fetch('DELETE', param ? `${uri}/${param}` : uri, data, humanKey, options).then(() => {
commit('DEL_' + storeKey.toUpperCase(), [param, extraParams].filter(item => !isEmptyValue(item))) commit('DEL_' + storeKey.toUpperCase(), [param, extraParams].filter(item => !isEmptyValue(item)))
}) })
},
'RESET_CACHE_DATA' ({ state }, keys = Object.keys(state)) {
for (const key of keys) {
if (key === 'users_details') {
state[key] = {}
} else {
state[key] = undefined
}
}
} }
}, },

View file

@ -1,47 +1,30 @@
<template> <template>
<div>
<card-form <card-form
:title="$t('users_import')" icon="user-plus" :title="$t('users_import')" icon="user-plus"
:validation="$v" :server-error="serverError" :validation="$v" :server-error="serverError"
@submit.prevent="beforeImport" @submit.prevent="onSubmit"
> >
<!-- CSV FILE --> <!-- CSV FILE -->
<form-field component="FileItem" v-bind="fields.csv" v-model="form.csv" <form-field v-bind="fields.csv" v-model="form.csv" :validation="$v.form.csv" />
:validation="$v.form.csv" accept=".csv" />
<!-- UPDATE --> <!-- UPDATE -->
<form-field component="CheckboxItem" v-bind="fields.update" v-model="form.update" <form-field v-bind="fields.update" v-model="form.update" />
:validation="$v.form.update" />
<!-- DELETE --> <!-- DELETE -->
<form-field component="CheckboxItem" v-bind="fields.delete" v-model="form.delete" <form-field v-bind="fields.delete" v-model="form.delete" />
:validation="$v.form.delete" />
</card-form> </card-form>
<!-- CONFIRM DESTRUCTIVE IMPORT MODAL -->
<b-modal
id="confirm-destructive-import-modal" ref="confirm-destructive-import-modal" centered
body-bg-variant="danger" body-text-variant="light"
@ok="onSubmit" hide-header
:ok-title="$t('users_import_delete_others')"
>
{{ $t('users_import_confirm_destructive') }}
</b-modal>
</div>
</template> </template>
<script> <script>
// import { mapGetters } from 'vuex' import api from '@/api'
import { validationMixin } from 'vuelidate' import { validationMixin } from 'vuelidate'
import { formatFormData } from '@/helpers/yunohostArguments' import { formatFormData } from '@/helpers/yunohostArguments'
import { import { required, fileMediaTypeMatch } from '@/helpers/validators'
required
} from '@/helpers/validators'
export default { export default {
name: 'UserImport', name: 'UserImport',
mixins: [validationMixin],
data () { data () {
return { return {
form: { form: {
@ -56,21 +39,26 @@ export default {
csv: { csv: {
label: this.$i18n.t('users_import_csv_file'), label: this.$i18n.t('users_import_csv_file'),
description: this.$i18n.t('users_import_csv_file_desc'), description: this.$i18n.t('users_import_csv_file_desc'),
component: 'FileItem',
props: { props: {
id: 'csv', id: 'csv',
placeholder: this.$i18n.t('placeholder.file') placeholder: this.$i18n.t('placeholder.file')
} }
}, },
update: { update: {
label: this.$i18n.t('users_import_update'), label: this.$i18n.t('users_import_update'),
description: this.$i18n.t('users_import_update_desc'), description: this.$i18n.t('users_import_update_desc'),
component: 'CheckboxItem',
props: { props: {
id: 'update' id: 'update'
} }
}, },
delete: { delete: {
label: this.$i18n.t('users_import_delete'), label: this.$i18n.t('users_import_delete'),
description: this.$i18n.t('users_import_delete_desc'), description: this.$i18n.t('users_import_delete_desc'),
component: 'CheckboxItem',
props: { props: {
id: 'delete' id: 'delete'
} }
@ -79,30 +67,26 @@ export default {
} }
}, },
validations () { validations: {
return {
form: { form: {
csv: { required }, csv: { required, fileMediaTypeMatch: fileMediaTypeMatch('text/csv') }
update: { },
delete: { }
}
} }
}, },
methods: { methods: {
beforeImport () { async onSubmit () {
if (this.form.delete) { if (this.form.delete) {
this.$refs['confirm-destructive-import-modal'].show() const confirmed = await this.$askConfirmation(
} else { this.$i18n.t('users_import_confirm_destructive'),
this.onSubmit() { okTitle: this.$i18n.t('users_import_delete_others') }
)
if (!confirmed) return
} }
},
onSubmit () { const data = formatFormData(this.form)
const data = formatFormData(this.form, { flatten: true }) api.post('users/import', data, { asFormData: true }).then(() => {
this.$store.dispatch( // Reset all cached data related to users.
'POST', { uri: 'users/import', data } this.$store.dispatch('RESET_CACHE_DATA', ['users', 'users_details', 'groups', 'permissions'])
).then(() => {
this.$router.push({ name: 'user-list' }) this.$router.push({ name: 'user-list' })
}).catch(error => { }).catch(error => {
this.serverError = error.message this.serverError = error.message
@ -110,7 +94,6 @@ export default {
} }
}, },
created () { mixins: [validationMixin]
}
} }
</script> </script>

View file

@ -8,34 +8,25 @@
> >
<template #top-bar-buttons> <template #top-bar-buttons>
<b-button variant="info" :to="{ name: 'group-list' }"> <b-button variant="info" :to="{ name: 'group-list' }">
<icon iname="key-modern" /> <icon iname="key-modern" /> {{ $t('groups_and_permissions_manage') }}
{{ $t('groups_and_permissions_manage') }}
</b-button> </b-button>
<div class="btn-group"> <b-dropdown
<b-dropdown split class="m-2" variant="success" :split-to="{ name: 'user-create' }"
:split-to="{name: 'user-create'}"> split variant="outline-success" right
split-variant="success"
>
<template #button-content> <template #button-content>
<icon iname="plus" /> <icon iname="plus" /> {{ $t('users_new') }}
{{ $t('users_new') }}
</template> </template>
<b-dropdown-item :to="{name: 'user-import'}"> <b-dropdown-item :to="{ name: 'user-import' }">
<icon iname="plus" /> {{ $t('users_import') }} <icon iname="plus" /> {{ $t('users_import') }}
</b-dropdown-item> </b-dropdown-item>
<b-dropdown-item @click="downloadExport"> <b-dropdown-item @click="downloadExport">
<icon iname="download" /> {{ $t('users_export') }} <icon iname="download" /> {{ $t('users_export') }}
</b-dropdown-item> </b-dropdown-item>
</b-dropdown> </b-dropdown>
</div>
</div>
</div>
<template v-if="users === null">
<b-alert variant="warning" show>
<icon iname="exclamation-triangle" class="fa-fw mr-1" />
{{ $t('users_no') }}
</b-alert>
</template> </template>
<b-list-group> <b-list-group>