mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
[enh] Add Import user view
This commit is contained in:
parent
d90cc05d58
commit
f2dbbe91d0
5 changed files with 171 additions and 9 deletions
|
@ -38,8 +38,8 @@ import { openWebSocket, getResponseData, handleError } from './handlers'
|
|||
* @param {Boolean} [options.addLocale=false] - Option to append the locale to the query string.
|
||||
* @return {URLSearchParams}
|
||||
*/
|
||||
export function objectToParams (obj, { addLocale = false } = {}) {
|
||||
const urlParams = new URLSearchParams()
|
||||
export function objectToParams (obj, { addLocale = false } = {}, formData = false) {
|
||||
const urlParams = (formData) ? new FormData() : new URLSearchParams()
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => urlParams.append(key, v))
|
||||
|
@ -96,14 +96,9 @@ export default {
|
|||
if (method === 'GET') {
|
||||
uri += `${uri.includes('?') ? '&' : '?'}locale=${store.getters.locale}`
|
||||
} else {
|
||||
options = { ...options, method, body: objectToParams(data, { addLocale: true }) }
|
||||
options = { ...options, method, body: objectToParams(data, { addLocale: true }, true) }
|
||||
}
|
||||
|
||||
const response = await fetch('/yunohost/api/' + uri, options)
|
||||
const responseData = await getResponseData(response)
|
||||
store.dispatch('END_REQUEST', { request, success: response.ok, wait })
|
||||
|
||||
return response.ok ? responseData : handleError(request, response, responseData)
|
||||
},
|
||||
|
||||
|
||||
|
|
31
app/src/components/globals/formItems/FileItem.vue
Normal file
31
app/src/components/globals/formItems/FileItem.vue
Normal file
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<b-form-file
|
||||
:id="id"
|
||||
v-model="file"
|
||||
v-on="$listeners"
|
||||
:placeholder="placeholder"
|
||||
:drop-placeholder="dropPlaceholder"
|
||||
:state="Boolean(file)"
|
||||
:required="required"
|
||||
:accept="accept"
|
||||
@blur="$parent.$emit('touch', name)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FileItem',
|
||||
data () {
|
||||
return { file: null }
|
||||
},
|
||||
props: {
|
||||
id: { type: String, default: null },
|
||||
placeholder: { type: String, default: null },
|
||||
dropPlaceholder: { type: String, default: null },
|
||||
required: { type: Boolean, default: false },
|
||||
state: { type: Boolean, default: null },
|
||||
name: { type: String, default: null },
|
||||
accept: { type: String, default: null }
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -293,7 +293,8 @@
|
|||
"firstname": "John",
|
||||
"lastname": "Doe",
|
||||
"groupname": "My group name",
|
||||
"domain": "my-domain.com"
|
||||
"domain": "my-domain.com",
|
||||
"file": "Browse a file or drag and drop it"
|
||||
},
|
||||
"logs": "Logs",
|
||||
"logs_suboperations": "Sub-operations",
|
||||
|
@ -489,6 +490,15 @@
|
|||
"users": "Users",
|
||||
"users_new": "New user",
|
||||
"users_no": "No users.",
|
||||
"users_import": "Import users",
|
||||
"users_import_csv_file": "CSV File",
|
||||
"users_import_update": "Update existing users",
|
||||
"users_import_delete": "Delete non listed users",
|
||||
"users_import_csv_file_desc": "The CSV file should be in UTF-8 and with columns username, password, groups, email and quota. See <a href=''>example import csv file</a>.",
|
||||
"users_import_update_desc": "If checked, all existing users contained in the csv file will be updated with the ne new value",
|
||||
"users_import_delete_desc": "If checked, all existing users that are not in the csv file will be deleted (and purged).",
|
||||
"users_import_confirm_destructive": "Are you sure you want to delete users that are not present in this file?",
|
||||
"users_import_delete_others": "Delete unlisted users",
|
||||
"version": "Version",
|
||||
"warnings": "{count} warnings",
|
||||
"words": {
|
||||
|
|
|
@ -60,6 +60,16 @@ const routes = [
|
|||
breadcrumb: ['user-list', 'user-create']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'user-import',
|
||||
path: '/users/import',
|
||||
component: () => import(/* webpackChunkName: "views/user/import" */ '@/views/user/UserImport'),
|
||||
props: true,
|
||||
meta: {
|
||||
args: { param: 'name' },
|
||||
breadcrumb: ['user-list', 'user-import']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'user-info',
|
||||
path: '/users/:name',
|
||||
|
|
116
app/src/views/user/UserImport.vue
Normal file
116
app/src/views/user/UserImport.vue
Normal file
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<div>
|
||||
<card-form
|
||||
:title="$t('users_import')" icon="user-plus"
|
||||
:validation="$v" :server-error="serverError"
|
||||
@submit.prevent="beforeImport"
|
||||
>
|
||||
<!-- CSV FILE -->
|
||||
<form-field component="FileItem" v-bind="fields.csv" v-model="form.csv"
|
||||
:validation="$v.form.csv" accept=".csv" />
|
||||
<!-- UPDATE -->
|
||||
<form-field component="CheckboxItem" v-bind="fields.update" v-model="form.update"
|
||||
:validation="$v.form.update" />
|
||||
<!-- DELETE -->
|
||||
<form-field component="CheckboxItem" v-bind="fields.delete" v-model="form.delete"
|
||||
:validation="$v.form.delete" />
|
||||
</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>
|
||||
|
||||
<script>
|
||||
// import { mapGetters } from 'vuex'
|
||||
import { validationMixin } from 'vuelidate'
|
||||
|
||||
import { formatFormData } from '@/helpers/yunohostArguments'
|
||||
import {
|
||||
required
|
||||
} from '@/helpers/validators'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'UserImport',
|
||||
|
||||
mixins: [validationMixin],
|
||||
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
csv: '',
|
||||
update: false,
|
||||
delete: false
|
||||
},
|
||||
|
||||
serverError: '',
|
||||
|
||||
fields: {
|
||||
csv: {
|
||||
label: this.$i18n.t('users_import_csv_file'),
|
||||
description: this.$i18n.t('users_import_csv_file_desc'),
|
||||
props: {
|
||||
id: 'csv',
|
||||
placeholder: this.$i18n.t('placeholder.file')
|
||||
}
|
||||
},
|
||||
update: {
|
||||
label: this.$i18n.t('users_import_update'),
|
||||
description: this.$i18n.t('users_import_update_desc'),
|
||||
props: {
|
||||
id: 'update'
|
||||
}
|
||||
},
|
||||
delete: {
|
||||
label: this.$i18n.t('users_import_delete'),
|
||||
description: this.$i18n.t('users_import_delete_desc'),
|
||||
props: {
|
||||
id: 'delete'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validations () {
|
||||
return {
|
||||
form: {
|
||||
csv: { required },
|
||||
update: { },
|
||||
delete: { }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
beforeImport () {
|
||||
if (this.form.delete) {
|
||||
this.$refs['confirm-destructive-import-modal'].show()
|
||||
} else {
|
||||
this.onSubmit()
|
||||
}
|
||||
},
|
||||
|
||||
onSubmit () {
|
||||
const data = formatFormData(this.form, { flatten: true })
|
||||
this.$store.dispatch(
|
||||
'POST', { uri: 'users/import', data }
|
||||
).then(() => {
|
||||
this.$router.push({ name: 'user-list' })
|
||||
}).catch(error => {
|
||||
this.serverError = error.message
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in a new issue