Improve user add form validation

This commit is contained in:
Johannes Zellner
2025-11-13 16:09:33 +01:00
parent cc30bc1897
commit 181ee43107
+19 -15
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, useTemplateRef, inject } from 'vue';
import { Dialog, TextInput, FormGroup, Checkbox, MultiSelect, SingleSelect } from '@cloudron/pankow';
import { Dialog, TextInput, EmailInput, FormGroup, Checkbox, MultiSelect, SingleSelect } from '@cloudron/pankow';
import { ROLES } from '../constants.js';
import ImagePicker from '../components/ImagePicker.vue';
import DashboardModel from '../models/DashboardModel.js';
@@ -66,6 +66,11 @@ function onAvatarChanged(file) {
avatarFile = file;
}
const isFormValid = ref(false);
function validateForm() {
isFormValid.value = form.value && form.value.checkValidity();
}
async function onSubmit() {
if (!form.value.reportValidity()) return;
@@ -231,7 +236,7 @@ defineExpose({
:title="user ? $t('users.editUserDialog.title') : $t('users.addUserDialog.title')"
:confirm-label="user ? $t('main.dialog.save') : $t('users.addUserDialog.addUserAction')"
:confirm-busy="busy"
:confirm-active="!busy"
:confirm-active="!busy && isFormValid"
reject-style="secondary"
:reject-label="$t('main.dialog.cancel')"
:reject-active="!busy"
@@ -241,13 +246,9 @@ defineExpose({
@alternate="onReset2FA()"
@confirm="onSubmit()"
>
<p class="text-warning" v-if="user && user.source">{{ $t('users.editUserDialog.externalLdapWarning') }}</p>
<div class="text-danger" v-if="formError.generic">{{ formError.generic }}</div>
<form @submit.prevent="onSubmit()" autocomplete="off" ref="form">
<form @submit.prevent="onSubmit()" autocomplete="off" ref="form" @input="validateForm()">
<fieldset :disabled="busy">
<input type="submit" style="display: none;" />
<input type="submit" style="display: none;" :disabled="!isFormValid" />
<div style="display: flex; justify-content: center;">
<div style="width: 80px;">
@@ -255,18 +256,21 @@ defineExpose({
</div>
</div>
<!-- if profile edit is locked a user has to be set here . username is editable until one is set -->
<div class="text-warning" v-if="user && user.source">{{ $t('users.editUserDialog.externalLdapWarning') }}</div>
<div class="error-label" v-if="formError.generic">{{ formError.generic }}</div>
<!-- if profile edit is locked a username has to be set here . username is editable until one is set -->
<FormGroup :has-error="formError.username">
<label for="usernameInput">{{ $t('users.user.username') }}</label>
<TextInput id="usernameInput" v-model="username" :required="profileLocked ? true : null" :readonly="user?.username ? true : undefined" />
<small v-if="!user?.username && !profileLocked" class="helper-text">{{ $t('users.user.usernamePlaceholder') }}</small>
<div class="text-danger" v-if="formError.username">{{ formError.username }}</div>
<div class="error-label" v-if="formError.username">{{ formError.username }}</div>
</FormGroup>
<FormGroup>
<label for="emailInput" :has-error="formError.email">{{ $t('users.user.primaryEmail') }} <sup><a href="https://docs.cloudron.io/profile/#primary-email" class="help" target="_blank" tabindex="-1"><i class="fa fa-question-circle"></i></a></sup></label>
<TextInput id="emailInput" v-model="email" :readonly="(user && user.source) ? true : undefined" required />
<div class="text-danger" v-if="formError.email">{{ formError.email }}</div>
<EmailInput id="emailInput" v-model="email" :readonly="(user && user.source) ? true : undefined" required />
<div class="error-label" v-if="formError.email">{{ formError.email }}</div>
</FormGroup>
<FormGroup style="flex-grow: 1">
@@ -277,14 +281,14 @@ defineExpose({
<FormGroup>
<label for="fallbackEmailInput">{{ $t('users.user.recoveryEmail') }} <sup><a href="https://docs.cloudron.io/profile/#password-recovery-email" class="help" target="_blank" tabindex="-1"><i class="fa fa-question-circle"></i></a></sup></label>
<TextInput id="fallbackEmailInput" v-model="fallbackEmail" />
<EmailInput id="fallbackEmailInput" v-model="fallbackEmail" />
<small class="helper-text">{{ $t('users.user.fallbackEmailPlaceholder') }}</small>
</FormGroup>
<FormGroup v-if="profile.isAtLeastAdmin" :has-error="formError.role">
<label for="roleInput">{{ $t('users.user.role') }} <sup><a href="https://docs.cloudron.io/user-management/#roles" class="help" target="_blank" tabindex="-1"><i class="fa fa-question-circle"></i></a></sup></label>
<SingleSelect id="roleInput" v-model="role" :options="roles" option-key="id" option-label="name" :disabled="isSelf"/>
<div class="text-danger" v-if="formError.role">{{ formError.role }}</div>
<div class="error-label" v-if="formError.role">{{ formError.role }}</div>
</FormGroup>
<!-- local groups. they can have local and external users -->
@@ -296,7 +300,7 @@ defineExpose({
<!-- on add, this is hidden for now, until we figure why one would want to add an inactive user -->
<Checkbox v-if="user" v-model="active" :disabled="isSelf" :label="$t('users.user.activeCheckbox')" help-url="https://docs.cloudron.io/user-management/#disable-user"/>
<Checkbox v-if="!user" v-model="sendInvite" :label="$t('users.addUserDialog.sendInviteCheckbox')" />
<Checkbox v-else v-model="sendInvite" :label="$t('users.addUserDialog.sendInviteCheckbox')" />
</fieldset>
</form>
</Dialog>