mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2026-09-02 19:43:13 +03:00
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:
@@ -108,6 +108,7 @@
|
|||||||
- [lmaotrigine](https://github.com/lmaotrigine)
|
- [lmaotrigine](https://github.com/lmaotrigine)
|
||||||
- [bjorntp](https://github.com/bjorntp)
|
- [bjorntp](https://github.com/bjorntp)
|
||||||
- [austinhardaway](https://github.com/austinhardaway)
|
- [austinhardaway](https://github.com/austinhardaway)
|
||||||
|
- [Alex Dickens](https://github.com/alex-dicko)
|
||||||
- [shindouj](https://github.com/shindouj)
|
- [shindouj](https://github.com/shindouj)
|
||||||
|
|
||||||
## Emby Contributors
|
## 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 { useUpdateUser } from 'apps/dashboard/features/users/api/useUpdateUser';
|
||||||
import { useUpdateUserPolicy } from 'apps/dashboard/features/users/api/useUpdateUserPolicy';
|
import { useUpdateUserPolicy } from 'apps/dashboard/features/users/api/useUpdateUserPolicy';
|
||||||
import { useNetworkConfig } from 'apps/dashboard/features/users/api/useNetworkConfig';
|
import { useNetworkConfig } from 'apps/dashboard/features/users/api/useNetworkConfig';
|
||||||
|
import Toast from 'apps/dashboard/components/Toast';
|
||||||
|
|
||||||
interface ProfileProps {
|
interface ProfileProps {
|
||||||
userDto: UserDto;
|
userDto: UserDto;
|
||||||
@@ -45,6 +46,12 @@ const Profile = ({ userDto }: ProfileProps) => {
|
|||||||
const { data: channels, isSuccess: isChannelsSuccess } = useChannels({ supportsMediaDeletion: true });
|
const { data: channels, isSuccess: isChannelsSuccess } = useChannels({ supportsMediaDeletion: true });
|
||||||
const { data: netConfig, isSuccess: isNetConfigSuccess } = useNetworkConfig();
|
const { data: netConfig, isSuccess: isNetConfigSuccess } = useNetworkConfig();
|
||||||
|
|
||||||
|
const [ isErrorToastOpen, setIsErrorToastOpen ] = useState(false);
|
||||||
|
|
||||||
|
const handleToastClose = useCallback(() => {
|
||||||
|
setIsErrorToastOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const updateUser = useUpdateUser();
|
const updateUser = useUpdateUser();
|
||||||
const updateUserPolicy = useUpdateUserPolicy();
|
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 (
|
return (
|
||||||
<div ref={element}>
|
<div ref={element}>
|
||||||
|
<Toast
|
||||||
|
open={isErrorToastOpen}
|
||||||
|
onClose={handleToastClose}
|
||||||
|
message={globalize.translate('ErrorDefault')}
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
className='lnkEditUserPreferencesContainer'
|
className='lnkEditUserPreferencesContainer'
|
||||||
style={{ paddingBottom: '1em' }}
|
style={{ paddingBottom: '1em' }}
|
||||||
@@ -332,6 +348,9 @@ const Profile = ({ userDto }: ProfileProps) => {
|
|||||||
label={globalize.translate('LabelName')}
|
label={globalize.translate('LabelName')}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelUsernameAllowedCharactersHelp')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='selectContainer fldSelectLoginProvider hide'>
|
<div className='selectContainer fldSelectLoginProvider hide'>
|
||||||
<SelectElement
|
<SelectElement
|
||||||
|
|||||||
@@ -167,6 +167,10 @@ const UserNew = () => {
|
|||||||
setIsErrorToastOpen(true);
|
setIsErrorToastOpen(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
loading.hide();
|
||||||
|
setIsErrorToastOpen(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -231,6 +235,9 @@ const UserNew = () => {
|
|||||||
label={globalize.translate('LabelName')}
|
label={globalize.translate('LabelName')}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelUsernameAllowedCharactersHelp')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='inputContainer'>
|
<div className='inputContainer'>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -1915,6 +1915,7 @@
|
|||||||
"LabelTileWidthHelp": "Maximum number of images per tile in the X direction.",
|
"LabelTileWidthHelp": "Maximum number of images per tile in the X direction.",
|
||||||
"LabelTileHeight": "Tile Height",
|
"LabelTileHeight": "Tile Height",
|
||||||
"LabelTileHeightHelp": "Maximum number of images per tile in the Y direction.",
|
"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",
|
"LabelJpegQuality": "JPEG Quality",
|
||||||
"LabelJpegQualityHelp": "The JPEG compression quality for trickplay images.",
|
"LabelJpegQualityHelp": "The JPEG compression quality for trickplay images.",
|
||||||
"LabelQscale": "Qscale",
|
"LabelQscale": "Qscale",
|
||||||
|
|||||||
Reference in New Issue
Block a user