mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
143 lines
3.5 KiB
Vue
143 lines
3.5 KiB
Vue
<script setup lang="ts">
|
|
import { computed, reactive, ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useRouter } from 'vue-router'
|
|
|
|
import api from '@/api'
|
|
import { useDomains, useUsersAndGroups } from '@/composables/data'
|
|
import { useForm } from '@/composables/form'
|
|
import {
|
|
alphalownumdot_,
|
|
minLength,
|
|
name,
|
|
required,
|
|
sameAs,
|
|
unique,
|
|
} from '@/helpers/validators'
|
|
import { formatForm } from '@/helpers/yunohostArguments'
|
|
import type { FieldProps, FormFieldDict } from '@/types/form'
|
|
|
|
const { t } = useI18n()
|
|
const router = useRouter()
|
|
|
|
await api.fetchAll([
|
|
{ uri: 'users', cachePath: 'users' },
|
|
{ uri: 'domains', cachePath: 'domains' },
|
|
])
|
|
|
|
const { usernames } = useUsersAndGroups()
|
|
const { domainsAsChoices, mainDomain } = useDomains()
|
|
|
|
type Form = typeof form.value
|
|
const form = ref({
|
|
username: '',
|
|
fullname: '',
|
|
domain: mainDomain.value,
|
|
password: '',
|
|
confirmation: '',
|
|
})
|
|
const fields = {
|
|
username: reactive({
|
|
component: 'InputItem',
|
|
label: t('user_username'),
|
|
rules: computed(() => ({
|
|
required,
|
|
alphalownumdot_,
|
|
notInUsers: unique(usernames),
|
|
})),
|
|
cProps: {
|
|
id: 'username',
|
|
placeholder: t('placeholder.username'),
|
|
},
|
|
}) satisfies FieldProps<'InputItem', Form['username']>,
|
|
|
|
fullname: {
|
|
component: 'InputItem',
|
|
hr: true,
|
|
label: t('user_fullname'),
|
|
rules: { required, name },
|
|
cProps: {
|
|
id: 'fullname',
|
|
placeholder: t('placeholder.fullname'),
|
|
},
|
|
} satisfies FieldProps<'InputItem', Form['fullname']>,
|
|
|
|
domain: reactive({
|
|
component: 'SelectItem',
|
|
hr: true,
|
|
id: 'mail',
|
|
label: t('user_email'),
|
|
description: t('tip_about_user_email'),
|
|
descriptionVariant: 'info',
|
|
rules: { required },
|
|
cProps: { choices: domainsAsChoices },
|
|
}) satisfies FieldProps<'SelectItem', Form['domain']>,
|
|
|
|
password: {
|
|
component: 'InputItem',
|
|
label: t('password'),
|
|
description: t('good_practices_about_user_password'),
|
|
descriptionVariant: 'warning',
|
|
rules: { required, passwordLenght: minLength(8) },
|
|
cProps: {
|
|
id: 'password',
|
|
placeholder: '••••••••',
|
|
type: 'password',
|
|
},
|
|
} satisfies FieldProps<'InputItem', Form['password']>,
|
|
|
|
confirmation: reactive({
|
|
component: 'InputItem',
|
|
label: t('password_confirmation'),
|
|
rules: computed(() => ({
|
|
required,
|
|
passwordMatch: sameAs(form.value.password),
|
|
})),
|
|
cProps: {
|
|
id: 'confirmation',
|
|
placeholder: '••••••••',
|
|
type: 'password',
|
|
},
|
|
}) satisfies FieldProps<'InputItem', Form['confirmation']>,
|
|
} satisfies FormFieldDict<Form>
|
|
|
|
const { v, onSubmit } = useForm(form, fields)
|
|
|
|
const onUserCreate = onSubmit(async (onError) => {
|
|
const data = await formatForm(form)
|
|
api
|
|
.post({
|
|
uri: 'users',
|
|
cachePath: 'users',
|
|
data,
|
|
humanKey: { key: 'users.create', name: form.value.username },
|
|
})
|
|
.then(() => {
|
|
router.push({ name: 'user-list' })
|
|
})
|
|
.catch(onError)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<CardForm
|
|
v-model="form"
|
|
icon="user-plus"
|
|
:fields="fields"
|
|
:title="$t('users_new')"
|
|
:validations="v"
|
|
@submit.prevent="onUserCreate"
|
|
>
|
|
<template #component:domain="componentProps">
|
|
<BInputGroup>
|
|
<BInputGroupText id="local-part" tag="label" class="border-right-0">
|
|
{{ form.username }}@
|
|
</BInputGroupText>
|
|
|
|
<SelectItem v-bind="componentProps" v-model="form.domain" />
|
|
</BInputGroup>
|
|
</template>
|
|
</CardForm>
|
|
</div>
|
|
</template>
|