diff options
Diffstat (limited to 'modern/src/settings/NotificationPage.jsx')
-rw-r--r-- | modern/src/settings/NotificationPage.jsx | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/modern/src/settings/NotificationPage.jsx b/modern/src/settings/NotificationPage.jsx new file mode 100644 index 00000000..fdefedaf --- /dev/null +++ b/modern/src/settings/NotificationPage.jsx @@ -0,0 +1,154 @@ +import React, { useState } from 'react'; + +import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, + FormControlLabel, + Checkbox, + FormGroup, + Button, +} from '@mui/material'; +import makeStyles from '@mui/styles/makeStyles'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import { useTranslation, useTranslationKeys } from '../common/components/LocalizationProvider'; +import EditItemView from './components/EditItemView'; +import { prefixString, unprefixString } from '../common/util/stringUtils'; +import SelectField from '../common/components/SelectField'; +import SettingsMenu from './components/SettingsMenu'; +import { useCatch } from '../reactHelper'; + +const useStyles = makeStyles((theme) => ({ + details: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), + }, +})); + +const NotificationPage = () => { + const classes = useStyles(); + const t = useTranslation(); + + const [item, setItem] = useState(); + + const alarms = useTranslationKeys((it) => it.startsWith('alarm')).map((it) => ({ + key: unprefixString('alarm', it), + name: t(it), + })); + + const testNotificators = useCatch(async () => { + await Promise.all(item.notificators.split(/[, ]+/).map(async (notificator) => { + const response = await fetch(`/api/notifications/test/${notificator}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(item), + }); + if (!response.ok) { + throw Error(await response.text()); + } + })); + }); + + const validate = () => item && item.type && item.notificators && (!item.notificators?.includes('command') || item.commandId); + + return ( + <EditItemView + endpoint="notifications" + item={item} + setItem={setItem} + validate={validate} + menu={<SettingsMenu />} + breadcrumbs={['settingsTitle', 'sharedNotification']} + > + {item && ( + <> + <Accordion defaultExpanded> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1"> + {t('sharedRequired')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <SelectField + value={item.type} + emptyValue={null} + onChange={(e) => setItem({ ...item, type: e.target.value })} + endpoint="/api/notifications/types" + keyGetter={(it) => it.type} + titleGetter={(it) => t(prefixString('event', it.type))} + label={t('sharedType')} + /> + {item.type === 'alarm' && ( + <SelectField + multiple + value={item.attributes && item.attributes.alarms ? item.attributes.alarms.split(/[, ]+/) : []} + onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, alarms: e.target.value.join() } })} + data={alarms} + keyGetter={(it) => it.key} + label={t('sharedAlarms')} + /> + )} + <SelectField + multiple + value={item.notificators ? item.notificators.split(/[, ]+/) : []} + onChange={(e) => setItem({ ...item, notificators: e.target.value.join() })} + endpoint="/api/notifications/notificators" + keyGetter={(it) => it.type} + titleGetter={(it) => t(prefixString('notificator', it.type))} + label={t('notificationNotificators')} + /> + {item.notificators?.includes('command') && ( + <SelectField + value={item.commandId || 0} + onChange={(event) => setItem({ ...item, commandId: Number(event.target.value) })} + endpoint="/api/commands" + titleGetter={(it) => it.description} + label={t('sharedSavedCommand')} + /> + )} + <Button + variant="outlined" + color="primary" + onClick={testNotificators} + disabled={!item.notificators} + > + {t('sharedTestNotificators')} + </Button> + <FormGroup> + <FormControlLabel + control={( + <Checkbox + checked={item.always} + onChange={(event) => setItem({ ...item, always: event.target.checked })} + /> + )} + label={t('notificationAlways')} + /> + </FormGroup> + </AccordionDetails> + </Accordion> + <Accordion> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1"> + {t('sharedExtra')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <SelectField + value={item.calendarId || 0} + onChange={(event) => setItem({ ...item, calendarId: Number(event.target.value) })} + endpoint="/api/calendars" + label={t('sharedCalendar')} + /> + </AccordionDetails> + </Accordion> + </> + )} + </EditItemView> + ); +}; + +export default NotificationPage; |