diff --git a/resources/i18n/pt.json b/resources/i18n/pt.json index f507c7ce..f5f90c1d 100644 --- a/resources/i18n/pt.json +++ b/resources/i18n/pt.json @@ -240,7 +240,9 @@ "transcodingDisabled": "Por questão de segurança, esta tela de configuração está desabilitada. Se você quiser alterar estas configurações, reinicie o servidor com a opção %{config}", "transcodingEnabled": "Navidrome está sendo executado com a opção %{config}. Isto permite que potencialmente se execute comandos do sistema pela interface Web. É recomendado que vc mantenha esta opção desabilitada, e só a habilite quando precisar configurar opções de Conversão", "songsAddedToPlaylist": "Música adicionada à playlist |||| %{smart_count} músicas adicionadas à playlist", - "noPlaylistsAvailable": "Nenhuma playlist" + "noPlaylistsAvailable": "Nenhuma playlist", + "delete_user_title": "Excluir usuário '%{name}'", + "delete_user_content": "Você tem certeza que deseja excluir o usuário e todos os seus dados (incluindo suas playlists e preferências)?" }, "menu": { "library": "Biblioteca", diff --git a/ui/src/i18n/en.json b/ui/src/i18n/en.json index 1915a97f..3b0ba717 100644 --- a/ui/src/i18n/en.json +++ b/ui/src/i18n/en.json @@ -241,7 +241,9 @@ "transcodingDisabled": "Changing the transcoding configuration through the web interface is disabled for security reasons. If you would like to change (edit or add) transcoding options, restart the server with the %{config} configuration option.", "transcodingEnabled": "Navidrome is currently running with %{config}, making it possible to run system commands from the transcoding settings using the web interface. We recommend to disable it for security reasons and only enable it when configuring Transcoding options.", "songsAddedToPlaylist": "Added 1 song to playlist |||| Added %{smart_count} songs to playlist", - "noPlaylistsAvailable": "None available" + "noPlaylistsAvailable": "None available", + "delete_user_title": "Delete user '%{name}'", + "delete_user_content": "Are you sure you want to delete this user and all their data (including playlists and preferences)?" }, "menu": { "library": "Library", diff --git a/ui/src/user/DeleteUserButton.js b/ui/src/user/DeleteUserButton.js new file mode 100644 index 00000000..852fcada --- /dev/null +++ b/ui/src/user/DeleteUserButton.js @@ -0,0 +1,79 @@ +import React from 'react' +import DeleteIcon from '@material-ui/icons/Delete' +import { makeStyles } from '@material-ui/core/styles' +import { fade } from '@material-ui/core/styles/colorManipulator' +import classnames from 'classnames' +import { useDeleteWithConfirmController, Button, Confirm } from 'react-admin' + +const useStyles = makeStyles( + (theme) => ({ + deleteButton: { + color: theme.palette.error.main, + '&:hover': { + backgroundColor: fade(theme.palette.error.main, 0.12), + // Reset on mouse devices + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + }, + }), + { name: 'RaDeleteWithConfirmButton' } +) + +const DeleteUserButton = (props) => { + const { + resource, + record, + basePath, + redirect = 'list', + className, + onClick, + ...rest + } = props + const { + open, + loading, + handleDialogOpen, + handleDialogClose, + handleDelete, + } = useDeleteWithConfirmController({ + resource, + record, + redirect, + basePath, + onClick, + }) + + const classes = useStyles(props) + return ( + <> + + + + ) +} + +export default DeleteUserButton diff --git a/ui/src/user/UserEdit.js b/ui/src/user/UserEdit.js index 207fca86..3940f829 100644 --- a/ui/src/user/UserEdit.js +++ b/ui/src/user/UserEdit.js @@ -1,4 +1,5 @@ import React from 'react' +import { makeStyles } from '@material-ui/core/styles' import { TextInput, BooleanInput, @@ -9,17 +10,35 @@ import { email, SimpleForm, useTranslate, + Toolbar, + SaveButton, } from 'react-admin' import { Title } from '../common' +import DeleteUserButton from './DeleteUserButton' + +const useStyles = makeStyles({ + toolbar: { + display: 'flex', + justifyContent: 'space-between', + }, +}) const UserTitle = ({ record }) => { const translate = useTranslate() const resourceName = translate('resources.user.name', { smart_count: 1 }) return } + +const UserToolbar = (props) => ( + <Toolbar {...props} classes={useStyles()}> + <SaveButton /> + <DeleteUserButton /> + </Toolbar> +) + const UserEdit = (props) => ( <Edit title={<UserTitle />} {...props}> - <SimpleForm> + <SimpleForm toolbar={<UserToolbar />}> <TextInput source="userName" validate={[required()]} /> <TextInput source="name" validate={[required()]} /> <TextInput source="email" validate={[email()]} /> diff --git a/ui/src/user/UserList.js b/ui/src/user/UserList.js index 6a040711..33bb291b 100644 --- a/ui/src/user/UserList.js +++ b/ui/src/user/UserList.js @@ -25,6 +25,7 @@ const UserList = (props) => { {...props} sort={{ field: 'userName', order: 'ASC' }} exporter={false} + bulkActionButtons={false} filters={<UserFilter />} > {isXsmall ? (