Skip to content

Commit

Permalink
Implement group commands
Browse files Browse the repository at this point in the history
  • Loading branch information
tananaev committed Mar 26, 2023
1 parent e06c03a commit 4e733fb
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 11 deletions.
6 changes: 4 additions & 2 deletions modern/src/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ import { devicesActions } from './store';
import EventPage from './other/EventPage';
import PreferencesPage from './settings/PreferencesPage';
import AccumulatorsPage from './settings/AccumulatorsPage';
import CommandSendPage from './settings/CommandSendPage';
import CommandDevicePage from './settings/CommandDevicePage';
import CommandGroupPage from './settings/CommandGroupPage';
import App from './App';
import ChangeServerPage from './other/ChangeServerPage';
import DevicesPage from './settings/DevicesPage';
Expand Down Expand Up @@ -114,12 +115,12 @@ const Navigation = () => {
<Route path="commands" element={<CommandsPage />} />
<Route path="command/:id" element={<CommandPage />} />
<Route path="command" element={<CommandPage />} />
<Route path="command-send/:deviceId" element={<CommandSendPage />} />
<Route path="attributes" element={<ComputedAttributesPage />} />
<Route path="attribute/:id" element={<ComputedAttributePage />} />
<Route path="attribute" element={<ComputedAttributePage />} />
<Route path="devices" element={<DevicesPage />} />
<Route path="device/:id/connections" element={<DeviceConnectionsPage />} />
<Route path="device/:id/command" element={<CommandDevicePage />} />
<Route path="device/:id" element={<DevicePage />} />
<Route path="device" element={<DevicePage />} />
<Route path="drivers" element={<DriversPage />} />
Expand All @@ -129,6 +130,7 @@ const Navigation = () => {
<Route path="geofence" element={<GeofencePage />} />
<Route path="groups" element={<GroupsPage />} />
<Route path="group/:id/connections" element={<GroupConnectionsPage />} />
<Route path="group/:id/command" element={<CommandGroupPage />} />
<Route path="group/:id" element={<GroupPage />} />
<Route path="group" element={<GroupPage />} />
<Route path="maintenances" element={<MaintenancesPage />} />
Expand Down
2 changes: 1 addition & 1 deletion modern/src/common/components/StatusCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPaddin
<ReplayIcon />
</IconButton>
<IconButton
onClick={() => navigate(`/settings/command-send/${deviceId}`)}
onClick={() => navigate(`/settings/device/${deviceId}/command`)}
disabled={disableActions}
>
<PublishIcon />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ const useStyles = makeStyles((theme) => ({
},
}));

const CommandSendPage = () => {
const CommandDevicePage = () => {
const navigate = useNavigate();
const classes = useStyles();
const t = useTranslation();

const { deviceId } = useParams();
const { id } = useParams();

const [savedId, setSavedId] = useState(0);
const [item, setItem] = useState({});
Expand All @@ -64,7 +64,7 @@ const CommandSendPage = () => {
command = item;
}

command.deviceId = parseInt(deviceId, 10);
command.deviceId = parseInt(id, 10);

const response = await fetch('/api/commands/send', {
method: 'POST',
Expand Down Expand Up @@ -96,12 +96,12 @@ const CommandSendPage = () => {
emptyValue={limitCommands ? null : 0}
emptyTitle={t('sharedNew')}
onChange={(e) => setSavedId(e.target.value)}
endpoint={`/api/commands/send?deviceId=${deviceId}`}
endpoint={`/api/commands/send?deviceId=${id}`}
titleGetter={(it) => it.description}
label={t('sharedSavedCommand')}
/>
{!limitCommands && !savedId && (
<BaseCommandView deviceId={deviceId} item={item} setItem={setItem} />
<BaseCommandView deviceId={id} item={item} setItem={setItem} />
)}
</AccordionDetails>
</Accordion>
Expand Down Expand Up @@ -129,4 +129,4 @@ const CommandSendPage = () => {
);
};

export default CommandSendPage;
export default CommandDevicePage;
121 changes: 121 additions & 0 deletions modern/src/settings/CommandGroupPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
Container,
Button,
FormControl,
InputLabel,
Select,
MenuItem,
FormControlLabel,
Checkbox,
TextField,
} from '@mui/material';
import makeStyles from '@mui/styles/makeStyles';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
import { useCatch } from '../reactHelper';

const useStyles = makeStyles((theme) => ({
container: {
marginTop: theme.spacing(2),
},
buttons: {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
display: 'flex',
justifyContent: 'space-evenly',
'& > *': {
flexBasis: '33%',
},
},
details: {
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
paddingBottom: theme.spacing(3),
},
}));

const CommandDevicePage = () => {
const navigate = useNavigate();
const classes = useStyles();
const t = useTranslation();

const { id } = useParams();

const [item, setItem] = useState({ type: 'custom', attributes: {} });

const handleSend = useCatch(async () => {
const query = new URLSearchParams({ groupId: id });
const response = await fetch(`/api/commands/send?${query.toString()}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(item),
});

if (response.ok) {
navigate(-1);
} else {
throw Error(await response.text());
}
});

return (
<PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'deviceCommand']}>
<Container maxWidth="xs" className={classes.container}>
<Accordion defaultExpanded>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="subtitle1">
{t('sharedRequired')}
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.details}>
<FormControl fullWidth>
<InputLabel>{t('sharedType')}</InputLabel>
<Select label={t('sharedType')} value="custom" disabled>
<MenuItem value="custom">{t('commandCustom')}</MenuItem>
</Select>
</FormControl>
<TextField
value={item.attributes.data}
onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, data: e.target.value } })}
label={t('commandData')}
/>
<FormControlLabel
control={<Checkbox checked={item.textChannel} onChange={(event) => setItem({ ...item, textChannel: event.target.checked })} />}
label={t('commandSendSms')}
/>
</AccordionDetails>
</Accordion>
<div className={classes.buttons}>
<Button
type="button"
color="primary"
variant="outlined"
onClick={() => navigate(-1)}
>
{t('sharedCancel')}
</Button>
<Button
type="button"
color="primary"
variant="contained"
onClick={handleSend}
disabled={!item.attributes.data}
>
{t('commandSend')}
</Button>
</div>
</Container>
</PageLayout>
);
};

export default CommandDevicePage;
13 changes: 12 additions & 1 deletion modern/src/settings/GroupsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Table, TableRow, TableCell, TableHead, TableBody,
} from '@mui/material';
import LinkIcon from '@mui/icons-material/Link';
import PublishIcon from '@mui/icons-material/Publish';
import makeStyles from '@mui/styles/makeStyles';
import { useEffectAsync } from '../reactHelper';
import { useTranslation } from '../common/components/LocalizationProvider';
Expand All @@ -13,6 +14,7 @@ import CollectionFab from './components/CollectionFab';
import CollectionActions from './components/CollectionActions';
import TableShimmer from '../common/components/TableShimmer';
import SearchHeader, { filterByKeyword } from './components/SearchHeader';
import { useRestriction } from '../common/util/permissions';

const useStyles = makeStyles((theme) => ({
columnAction: {
Expand All @@ -26,6 +28,8 @@ const GroupsPage = () => {
const navigate = useNavigate();
const t = useTranslation();

const limitCommands = useRestriction('limitCommands');

const [timestamp, setTimestamp] = useState(Date.now());
const [items, setItems] = useState([]);
const [searchKeyword, setSearchKeyword] = useState('');
Expand All @@ -45,6 +49,13 @@ const GroupsPage = () => {
}
}, [timestamp]);

const actionCommand = {
key: 'command',
title: t('loginLogin'),
icon: <PublishIcon fontSize="small" />,
handler: (groupId) => navigate(`/settings/group/${groupId}/command`),
};

const actionConnections = {
key: 'connections',
title: t('sharedConnections'),
Expand Down Expand Up @@ -72,7 +83,7 @@ const GroupsPage = () => {
editPath="/settings/group"
endpoint="groups"
setTimestamp={setTimestamp}
customActions={[actionConnections]}
customActions={limitCommands ? [actionConnections] : [actionConnections, actionCommand]}
/>
</TableCell>
</TableRow>
Expand Down
2 changes: 1 addition & 1 deletion modern/src/settings/components/SettingsMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const SettingsMenu = () => {
title={t('sharedSavedCommands')}
link="/settings/commands"
icon={<PublishIcon />}
selected={location.pathname.startsWith('/settings/command') && !location.pathname.startsWith('/settings/command-send')}
selected={location.pathname.startsWith('/settings/command')}
/>
</>
)}
Expand Down

0 comments on commit 4e733fb

Please sign in to comment.