Fixed infinite load when editing/adding user with invalid username (#8098)

* Add error messages when add/edit user fails. Add help text on username fields.

* fix linting errors

* add myself to contributors list

* Remove unused variable and restore formatting

* restore formatting

---------

Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
This commit is contained in:
Alex
2026-07-30 19:11:50 +00:00
committed by GitHub
co-authored by Bill Thornton
parent 8fe63cd6d6
commit 2270114bb3
4 changed files with 28 additions and 0 deletions
+1
View File
@@ -108,6 +108,7 @@
- [lmaotrigine](https://github.com/lmaotrigine)
- [bjorntp](https://github.com/bjorntp)
- [austinhardaway](https://github.com/austinhardaway)
- [Alex Dickens](https://github.com/alex-dicko)
- [shindouj](https://github.com/shindouj)
## Emby Contributors
@@ -17,6 +17,7 @@ import { useChannels } from 'apps/dashboard/features/users/api/useChannels';
import { useUpdateUser } from 'apps/dashboard/features/users/api/useUpdateUser';
import { useUpdateUserPolicy } from 'apps/dashboard/features/users/api/useUpdateUserPolicy';
import { useNetworkConfig } from 'apps/dashboard/features/users/api/useNetworkConfig';
import Toast from 'apps/dashboard/components/Toast';
interface ProfileProps {
userDto: UserDto;
@@ -45,6 +46,12 @@ const Profile = ({ userDto }: ProfileProps) => {
const { data: channels, isSuccess: isChannelsSuccess } = useChannels({ supportsMediaDeletion: true });
const { data: netConfig, isSuccess: isNetConfigSuccess } = useNetworkConfig();
const [ isErrorToastOpen, setIsErrorToastOpen ] = useState(false);
const handleToastClose = useCallback(() => {
setIsErrorToastOpen(false);
}, []);
const updateUser = useUpdateUser();
const updateUserPolicy = useUpdateUserPolicy();
@@ -255,6 +262,10 @@ const Profile = ({ userDto }: ProfileProps) => {
}
});
}
},
onError: () => {
loading.hide();
setIsErrorToastOpen(true);
}
});
};
@@ -306,6 +317,11 @@ const Profile = ({ userDto }: ProfileProps) => {
return (
<div ref={element}>
<Toast
open={isErrorToastOpen}
onClose={handleToastClose}
message={globalize.translate('ErrorDefault')}
/>
<div
className='lnkEditUserPreferencesContainer'
style={{ paddingBottom: '1em' }}
@@ -332,6 +348,9 @@ const Profile = ({ userDto }: ProfileProps) => {
label={globalize.translate('LabelName')}
required
/>
<div className='fieldDescription'>
{globalize.translate('LabelUsernameAllowedCharactersHelp')}
</div>
</div>
<div className='selectContainer fldSelectLoginProvider hide'>
<SelectElement
+7
View File
@@ -167,6 +167,10 @@ const UserNew = () => {
setIsErrorToastOpen(true);
}
});
},
onError: () => {
loading.hide();
setIsErrorToastOpen(true);
}
});
};
@@ -231,6 +235,9 @@ const UserNew = () => {
label={globalize.translate('LabelName')}
required
/>
<div className='fieldDescription'>
{globalize.translate('LabelUsernameAllowedCharactersHelp')}
</div>
</div>
<div className='inputContainer'>
<Input
+1
View File
@@ -1915,6 +1915,7 @@
"LabelTileWidthHelp": "Maximum number of images per tile in the X direction.",
"LabelTileHeight": "Tile Height",
"LabelTileHeightHelp": "Maximum number of images per tile in the Y direction.",
"LabelUsernameAllowedCharactersHelp": "Usernames can contain letters, numbers, spaces, and the following characters: - _ ' . @ +. They cannot begin or end with a space.",
"LabelJpegQuality": "JPEG Quality",
"LabelJpegQualityHelp": "The JPEG compression quality for trickplay images.",
"LabelQscale": "Qscale",