1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2025-05-15 03:56:12 +02:00

WIPWIPWIP

This commit is contained in:
Philipp Heckel 2022-12-02 15:37:48 -05:00
parent 84dca41008
commit 2772a38dae
16 changed files with 644 additions and 66 deletions
web/src/components

View file

@ -32,7 +32,7 @@ import DialogTitle from "@mui/material/DialogTitle";
import DialogContent from "@mui/material/DialogContent";
import DialogActions from "@mui/material/DialogActions";
import userManager from "../app/UserManager";
import {playSound, shuffle, sounds, validUrl} from "../app/utils";
import {playSound, shuffle, sounds, validTopic, validUrl} from "../app/utils";
import {useTranslation} from "react-i18next";
const Preferences = () => {
@ -42,6 +42,7 @@ const Preferences = () => {
<Notifications/>
<Appearance/>
<Users/>
<AccessControl/>
</Stack>
</Container>
);
@ -473,4 +474,164 @@ const Language = () => {
)
};
const AccessControl = () => {
const { t } = useTranslation();
const [dialogKey, setDialogKey] = useState(0);
const [dialogOpen, setDialogOpen] = useState(false);
const entries = useLiveQuery(() => userManager.all());
const handleAddClick = () => {
setDialogKey(prev => prev+1);
setDialogOpen(true);
};
const handleDialogCancel = () => {
setDialogOpen(false);
};
const handleDialogSubmit = async (user) => {
setDialogOpen(false);
try {
await userManager.save(user);
console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} added`);
} catch (e) {
console.log(`[Preferences] Error adding user.`, e);
}
};
return (
<Card sx={{ padding: 1 }} aria-label={t("prefs_users_title")}>
<CardContent sx={{ paddingBottom: 1 }}>
<Typography variant="h5" sx={{marginBottom: 2}}>
Access control
</Typography>
<Paragraph>
Define read/write access to topics for this server.
</Paragraph>
{entries?.length > 0 && <AccessControlTable entries={entries}/>}
</CardContent>
<CardActions>
<Button onClick={handleAddClick}>{t("prefs_users_add_button")}</Button>
<AccessControlDialog
key={`aclDialog${dialogKey}`}
open={dialogOpen}
user={null}
users={entries}
onCancel={handleDialogCancel}
onSubmit={handleDialogSubmit}
/>
</CardActions>
</Card>
);
};
const AccessControlTable = (props) => {
const { t } = useTranslation();
const [dialogKey, setDialogKey] = useState(0);
const [dialogOpen, setDialogOpen] = useState(false);
const [dialogUser, setDialogUser] = useState(null);
const handleEditClick = (user) => {
setDialogKey(prev => prev+1);
setDialogUser(user);
setDialogOpen(true);
};
const handleDialogCancel = () => {
setDialogOpen(false);
};
const handleDialogSubmit = async (user) => {
setDialogOpen(false);
try {
await userManager.save(user);
console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} updated`);
} catch (e) {
console.log(`[Preferences] Error updating user.`, e);
}
};
const handleDeleteClick = async (user) => {
try {
await userManager.delete(user.baseUrl);
console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} deleted`);
} catch (e) {
console.error(`[Preferences] Error deleting user for ${user.baseUrl}`, e);
}
};
return (
<Table size="small" aria-label={t("prefs_users_table")}>
<TableHead>
<TableRow>
<TableCell sx={{paddingLeft: 0}}>Topic</TableCell>
<TableCell>User</TableCell>
<TableCell>Access</TableCell>
<TableCell/>
</TableRow>
</TableHead>
<TableBody>
{props.entries?.map(user => (
<TableRow
key={user.baseUrl}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row" sx={{paddingLeft: 0}} aria-label={t("prefs_users_table_user_header")}>{user.username}</TableCell>
<TableCell aria-label={t("xxxxxxxxxx")}>{user.baseUrl}</TableCell>
<TableCell align="right">
<IconButton onClick={() => handleEditClick(user)} aria-label={t("prefs_users_edit_button")}>
<EditIcon/>
</IconButton>
<IconButton onClick={() => handleDeleteClick(user)} aria-label={t("prefs_users_delete_button")}>
<CloseIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
<AccessControlDialog
key={`userEditDialog${dialogKey}`}
open={dialogOpen}
user={dialogUser}
users={props.entries}
onCancel={handleDialogCancel}
onSubmit={handleDialogSubmit}
/>
</Table>
);
};
const AccessControlDialog = (props) => {
const { t } = useTranslation();
const [topic, setTopic] = useState("");
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
const addButtonEnabled = (() => {
return validTopic(topic);
})();
const handleSubmit = async () => {
// TODO
};
return (
<Dialog open={props.open} onClose={props.onCancel} fullScreen={fullScreen}>
<DialogTitle>Add entry</DialogTitle>
<DialogContent>
<TextField
autoFocus={editMode}
margin="dense"
id="topic"
label={"Topic"}
aria-label={"Topic xx"}
value={topic}
onChange={ev => setTopic(ev.target.value)}
type="text"
fullWidth
variant="standard"
/>
<FormControl fullWidth variant="standard" sx={{ margin: 1 }}>
<Select value={"read-write"} onChange={() => {}}>
<MenuItem value={"private"}>Read/write access only by me</MenuItem>
<MenuItem value={"read-only"}>Read/write access by user, anonymous read</MenuItem>
</Select>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={props.onCancel}>Cancel</Button>
<Button onClick={handleSubmit} disabled={!addButtonEnabled}>Add entry</Button>
</DialogActions>
</Dialog>
);
};
export default Preferences;