minor improvements
This commit is contained in:
parent
fb353d1bc8
commit
5abbbac2b6
@ -5,7 +5,7 @@ import {
|
|||||||
Box, CssBaseline, Divider,
|
Box, CssBaseline, Divider,
|
||||||
IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText,
|
IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText,
|
||||||
Select, Drawer,
|
Select, Drawer,
|
||||||
styled, MenuItem, Menu,
|
styled, MenuItem, Menu, useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Dropdown } from '@mui/base/Dropdown';
|
import { Dropdown } from '@mui/base/Dropdown';
|
||||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||||
@ -100,6 +100,7 @@ export default function Sidebar(props) {
|
|||||||
const [fetchLanguages, setFetchLanguages] = useState(true);
|
const [fetchLanguages, setFetchLanguages] = useState(true);
|
||||||
const [drawerOpen, setDrawerOpen] = useState(window.screen.width >= 1000);
|
const [drawerOpen, setDrawerOpen] = useState(window.screen.width >= 1000);
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
|
const theme = useTheme();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const currentPath = useCurrentPath();
|
const currentPath = useCurrentPath();
|
||||||
|
|
||||||
|
@ -159,9 +159,9 @@ export default function AccessControlList(props) {
|
|||||||
rows.push(
|
rows.push(
|
||||||
<TableRow key={"perm-" + index}>
|
<TableRow key={"perm-" + index}>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div style={{display: "grid", gridTemplateColumns: "60px auto"}}>
|
<Grid container>
|
||||||
<div style={{alignSelf: "center"}}>
|
<Grid item xs={1} alignContent={"center"}>
|
||||||
<IconButton style={{padding: 0}} size={"small"} color={"primary"}
|
<IconButton size={"small"} color={"primary"}
|
||||||
disabled={isRestricted(permission.method)}
|
disabled={isRestricted(permission.method)}
|
||||||
onClick={() => setDialogData({
|
onClick={() => setDialogData({
|
||||||
open: true,
|
open: true,
|
||||||
@ -172,25 +172,25 @@ export default function AccessControlList(props) {
|
|||||||
{ type: "label", value: L("permissions.description") + ":" },
|
{ type: "label", value: L("permissions.description") + ":" },
|
||||||
{ type: "text", name: "description", value: permission.description, maxLength: 128 }
|
{ type: "text", name: "description", value: permission.description, maxLength: 128 }
|
||||||
],
|
],
|
||||||
onOption: (option, inputData) => option === 0 ? onUpdatePermission(inputData, permission.groups) : true })} >
|
onOption: (option, inputData) => option === 1 ? onUpdatePermission(inputData, permission.groups) : true })} >
|
||||||
<Edit />
|
<Edit />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton style={{padding: 0}} size={"small"} color={"secondary"}
|
<IconButton size={"small"} color={"error"}
|
||||||
disabled={isRestricted(permission.method)}
|
disabled={isRestricted(permission.method)}
|
||||||
onClick={() => setDialogData({
|
onClick={() => setDialogData({
|
||||||
open: true,
|
open: true,
|
||||||
title: L("permissions.delete_permission_confirm"),
|
title: L("permissions.delete_permission_confirm"),
|
||||||
message: L("permissions.method") + ": " + permission.method,
|
message: L("permissions.method") + ": " + permission.method,
|
||||||
onOption: (option) => option === 0 ? onDeletePermission(permission.method) : true
|
onOption: (option) => option === 1 ? onDeletePermission(permission.method) : true
|
||||||
})} >
|
})} >
|
||||||
<Delete />
|
<Delete />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</Grid>
|
||||||
<div>
|
<Grid item>
|
||||||
<b>{permission.method}</b><br />
|
<b>{permission.method}</b><br />
|
||||||
<i>{permission.description}</i>
|
<i>{permission.description}</i>
|
||||||
</div>
|
</Grid>
|
||||||
</div>
|
</Grid>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<BorderedColumn key={"perm-" + index + "-everyone"} align={"center"}>
|
<BorderedColumn key={"perm-" + index + "-everyone"} align={"center"}>
|
||||||
<Checkbox checked={!permission.groups.length}
|
<Checkbox checked={!permission.groups.length}
|
||||||
@ -250,7 +250,7 @@ export default function AccessControlList(props) {
|
|||||||
placeholder: L("permissions.description")
|
placeholder: L("permissions.description")
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
onOption: (option, inputData) => option === 0 ? onUpdatePermission(inputData, []) : true
|
onOption: (option, inputData) => option === 1 ? onUpdatePermission(inputData, []) : true
|
||||||
})}>
|
})}>
|
||||||
{L("general.add")}
|
{L("general.add")}
|
||||||
</Button>
|
</Button>
|
||||||
@ -279,6 +279,6 @@ export default function AccessControlList(props) {
|
|||||||
message={dialogData.message}
|
message={dialogData.message}
|
||||||
onOption={dialogData.onOption}
|
onOption={dialogData.onOption}
|
||||||
inputs={dialogData.inputs}
|
inputs={dialogData.inputs}
|
||||||
options={[L("general.ok"), L("general.cancel")]}/>
|
options={[L("general.cancel"), L("general.ok")]}/>
|
||||||
</ViewContent>
|
</ViewContent>
|
||||||
}
|
}
|
@ -159,9 +159,9 @@ export default function EditGroupView(props) {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
onOption: (option) => {
|
onOption: (option) => {
|
||||||
if(option === 0) {
|
if(option === 1) {
|
||||||
onAddMember()
|
onAddMember()
|
||||||
} else {
|
} else {
|
||||||
selectedUserRef.current = null
|
selectedUserRef.current = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,12 +227,12 @@ export default function EditGroupView(props) {
|
|||||||
</Button>
|
</Button>
|
||||||
{ !isNewGroup &&
|
{ !isNewGroup &&
|
||||||
<Button startIcon={<Delete/>} disabled={!api.hasPermission("groups/delete")}
|
<Button startIcon={<Delete/>} disabled={!api.hasPermission("groups/delete")}
|
||||||
variant={"outlined"} color={"secondary"}
|
variant={"outlined"} color={"error"}
|
||||||
onClick={() => setDialogData({
|
onClick={() => setDialogData({
|
||||||
open: true,
|
open: true,
|
||||||
title: L("account.delete_group_title"),
|
title: L("account.delete_group_title"),
|
||||||
message: L("account.delete_group_text"),
|
message: L("account.delete_group_text"),
|
||||||
onOption: option => option === 0 ? onDeleteGroup() : true
|
onOption: option => option === 1 ? onDeleteGroup() : true
|
||||||
})}>
|
})}>
|
||||||
{L("general.delete")}
|
{L("general.delete")}
|
||||||
</Button>
|
</Button>
|
||||||
@ -262,12 +262,12 @@ export default function EditGroupView(props) {
|
|||||||
label: L("general.remove"),
|
label: L("general.remove"),
|
||||||
element: Delete,
|
element: Delete,
|
||||||
disabled: !api.hasPermission("groups/removeMember"),
|
disabled: !api.hasPermission("groups/removeMember"),
|
||||||
color: "secondary",
|
color: "error",
|
||||||
onClick: (entry) => setDialogData({
|
onClick: (entry) => setDialogData({
|
||||||
open: true,
|
open: true,
|
||||||
title: L("account.remove_group_member_title"),
|
title: L("account.remove_group_member_title"),
|
||||||
message: sprintf(L("account.remove_group_member_text"), entry.fullName || entry.name),
|
message: sprintf(L("account.remove_group_member_text"), entry.fullName || entry.name),
|
||||||
onOption: (option) => option === 0 ? onRemoveMember(entry.id) : true
|
onOption: (option) => option === 1 ? onRemoveMember(entry.id) : true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
@ -293,6 +293,6 @@ export default function EditGroupView(props) {
|
|||||||
message={dialogData.message}
|
message={dialogData.message}
|
||||||
onOption={dialogData.onOption}
|
onOption={dialogData.onOption}
|
||||||
inputs={dialogData.inputs}
|
inputs={dialogData.inputs}
|
||||||
options={[L("general.ok"), L("general.cancel")]} />
|
options={[L("general.cancel"), L("general.ok")]} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
@ -76,12 +76,12 @@ const StatBox = (props) => <StyledStatBox variant={"filled"} icon={false}
|
|||||||
const StatusLine = (props) => {
|
const StatusLine = (props) => {
|
||||||
const {enabled, text, ...other} = props;
|
const {enabled, text, ...other} = props;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
return <Box display="grid" gridTemplateColumns={"30px auto"}>
|
return <Box display="grid" gridTemplateColumns={"30px auto"} alignItems={"center"}>
|
||||||
<CheckCircle color={"primary"} title={text} /> {text}
|
<CheckCircle color={"primary"} title={text} /> {text}
|
||||||
</Box>
|
</Box>
|
||||||
} else {
|
} else {
|
||||||
return <Box display="grid" gridTemplateColumns={"30px auto"}>
|
return <Box display="grid" gridTemplateColumns={"30px auto"} alignItems={"center"}>
|
||||||
<HighlightOff color={"secondary"} title={text} /> {text}
|
<HighlightOff color={"error"} title={text} /> {text}
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,25 +127,25 @@ export default function Overview(props) {
|
|||||||
<Link key={"home"} to={"/admin/dashboard"}>Home</Link>
|
<Link key={"home"} to={"/admin/dashboard"}>Home</Link>
|
||||||
]}>
|
]}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={6} lg={3}>
|
||||||
<StatBox color={"info"} count={stats?.userCount}
|
<StatBox color={"info"} count={stats?.userCount}
|
||||||
text={L("admin.users_registered")}
|
text={L("admin.users_registered")}
|
||||||
icon={<People/>}
|
icon={<People/>}
|
||||||
link={"/admin/users"}/>
|
link={"/admin/users"}/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={6} lg={3}>
|
||||||
<StatBox color={"success"} count={stats?.groupCount}
|
<StatBox color={"success"} count={stats?.groupCount}
|
||||||
text={L("admin.available_groups")}
|
text={L("admin.available_groups")}
|
||||||
icon={<Groups/>}
|
icon={<Groups/>}
|
||||||
link={"/admin/groups"}/>
|
link={"/admin/groups"}/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={6} lg={3}>
|
||||||
<StatBox color={"warning"} count={stats?.pageCount}
|
<StatBox color={"warning"} count={stats?.pageCount}
|
||||||
text={L("admin.routes_defined")}
|
text={L("admin.routes_defined")}
|
||||||
icon={<LibraryBooks/>}
|
icon={<LibraryBooks/>}
|
||||||
link={"/admin/routes"}/>
|
link={"/admin/routes"}/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={6} lg={3}>
|
||||||
<StatBox color={"error"} count={stats?.errorCount}
|
<StatBox color={"error"} count={stats?.errorCount}
|
||||||
text={L("admin.error_count")}
|
text={L("admin.error_count")}
|
||||||
icon={<BugReport />}
|
icon={<BugReport />}
|
||||||
|
@ -76,7 +76,7 @@ export default function EditProfilePicture(props) {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
onOption: (option) => {
|
onOption: (option) => {
|
||||||
if (option === 0 && file) {
|
if (option === 1 && file) {
|
||||||
onUploadPicture(file)
|
onUploadPicture(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,13 +115,13 @@ export default function EditProfilePicture(props) {
|
|||||||
</Button>
|
</Button>
|
||||||
{profile.profilePicture &&
|
{profile.profilePicture &&
|
||||||
<Button variant="outlined" size="small"
|
<Button variant="outlined" size="small"
|
||||||
startIcon={<Delete />} color="secondary"
|
startIcon={<Delete />} color={"error"}
|
||||||
onClick={() => setDialogData({
|
onClick={() => setDialogData({
|
||||||
show: true,
|
show: true,
|
||||||
title: L("account.picture_remove_title"),
|
title: L("account.picture_remove_title"),
|
||||||
message: L("account.picture_remove_text"),
|
message: L("account.picture_remove_text"),
|
||||||
options: [L("general.confirm"), L("general.cancel")],
|
options: [L("general.confirm"), L("general.cancel")],
|
||||||
onOption: (option) => option === 0 ? onRemoveImage() : true
|
onOption: (option) => option === 1 ? onRemoveImage() : true
|
||||||
})}>
|
})}>
|
||||||
{L("account.remove_picture")}
|
{L("account.remove_picture")}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -106,7 +106,7 @@ export default function GpgBox(props) {
|
|||||||
<GpgFingerprintBox mb={2}>
|
<GpgFingerprintBox mb={2}>
|
||||||
{ profile.gpgKey.confirmed ?
|
{ profile.gpgKey.confirmed ?
|
||||||
<CheckCircle color="info" title={L("account.gpg_key_confirmed")} /> :
|
<CheckCircle color="info" title={L("account.gpg_key_confirmed")} /> :
|
||||||
<ErrorOutline color="secondary" title={L("account.gpg_key_pending")} />
|
<ErrorOutline color="error" title={L("account.gpg_key_pending")} />
|
||||||
}
|
}
|
||||||
GPG-Fingerprint: <code title={L("general.click_to_copy")}
|
GPG-Fingerprint: <code title={L("general.click_to_copy")}
|
||||||
onClick={() => navigator.clipboard.writeText(profile.gpgKey.fingerprint)}>
|
onClick={() => navigator.clipboard.writeText(profile.gpgKey.fingerprint)}>
|
||||||
@ -124,7 +124,7 @@ export default function GpgBox(props) {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</SpacedFormGroup>
|
</SpacedFormGroup>
|
||||||
<Button startIcon={isGpgKeyRemoving ? <CircularProgress size={12} /> : <Remove />}
|
<Button startIcon={isGpgKeyRemoving ? <CircularProgress size={12} /> : <Remove />}
|
||||||
color="secondary" onClick={onRemoveGpgKey}
|
color="error" onClick={onRemoveGpgKey}
|
||||||
variant="outlined" size="small"
|
variant="outlined" size="small"
|
||||||
disabled={isGpgKeyRemoving || !api.hasPermission("gpgKey/remove")}>
|
disabled={isGpgKeyRemoving || !api.hasPermission("gpgKey/remove")}>
|
||||||
{isGpgKeyRemoving ? L("general.removing") + "…" : L("general.remove")}
|
{isGpgKeyRemoving ? L("general.removing") + "…" : L("general.remove")}
|
||||||
|
@ -82,7 +82,7 @@ export default function MultiFactorBox(props) {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</SpacedFormGroup>
|
</SpacedFormGroup>
|
||||||
<Button startIcon={is2FARemoving ? <CircularProgress size={12} /> : <Remove />}
|
<Button startIcon={is2FARemoving ? <CircularProgress size={12} /> : <Remove />}
|
||||||
color="secondary" onClick={onRemove2FA}
|
color="danger" onClick={onRemove2FA}
|
||||||
variant="outlined" size="small"
|
variant="outlined" size="small"
|
||||||
disabled={is2FARemoving || !api.hasPermission("tfa/remove")}>
|
disabled={is2FARemoving || !api.hasPermission("tfa/remove")}>
|
||||||
{is2FARemoving ? L("general.removing") + "…" : L("general.remove")}
|
{is2FARemoving ? L("general.removing") + "…" : L("general.remove")}
|
||||||
|
@ -37,8 +37,8 @@ export default function MfaTotp(props) {
|
|||||||
sx: { "& input": { textAlign: "center", fontFamily: "monospace" } },
|
sx: { "& input": { textAlign: "center", fontFamily: "monospace" } },
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
options: [L("general.ok"), L("general.cancel")],
|
options: [L("general.cancel"), L("general.ok")],
|
||||||
onOption: (option, data) => option === 0 ? onConfirmTOTP(data.code) : true
|
onOption: (option, data) => option === 1 ? onConfirmTOTP(data.code) : true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [api, onConfirmTOTP]);
|
}, [api, onConfirmTOTP]);
|
||||||
|
@ -104,9 +104,9 @@ export default function RouteForm(props) {
|
|||||||
onChange={e => setRoute({...route, extra: minifyJson(e.target.value)})}/>
|
onChange={e => setRoute({...route, extra: minifyJson(e.target.value)})}/>
|
||||||
<Box mt={1} fontStyle={"italic"} display={"grid"} gridTemplateColumns={"30px auto"}>{
|
<Box mt={1} fontStyle={"italic"} display={"grid"} gridTemplateColumns={"30px auto"}>{
|
||||||
extraArgs === null ?
|
extraArgs === null ?
|
||||||
<><ErrorRounded color={"secondary"}/><span>{L("routes.json_err")}</span></> :
|
<><ErrorRounded color={"error"}/><span>{L("routes.json_err")}</span></> :
|
||||||
(type !== "object" ?
|
(type !== "object" ?
|
||||||
<><ErrorRounded color={"secondary"}/><span>{L("routes.json_not_object")}</span></> :
|
<><ErrorRounded color={"error"}/><span>{L("routes.json_not_object")}</span></> :
|
||||||
<><CheckCircle color={"primary"} /><span>{L("routes.json_ok")}</span></>)
|
<><CheckCircle color={"primary"} /><span>{L("routes.json_ok")}</span></>)
|
||||||
}</Box>
|
}</Box>
|
||||||
</RouteFormControl>
|
</RouteFormControl>
|
||||||
|
@ -178,7 +178,7 @@ export default function RouteListView(props) {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton size={"small"} title={L("general.delete")}
|
<IconButton size={"small"} title={L("general.delete")}
|
||||||
disabled={!api.hasPermission("routes/remove")}
|
disabled={!api.hasPermission("routes/remove")}
|
||||||
color={"secondary"}
|
color={"error"}
|
||||||
onClick={() => setDialogData({
|
onClick={() => setDialogData({
|
||||||
open: true,
|
open: true,
|
||||||
title: L("routes.delete_route_title"),
|
title: L("routes.delete_route_title"),
|
||||||
@ -186,8 +186,8 @@ export default function RouteListView(props) {
|
|||||||
inputs: [
|
inputs: [
|
||||||
{ type: "text", name: "pattern", value: route.pattern, disabled: true}
|
{ type: "text", name: "pattern", value: route.pattern, disabled: true}
|
||||||
],
|
],
|
||||||
options: [L("general.ok"), L("general.cancel")],
|
options: [L("general.cancel"), L("general.ok")],
|
||||||
onOption: btn => btn === 0 ? onDeleteRoute(route.id) : true
|
onOption: btn => btn === 1 ? onDeleteRoute(route.id) : true
|
||||||
})}>
|
})}>
|
||||||
<Delete />
|
<Delete />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -207,6 +207,6 @@ export default function RouteListView(props) {
|
|||||||
message={dialogData.message}
|
message={dialogData.message}
|
||||||
onOption={dialogData.onOption}
|
onOption={dialogData.onOption}
|
||||||
inputs={dialogData.inputs}
|
inputs={dialogData.inputs}
|
||||||
options={[L("general.ok"), L("general.cancel")]} />
|
options={[L("general.cancel"), L("general.ok")]} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
@ -341,7 +341,7 @@ export default function SettingsView(props) {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align={"center"}>
|
<TableCell align={"center"}>
|
||||||
<IconButton onClick={() => onDeleteKey(key)}
|
<IconButton onClick={() => onDeleteKey(key)}
|
||||||
color={"secondary"}>
|
color={"error"}>
|
||||||
<Delete />
|
<Delete />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@ -404,7 +404,7 @@ export default function SettingsView(props) {
|
|||||||
variant={"outlined"} title={L(hasChanged ? "general.unsaved_changes" : "general.save")}>
|
variant={"outlined"} title={L(hasChanged ? "general.unsaved_changes" : "general.save")}>
|
||||||
{isSaving ? L("general.saving") + "…" : (L("general.save") + (hasChanged ? " *" : ""))}
|
{isSaving ? L("general.saving") + "…" : (L("general.save") + (hasChanged ? " *" : ""))}
|
||||||
</Button>
|
</Button>
|
||||||
<Button color={"secondary"}
|
<Button color={"error"}
|
||||||
onClick={onReset}
|
onClick={onReset}
|
||||||
disabled={isSaving}
|
disabled={isSaving}
|
||||||
startIcon={<RestartAlt />}
|
startIcon={<RestartAlt />}
|
||||||
|
Loading…
Reference in New Issue
Block a user