Wizard: indicate which user tab contains error

Fixes: #3097

Added exclamation marks to the tabs where the user contains error.
This commit is contained in:
Katarina Sieklova 2025-05-13 17:43:18 +02:00 committed by Anna Vítová
parent 310f7a05cf
commit 362e5f7ca6
2 changed files with 28 additions and 12 deletions

View file

@ -7,8 +7,12 @@ import {
Tabs, Tabs,
Tab, Tab,
TabTitleText, TabTitleText,
Icon,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import {
ExclamationCircleIcon,
ExternalLinkAltIcon,
} from '@patternfly/react-icons';
import calculateNewIndex from './calculateNewIndex'; import calculateNewIndex from './calculateNewIndex';
import RemoveUserModal from './RemoveUserModal'; import RemoveUserModal from './RemoveUserModal';
@ -122,12 +126,9 @@ const UserInfo = () => {
}; };
const getValidationByIndex = (index: number) => { const getValidationByIndex = (index: number) => {
const errors = stepValidation?.errors[index] || {};
return { return {
errors: { errors,
userName: stepValidation?.errors[index]?.userName,
userSshKey: stepValidation?.errors[index]?.userSshKey,
groups: stepValidation?.errors[index]?.groups,
},
disabledNext: stepValidation.disabledNext, disabledNext: stepValidation.disabledNext,
}; };
}; };
@ -156,7 +157,20 @@ const UserInfo = () => {
aria-label={`User ${user.name} tab`} aria-label={`User ${user.name} tab`}
key={index} key={index}
eventKey={index} eventKey={index}
title={<TabTitleText>{user.name || 'New user'}</TabTitleText>} title={
<TabTitleText>
{user.name || 'New user'}{' '}
{Object.entries(getValidationByIndex(index).errors).some(
([field, error]) =>
Boolean(error) &&
!(field === 'userName' && error === 'Required value')
) && (
<Icon status="danger">
<ExclamationCircleIcon title="Validation error" />
</Icon>
)}
</TabTitleText>
}
> >
<FormGroup isRequired label="Username" className="pf-v6-u-pb-md"> <FormGroup isRequired label="Username" className="pf-v6-u-pb-md">
<ValidatedInputAndTextArea <ValidatedInputAndTextArea

View file

@ -486,7 +486,8 @@ export function useServicesValidation(): StepValidation {
const validateUserName = ( const validateUserName = (
users: UserWithAdditionalInfo[], users: UserWithAdditionalInfo[],
userName: string userName: string,
currentIndex: number
): string => { ): string => {
if (!userName) { if (!userName) {
return 'Required value'; return 'Required value';
@ -496,9 +497,10 @@ const validateUserName = (
} }
// check for duplicate names // check for duplicate names
const duplicateName = const count = users.filter(
new Set(users.map((user) => user.name)).size !== users.length; (user, index) => user.name === userName && index !== currentIndex
if (duplicateName) { ).length;
if (count > 0) {
return 'Username already exists'; return 'Username already exists';
} }
return ''; return '';
@ -525,7 +527,7 @@ export function useUsersValidation(): UsersStepValidation {
for (let index = 0; index < users.length; index++) { for (let index = 0; index < users.length; index++) {
const invalidGroups = []; const invalidGroups = [];
const userNameError = validateUserName(users, users[index].name); const userNameError = validateUserName(users, users[index].name, index);
const sshKeyError = validateSshKey(users[index].ssh_key); const sshKeyError = validateSshKey(users[index].ssh_key);
const isPasswordValid = checkPasswordValidity( const isPasswordValid = checkPasswordValidity(
users[index].password, users[index].password,