aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-06-22 08:35:59 -0700
committerAnton Tananaev <anton@traccar.org>2022-06-22 08:35:59 -0700
commit50a97b2ec3a3a22955cae8bfd6a766b3abb2cf27 (patch)
treef9966709ac4b6db0be873c9113843b02d1b7b1e0
parentb1dd7bfd252278649622c99b4153e9cfa563cd9f (diff)
downloadtrackermap-web-50a97b2ec3a3a22955cae8bfd6a766b3abb2cf27.tar.gz
trackermap-web-50a97b2ec3a3a22955cae8bfd6a766b3abb2cf27.tar.bz2
trackermap-web-50a97b2ec3a3a22955cae8bfd6a766b3abb2cf27.zip
Login as another user
-rw-r--r--modern/src/settings/UsersPage.js37
-rw-r--r--modern/src/settings/components/CollectionActions.js15
2 files changed, 49 insertions, 3 deletions
diff --git a/modern/src/settings/UsersPage.js b/modern/src/settings/UsersPage.js
index a274d569..0d8a077c 100644
--- a/modern/src/settings/UsersPage.js
+++ b/modern/src/settings/UsersPage.js
@@ -1,9 +1,12 @@
import React, { useState } from 'react';
+import { useDispatch } from 'react-redux';
+import { useNavigate } from 'react-router-dom';
import {
Table, TableRow, TableCell, TableHead, TableBody,
} from '@mui/material';
+import LoginIcon from '@mui/icons-material/Login';
import makeStyles from '@mui/styles/makeStyles';
-import { useEffectAsync } from '../reactHelper';
+import { useCatch, useEffectAsync } from '../reactHelper';
import { formatBoolean } from '../common/util/formatter';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
@@ -11,6 +14,8 @@ import SettingsMenu from './components/SettingsMenu';
import CollectionFab from './components/CollectionFab';
import CollectionActions from './components/CollectionActions';
import TableShimmer from '../common/components/TableShimmer';
+import { useAdministrator } from '../common/util/permissions';
+import { sessionActions } from '../store';
const useStyles = makeStyles((theme) => ({
columnAction: {
@@ -21,12 +26,33 @@ const useStyles = makeStyles((theme) => ({
const UsersPage = () => {
const classes = useStyles();
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
const t = useTranslation();
+ const admin = useAdministrator();
+
const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
+ const handleLogin = useCatch(async (userId) => {
+ const response = await fetch(`/api/session/${userId}`);
+ if (response.ok) {
+ const user = await response.json();
+ dispatch(sessionActions.updateUser(user));
+ navigate('/');
+ } else {
+ throw Error(await response.text());
+ }
+ });
+
+ const loginAction = {
+ title: t('loginLogin'),
+ icon: (<LoginIcon fontSize="small" />),
+ handler: handleLogin,
+ };
+
useEffectAsync(async () => {
setLoading(true);
try {
@@ -61,7 +87,14 @@ const UsersPage = () => {
<TableCell>{formatBoolean(item.administrator, t)}</TableCell>
<TableCell>{formatBoolean(item.disabled, t)}</TableCell>
<TableCell className={classes.columnAction} padding="none">
- <CollectionActions itemId={item.id} editPath="/settings/user" endpoint="users" setTimestamp={setTimestamp} />
+ {admin}
+ <CollectionActions
+ itemId={item.id}
+ editPath="/settings/user"
+ endpoint="users"
+ setTimestamp={setTimestamp}
+ customAction={admin ? loginAction : null}
+ />
</TableCell>
</TableRow>
)) : (<TableShimmer columns={5} endAction />)}
diff --git a/modern/src/settings/components/CollectionActions.js b/modern/src/settings/components/CollectionActions.js
index e69553bd..e40b3eaa 100644
--- a/modern/src/settings/components/CollectionActions.js
+++ b/modern/src/settings/components/CollectionActions.js
@@ -17,7 +17,7 @@ const useStyles = makeStyles(() => ({
}));
const CollectionActions = ({
- itemId, editPath, endpoint, setTimestamp,
+ itemId, editPath, endpoint, setTimestamp, customAction,
}) => {
const theme = useTheme();
const classes = useStyles();
@@ -39,6 +39,11 @@ const CollectionActions = ({
setMenuAnchorEl(null);
};
+ const handleCustom = () => {
+ customAction.handler(itemId);
+ setMenuAnchorEl(null);
+ };
+
const handleRemoveResult = (removed) => {
setRemoving(false);
if (removed) {
@@ -54,12 +59,20 @@ const CollectionActions = ({
<MoreVertIcon fontSize="small" />
</IconButton>
<Menu open={!!menuAnchorEl} anchorEl={menuAnchorEl} onClose={() => setMenuAnchorEl(null)}>
+ {customAction && (
+ <MenuItem onClick={handleCustom}>{customAction.title}</MenuItem>
+ )}
<MenuItem onClick={handleEdit}>{t('sharedEdit')}</MenuItem>
<MenuItem onClick={handleRemove}>{t('sharedRemove')}</MenuItem>
</Menu>
</>
) : (
<div className={classes.row}>
+ {customAction && (
+ <IconButton size="small" onClick={handleCustom}>
+ {customAction.icon}
+ </IconButton>
+ )}
<IconButton size="small" onClick={handleEdit}>
<EditIcon fontSize="small" />
</IconButton>