aboutsummaryrefslogtreecommitdiff
path: root/modern/src/settings
diff options
context:
space:
mode:
Diffstat (limited to 'modern/src/settings')
-rw-r--r--modern/src/settings/CalendarsPage.js60
-rw-r--r--modern/src/settings/CommandsPage.js68
-rw-r--r--modern/src/settings/ComputedAttributesPage.js76
-rw-r--r--modern/src/settings/DriversPage.js64
-rw-r--r--modern/src/settings/GroupsPage.js60
-rw-r--r--modern/src/settings/MaintenancesPage.js73
-rw-r--r--modern/src/settings/NotificationsPage.js72
-rw-r--r--modern/src/settings/UsersPage.js72
-rw-r--r--modern/src/settings/components/CollectionActions.js48
-rw-r--r--modern/src/settings/components/CollectionFab.js35
-rw-r--r--modern/src/settings/components/EditCollectionView.js89
11 files changed, 339 insertions, 378 deletions
diff --git a/modern/src/settings/CalendarsPage.js b/modern/src/settings/CalendarsPage.js
index 06697647..a5072277 100644
--- a/modern/src/settings/CalendarsPage.js
+++ b/modern/src/settings/CalendarsPage.js
@@ -1,13 +1,13 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -16,10 +16,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const CalendarsView = ({ updateTimestamp, onMenuClick }) => {
+const CalendarsPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -29,38 +30,33 @@ const CalendarsView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedCalendars']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedName')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/calendar" endpoint="calendars" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.name}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/calendar" />
+ </PageLayout>
);
};
-const CalendarsPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedCalendars']}>
- <EditCollectionView content={CalendarsView} editPath="/settings/calendar" endpoint="calendars" />
- </PageLayout>
-);
-
export default CalendarsPage;
diff --git a/modern/src/settings/CommandsPage.js b/modern/src/settings/CommandsPage.js
index 1b09a8bd..64a29bf6 100644
--- a/modern/src/settings/CommandsPage.js
+++ b/modern/src/settings/CommandsPage.js
@@ -1,15 +1,15 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { useTranslation } from '../common/components/LocalizationProvider';
import { formatBoolean } from '../common/util/formatter';
import { prefixString } from '../common/util/stringUtils';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -18,10 +18,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const CommandsView = ({ updateTimestamp, onMenuClick }) => {
+const CommandsPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -31,42 +32,37 @@ const CommandsView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedDescription')}</TableCell>
- <TableCell>{t('sharedType')}</TableCell>
- <TableCell>{t('commandSendSms')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.description}</TableCell>
- <TableCell>{t(prefixString('command', item.type))}</TableCell>
- <TableCell>{formatBoolean(item.textChannel, t)}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedSavedCommands']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedDescription')}</TableCell>
+ <TableCell>{t('sharedType')}</TableCell>
+ <TableCell>{t('commandSendSms')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/command" endpoint="commands" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.description}</TableCell>
+ <TableCell>{t(prefixString('command', item.type))}</TableCell>
+ <TableCell>{formatBoolean(item.textChannel, t)}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/command" />
+ </PageLayout>
);
};
-const CommandsPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedSavedCommands']}>
- <EditCollectionView content={CommandsView} editPath="/settings/command" endpoint="commands" />
- </PageLayout>
-);
-
export default CommandsPage;
diff --git a/modern/src/settings/ComputedAttributesPage.js b/modern/src/settings/ComputedAttributesPage.js
index 86704c3b..0b029308 100644
--- a/modern/src/settings/ComputedAttributesPage.js
+++ b/modern/src/settings/ComputedAttributesPage.js
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { useTranslation } from '../common/components/LocalizationProvider';
import { useAdministrator } from '../common/util/permissions';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -17,10 +17,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const ComputedAttributeView = ({ updateTimestamp, onMenuClick }) => {
+const ComputedAttributesPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
const administrator = useAdministrator();
@@ -31,46 +32,41 @@ const ComputedAttributeView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- {administrator && <TableCell className={classes.columnAction} />}
- <TableCell>{t('sharedDescription')}</TableCell>
- <TableCell>{t('sharedAttribute')}</TableCell>
- <TableCell>{t('sharedExpression')}</TableCell>
- <TableCell>{t('sharedType')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- {administrator && (
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- )}
- <TableCell>{item.description}</TableCell>
- <TableCell>{item.attribute}</TableCell>
- <TableCell>{item.expression}</TableCell>
- <TableCell>{item.type}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedComputedAttributes']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ {administrator && <TableCell className={classes.columnAction} />}
+ <TableCell>{t('sharedDescription')}</TableCell>
+ <TableCell>{t('sharedAttribute')}</TableCell>
+ <TableCell>{t('sharedExpression')}</TableCell>
+ <TableCell>{t('sharedType')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ {administrator && (
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/attribute" endpoint="attributes/computed" setTimestamp={setTimestamp} />
+ </TableCell>
+ )}
+ <TableCell>{item.description}</TableCell>
+ <TableCell>{item.attribute}</TableCell>
+ <TableCell>{item.expression}</TableCell>
+ <TableCell>{item.type}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/attribute" />
+ </PageLayout>
);
};
-const ComputedAttributesPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedComputedAttributes']}>
- <EditCollectionView content={ComputedAttributeView} editPath="/settings/attribute" endpoint="attributes/computed" />
- </PageLayout>
-);
-
export default ComputedAttributesPage;
diff --git a/modern/src/settings/DriversPage.js b/modern/src/settings/DriversPage.js
index 26601777..b5c30a17 100644
--- a/modern/src/settings/DriversPage.js
+++ b/modern/src/settings/DriversPage.js
@@ -1,13 +1,13 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -16,10 +16,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const DriversView = ({ updateTimestamp, onMenuClick }) => {
+const DriversPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -29,40 +30,35 @@ const DriversView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- <TableCell>{t('deviceIdentifier')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
- <TableCell>{item.uniqueId}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedDrivers']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedName')}</TableCell>
+ <TableCell>{t('deviceIdentifier')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/driver" endpoint="drivers" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.name}</TableCell>
+ <TableCell>{item.uniqueId}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/driver" />
+ </PageLayout>
);
};
-const DriversPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedDrivers']}>
- <EditCollectionView content={DriversView} editPath="/settings/driver" endpoint="drivers" />
- </PageLayout>
-);
-
export default DriversPage;
diff --git a/modern/src/settings/GroupsPage.js b/modern/src/settings/GroupsPage.js
index 257d0bca..ae17bd78 100644
--- a/modern/src/settings/GroupsPage.js
+++ b/modern/src/settings/GroupsPage.js
@@ -1,13 +1,13 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -16,10 +16,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const GroupsView = ({ updateTimestamp, onMenuClick }) => {
+const GroupsPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -29,38 +30,33 @@ const GroupsView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'settingsGroups']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedName')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/group" endpoint="groups" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.name}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/group" />
+ </PageLayout>
);
};
-const GroupsPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'settingsGroups']}>
- <EditCollectionView content={GroupsView} editPath="/settings/group" endpoint="groups" />
- </PageLayout>
-);
-
export default GroupsPage;
diff --git a/modern/src/settings/MaintenancesPage.js b/modern/src/settings/MaintenancesPage.js
index ea00e7e1..43a37b60 100644
--- a/modern/src/settings/MaintenancesPage.js
+++ b/modern/src/settings/MaintenancesPage.js
@@ -1,17 +1,16 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
-
import usePositionAttributes from '../common/attributes/usePositionAttributes';
import { formatDistance, formatSpeed } from '../common/util/formatter';
import { useAttributePreference } from '../common/util/preferences';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -20,12 +19,13 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const MaintenancesView = ({ updateTimestamp, onMenuClick }) => {
+const MaintenacesPage = () => {
const classes = useStyles();
const t = useTranslation();
const positionAttributes = usePositionAttributes(t);
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
const speedUnit = useAttributePreference('speedUnit');
const distanceUnit = useAttributePreference('distanceUnit');
@@ -37,7 +37,7 @@ const MaintenancesView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
const convertAttribute = (key, value) => {
const attribute = positionAttributes[key];
@@ -56,41 +56,36 @@ const MaintenancesView = ({ updateTimestamp, onMenuClick }) => {
};
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- <TableCell>{t('sharedType')}</TableCell>
- <TableCell>{t('maintenanceStart')}</TableCell>
- <TableCell>{t('maintenancePeriod')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
- <TableCell>{item.type}</TableCell>
- <TableCell>{convertAttribute(item.type, item.start)}</TableCell>
- <TableCell>{convertAttribute(item.type, item.period)}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedMaintenance']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedName')}</TableCell>
+ <TableCell>{t('sharedType')}</TableCell>
+ <TableCell>{t('maintenanceStart')}</TableCell>
+ <TableCell>{t('maintenancePeriod')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/maintenance" endpoint="maintenance" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.name}</TableCell>
+ <TableCell>{item.type}</TableCell>
+ <TableCell>{convertAttribute(item.type, item.start)}</TableCell>
+ <TableCell>{convertAttribute(item.type, item.period)}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/maintenance" />
+ </PageLayout>
);
};
-const MaintenacesPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedMaintenance']}>
- <EditCollectionView content={MaintenancesView} editPath="/settings/maintenance" endpoint="maintenance" />
- </PageLayout>
-);
-
export default MaintenacesPage;
diff --git a/modern/src/settings/NotificationsPage.js b/modern/src/settings/NotificationsPage.js
index de3e762f..ec0df1cb 100644
--- a/modern/src/settings/NotificationsPage.js
+++ b/modern/src/settings/NotificationsPage.js
@@ -1,15 +1,15 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { prefixString } from '../common/util/stringUtils';
import { formatBoolean } from '../common/util/formatter';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -18,10 +18,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const NotificationsView = ({ updateTimestamp, onMenuClick }) => {
+const NotificationsPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -31,7 +32,7 @@ const NotificationsView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
const formatList = (prefix, value) => {
if (value) {
@@ -45,41 +46,36 @@ const NotificationsView = ({ updateTimestamp, onMenuClick }) => {
};
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('notificationType')}</TableCell>
- <TableCell>{t('notificationAlways')}</TableCell>
- <TableCell>{t('sharedAlarms')}</TableCell>
- <TableCell>{t('notificationNotificators')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{t(prefixString('event', item.type))}</TableCell>
- <TableCell>{formatBoolean(item.always, t)}</TableCell>
- <TableCell>{formatList('alarm', item.attributes.alarms)}</TableCell>
- <TableCell>{formatList('notificator', item.notificators)}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedNotifications']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('notificationType')}</TableCell>
+ <TableCell>{t('notificationAlways')}</TableCell>
+ <TableCell>{t('sharedAlarms')}</TableCell>
+ <TableCell>{t('notificationNotificators')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/notification" endpoint="notifications" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{t(prefixString('event', item.type))}</TableCell>
+ <TableCell>{formatBoolean(item.always, t)}</TableCell>
+ <TableCell>{formatList('alarm', item.attributes.alarms)}</TableCell>
+ <TableCell>{formatList('notificator', item.notificators)}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/notification" />
+ </PageLayout>
);
};
-const NotificationsPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedNotifications']}>
- <EditCollectionView content={NotificationsView} editPath="/settings/notification" endpoint="notifications" />
- </PageLayout>
-);
-
export default NotificationsPage;
diff --git a/modern/src/settings/UsersPage.js b/modern/src/settings/UsersPage.js
index 235ae4c7..059b6bcc 100644
--- a/modern/src/settings/UsersPage.js
+++ b/modern/src/settings/UsersPage.js
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import {
- TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton,
+ TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles,
} from '@material-ui/core';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useEffectAsync } from '../reactHelper';
-import EditCollectionView from './components/EditCollectionView';
import { formatBoolean } from '../common/util/formatter';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -17,10 +17,11 @@ const useStyles = makeStyles((theme) => ({
},
}));
-const UsersView = ({ updateTimestamp, onMenuClick }) => {
+const UsersPage = () => {
const classes = useStyles();
const t = useTranslation();
+ const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
useEffectAsync(async () => {
@@ -30,44 +31,39 @@ const UsersView = ({ updateTimestamp, onMenuClick }) => {
} else {
throw Error(await response.text());
}
- }, [updateTimestamp]);
+ }, [timestamp]);
return (
- <TableContainer>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell className={classes.columnAction} />
- <TableCell>{t('sharedName')}</TableCell>
- <TableCell>{t('userEmail')}</TableCell>
- <TableCell>{t('userAdmin')}</TableCell>
- <TableCell>{t('sharedDisabled')}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {items.map((item) => (
- <TableRow key={item.id}>
- <TableCell className={classes.columnAction} padding="none">
- <IconButton size="small" onClick={(event) => onMenuClick(event.currentTarget, item.id)}>
- <MoreVertIcon />
- </IconButton>
- </TableCell>
- <TableCell>{item.name}</TableCell>
- <TableCell>{item.email}</TableCell>
- <TableCell>{formatBoolean(item.administrator, t)}</TableCell>
- <TableCell>{formatBoolean(item.disabled, t)}</TableCell>
+ <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'settingsUsers']}>
+ <TableContainer>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell className={classes.columnAction} />
+ <TableCell>{t('sharedName')}</TableCell>
+ <TableCell>{t('userEmail')}</TableCell>
+ <TableCell>{t('userAdmin')}</TableCell>
+ <TableCell>{t('sharedDisabled')}</TableCell>
</TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
+ </TableHead>
+ <TableBody>
+ {items.map((item) => (
+ <TableRow key={item.id}>
+ <TableCell className={classes.columnAction} padding="none">
+ <CollectionActions itemId={item.id} editPath="/settings/user" endpoint="users" setTimestamp={setTimestamp} />
+ </TableCell>
+ <TableCell>{item.name}</TableCell>
+ <TableCell>{item.email}</TableCell>
+ <TableCell>{formatBoolean(item.administrator, t)}</TableCell>
+ <TableCell>{formatBoolean(item.disabled, t)}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <CollectionFab editPath="/settings/user" />
+ </PageLayout>
);
};
-const UsersPage = () => (
- <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'settingsUsers']}>
- <EditCollectionView content={UsersView} editPath="/settings/user" endpoint="users" />
- </PageLayout>
-);
-
export default UsersPage;
diff --git a/modern/src/settings/components/CollectionActions.js b/modern/src/settings/components/CollectionActions.js
new file mode 100644
index 00000000..6bf9ddb1
--- /dev/null
+++ b/modern/src/settings/components/CollectionActions.js
@@ -0,0 +1,48 @@
+import React, { useState } from 'react';
+import { IconButton, Menu, MenuItem } from '@material-ui/core';
+import MoreVertIcon from '@material-ui/icons/MoreVert';
+import { useHistory } from 'react-router-dom';
+import RemoveDialog from '../../common/components/RemoveDialog';
+import { useTranslation } from '../../common/components/LocalizationProvider';
+
+const CollectionActions = ({
+ itemId, editPath, endpoint, setTimestamp,
+}) => {
+ const history = useHistory();
+ const t = useTranslation();
+
+ const [menuAnchorEl, setMenuAnchorEl] = useState(null);
+ const [removing, setRemoving] = useState(false);
+
+ const handleEdit = () => {
+ history.push(`${editPath}/${itemId}`);
+ setMenuAnchorEl(null);
+ };
+
+ const handleRemove = () => {
+ setRemoving(true);
+ setMenuAnchorEl(null);
+ };
+
+ const handleRemoveResult = (removed) => {
+ setRemoving(false);
+ if (removed && setTimestamp) {
+ setTimestamp(Date.now());
+ }
+ };
+
+ return (
+ <>
+ <IconButton size="small" onClick={(event) => setMenuAnchorEl(event.currentTarget)}>
+ <MoreVertIcon />
+ </IconButton>
+ <Menu open={!!menuAnchorEl} anchorEl={menuAnchorEl} onClose={() => setMenuAnchorEl(null)}>
+ <MenuItem onClick={handleEdit}>{t('sharedEdit')}</MenuItem>
+ <MenuItem onClick={handleRemove}>{t('sharedRemove')}</MenuItem>
+ </Menu>
+ <RemoveDialog style={{ transform: 'none' }} open={removing} endpoint={endpoint} itemId={itemId} onResult={handleRemoveResult} />
+ </>
+ );
+};
+
+export default CollectionActions;
diff --git a/modern/src/settings/components/CollectionFab.js b/modern/src/settings/components/CollectionFab.js
new file mode 100644
index 00000000..f52bed38
--- /dev/null
+++ b/modern/src/settings/components/CollectionFab.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import { Fab, makeStyles } from '@material-ui/core';
+import AddIcon from '@material-ui/icons/Add';
+import { useHistory } from 'react-router-dom';
+import { useReadonly } from '../../common/util/permissions';
+import dimensions from '../../common/theme/dimensions';
+
+const useStyles = makeStyles((theme) => ({
+ fab: {
+ position: 'fixed',
+ bottom: theme.spacing(2),
+ right: theme.spacing(2),
+ [theme.breakpoints.down('sm')]: {
+ bottom: dimensions.bottomBarHeight + theme.spacing(2),
+ },
+ },
+}));
+
+const CollectionFab = ({ editPath, disabled }) => {
+ const classes = useStyles();
+ const history = useHistory();
+
+ const readonly = useReadonly();
+
+ if (!readonly && !disabled) {
+ return (
+ <Fab size="medium" color="primary" className={classes.fab} onClick={() => history.push(editPath)}>
+ <AddIcon />
+ </Fab>
+ );
+ }
+ return '';
+};
+
+export default CollectionFab;
diff --git a/modern/src/settings/components/EditCollectionView.js b/modern/src/settings/components/EditCollectionView.js
deleted file mode 100644
index b0bf3ea0..00000000
--- a/modern/src/settings/components/EditCollectionView.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import React, { useState } from 'react';
-import { makeStyles } from '@material-ui/core/styles';
-import { useHistory } from 'react-router-dom';
-import Menu from '@material-ui/core/Menu';
-import MenuItem from '@material-ui/core/MenuItem';
-import Fab from '@material-ui/core/Fab';
-import AddIcon from '@material-ui/icons/Add';
-
-import RemoveDialog from '../../common/components/RemoveDialog';
-import { useTranslation } from '../../common/components/LocalizationProvider';
-import dimensions from '../../common/theme/dimensions';
-import { useReadonly } from '../../common/util/permissions';
-
-const useStyles = makeStyles((theme) => ({
- fab: {
- position: 'fixed',
- bottom: theme.spacing(2),
- right: theme.spacing(2),
- [theme.breakpoints.down('sm')]: {
- bottom: dimensions.bottomBarHeight + theme.spacing(2),
- },
- },
-}));
-
-const EditCollectionView = ({
- content, editPath, endpoint, disableAdd, filter,
-}) => {
- const classes = useStyles();
- const history = useHistory();
- const t = useTranslation();
-
- const readonly = useReadonly();
-
- const [selectedId, setSelectedId] = useState(null);
- const [selectedAnchorEl, setSelectedAnchorEl] = useState(null);
- const [removeDialogShown, setRemoveDialogShown] = useState(false);
- const [updateTimestamp, setUpdateTimestamp] = useState(Date.now());
-
- const menuShow = (anchorId, itemId) => {
- setSelectedAnchorEl(anchorId);
- setSelectedId(itemId);
- };
-
- const menuHide = () => {
- setSelectedAnchorEl(null);
- };
-
- const handleAdd = () => {
- history.push(editPath);
- menuHide();
- };
-
- const handleEdit = () => {
- history.push(`${editPath}/${selectedId}`);
- menuHide();
- };
-
- const handleRemove = () => {
- setRemoveDialogShown(true);
- menuHide();
- };
-
- const handleRemoveResult = (removed) => {
- setRemoveDialogShown(false);
- if (removed) {
- setUpdateTimestamp(Date.now());
- }
- };
-
- const Content = content;
-
- return (
- <>
- <Content updateTimestamp={updateTimestamp} onMenuClick={menuShow} filter={filter} />
- {!readonly && !disableAdd && (
- <Fab size="medium" color="primary" className={classes.fab} onClick={handleAdd}>
- <AddIcon />
- </Fab>
- )}
- <Menu open={!!selectedAnchorEl} anchorEl={selectedAnchorEl} onClose={menuHide}>
- <MenuItem onClick={handleEdit}>{t('sharedEdit')}</MenuItem>
- <MenuItem onClick={handleRemove}>{t('sharedRemove')}</MenuItem>
- </Menu>
- <RemoveDialog open={removeDialogShown} endpoint={endpoint} itemId={selectedId} onResult={handleRemoveResult} />
- </>
- );
-};
-
-export default EditCollectionView;