diff options
author | Anton Tananaev <anton@traccar.org> | 2022-05-23 17:28:00 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-05-23 17:28:00 -0700 |
commit | ae22e17de1d9745b0f49c09ccc11ea92dd976907 (patch) | |
tree | 4f2df47079cd519aa55a35448c5635caa8ee24ba /modern/src/settings | |
parent | 6007d38d572066d3aa6381964a863f2b291c8903 (diff) | |
download | trackermap-web-ae22e17de1d9745b0f49c09ccc11ea92dd976907.tar.gz trackermap-web-ae22e17de1d9745b0f49c09ccc11ea92dd976907.tar.bz2 trackermap-web-ae22e17de1d9745b0f49c09ccc11ea92dd976907.zip |
Fix forms
Diffstat (limited to 'modern/src/settings')
-rw-r--r-- | modern/src/settings/AccumulatorsPage.js | 46 | ||||
-rw-r--r-- | modern/src/settings/CalendarPage.js | 6 | ||||
-rw-r--r-- | modern/src/settings/CommandPage.js | 6 | ||||
-rw-r--r-- | modern/src/settings/CommandSendPage.js | 47 | ||||
-rw-r--r-- | modern/src/settings/ComputedAttributePage.js | 10 | ||||
-rw-r--r-- | modern/src/settings/DevicePage.js | 18 | ||||
-rw-r--r-- | modern/src/settings/DriverPage.js | 7 | ||||
-rw-r--r-- | modern/src/settings/GeofencePage.js | 6 | ||||
-rw-r--r-- | modern/src/settings/GroupPage.js | 13 | ||||
-rw-r--r-- | modern/src/settings/MaintenancePage.js | 10 | ||||
-rw-r--r-- | modern/src/settings/NotificationPage.js | 45 | ||||
-rw-r--r-- | modern/src/settings/PreferencesPage.js | 34 | ||||
-rw-r--r-- | modern/src/settings/ServerPage.js | 99 | ||||
-rw-r--r-- | modern/src/settings/UserPage.js | 113 | ||||
-rw-r--r-- | modern/src/settings/components/BaseCommandView.js | 2 | ||||
-rw-r--r-- | modern/src/settings/components/EditAttributesView.js | 12 | ||||
-rw-r--r-- | modern/src/settings/components/EditItemView.js | 43 |
17 files changed, 252 insertions, 265 deletions
diff --git a/modern/src/settings/AccumulatorsPage.js b/modern/src/settings/AccumulatorsPage.js index ce2d18a2..37c77d5a 100644 --- a/modern/src/settings/AccumulatorsPage.js +++ b/modern/src/settings/AccumulatorsPage.js @@ -8,7 +8,6 @@ import { Typography, Container, TextField, - FormControl, Button, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; @@ -23,6 +22,8 @@ const useStyles = makeStyles((theme) => ({ marginTop: theme.spacing(2), }, buttons: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), display: 'flex', justifyContent: 'space-evenly', '& > *': { @@ -30,7 +31,10 @@ const useStyles = makeStyles((theme) => ({ }, }, details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -80,14 +84,12 @@ const AccumulatorsPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" type="number" value={item.hours} onChange={(event) => setItem({ ...item, hours: Number(event.target.value) })} label={t('positionHours')} /> <TextField - margin="normal" type="number" value={item.totalDistance} onChange={(event) => setItem({ ...item, totalDistance: Number(event.target.value) })} @@ -95,26 +97,24 @@ const AccumulatorsPage = () => { /> </AccordionDetails> </Accordion> - <FormControl fullWidth margin="normal"> - <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={handleSave} - > - {t('sharedSave')} - </Button> - </div> - </FormControl> + <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={handleSave} + > + {t('sharedSave')} + </Button> + </div> </Container> )} </PageLayout> diff --git a/modern/src/settings/CalendarPage.js b/modern/src/settings/CalendarPage.js index 1d967a35..8bfcd50d 100644 --- a/modern/src/settings/CalendarPage.js +++ b/modern/src/settings/CalendarPage.js @@ -11,9 +11,12 @@ import EditAttributesView from './components/EditAttributesView'; import { useTranslation } from '../common/components/LocalizationProvider'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -57,7 +60,6 @@ const CalendarPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} diff --git a/modern/src/settings/CommandPage.js b/modern/src/settings/CommandPage.js index 5c306e4c..1d788610 100644 --- a/modern/src/settings/CommandPage.js +++ b/modern/src/settings/CommandPage.js @@ -9,9 +9,12 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import BaseCommandView from './components/BaseCommandView'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -41,7 +44,6 @@ const CommandPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.description || ''} onChange={(event) => setItem({ ...item, description: event.target.value })} label={t('sharedDescription')} diff --git a/modern/src/settings/CommandSendPage.js b/modern/src/settings/CommandSendPage.js index 29c9df46..55e26ec8 100644 --- a/modern/src/settings/CommandSendPage.js +++ b/modern/src/settings/CommandSendPage.js @@ -7,7 +7,6 @@ import { Typography, Container, Button, - FormControl, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; @@ -23,6 +22,8 @@ const useStyles = makeStyles((theme) => ({ marginTop: theme.spacing(2), }, buttons: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), display: 'flex', justifyContent: 'space-evenly', '& > *': { @@ -30,7 +31,10 @@ const useStyles = makeStyles((theme) => ({ }, }, details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -85,7 +89,6 @@ const CommandSendPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <SelectField - margin="normal" value={savedId} emptyTitle={t('sharedNew')} onChange={(e) => setSavedId(e.target.value)} @@ -98,27 +101,25 @@ const CommandSendPage = () => { )} </AccordionDetails> </Accordion> - <FormControl fullWidth margin="normal"> - <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={!validate()} - > - {t('commandSend')} - </Button> - </div> - </FormControl> + <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={!validate()} + > + {t('commandSend')} + </Button> + </div> </Container> </PageLayout> ); diff --git a/modern/src/settings/ComputedAttributePage.js b/modern/src/settings/ComputedAttributePage.js index ba5fe712..da92ad80 100644 --- a/modern/src/settings/ComputedAttributePage.js +++ b/modern/src/settings/ComputedAttributePage.js @@ -17,9 +17,12 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -69,12 +72,11 @@ const ComputedAttributePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.description || ''} onChange={(event) => setItem({ ...item, description: event.target.value })} label={t('sharedDescription')} /> - <FormControl margin="normal" fullWidth> + <FormControl> <InputLabel>{t('sharedAttribute')}</InputLabel> <Select label={t('sharedAttribute')} @@ -87,7 +89,6 @@ const ComputedAttributePage = () => { </Select> </FormControl> <TextField - margin="normal" value={item.expression || ''} onChange={(event) => setItem({ ...item, expression: event.target.value })} label={t('sharedExpression')} @@ -95,7 +96,6 @@ const ComputedAttributePage = () => { rows={4} /> <FormControl - margin="normal" fullWidth disabled={key in positionAttributes} > diff --git a/modern/src/settings/DevicePage.js b/modern/src/settings/DevicePage.js index 3f194570..d7b67b0b 100644 --- a/modern/src/settings/DevicePage.js +++ b/modern/src/settings/DevicePage.js @@ -23,9 +23,12 @@ import { useAdministrator } from '../common/util/permissions'; import SettingsMenu from './components/SettingsMenu'; import useCommonDeviceAttributes from '../common/attributes/useCommonDeviceAttributes'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -61,13 +64,11 @@ const DevicePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} /> <TextField - margin="normal" value={item.uniqueId || ''} onChange={(event) => setItem({ ...item, uniqueId: event.target.value })} label={t('deviceIdentifier')} @@ -82,32 +83,27 @@ const DevicePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <SelectField - margin="normal" value={item.groupId || 0} onChange={(event) => setItem({ ...item, groupId: Number(event.target.value) })} endpoint="/api/groups" label={t('groupParent')} /> <TextField - margin="normal" value={item.phone || ''} onChange={(event) => setItem({ ...item, phone: event.target.value })} label={t('sharedPhone')} /> <TextField - margin="normal" value={item.model || ''} onChange={(event) => setItem({ ...item, model: event.target.value })} label={t('deviceModel')} /> <TextField - margin="normal" value={item.contact || ''} onChange={(event) => setItem({ ...item, contact: event.target.value })} label={t('deviceContact')} /> <SelectField - margin="normal" value={item.category || 'default'} emptyValue={null} onChange={(event) => setItem({ ...item, category: event.target.value })} @@ -148,7 +144,6 @@ const DevicePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <LinkField - margin="normal" endpointAll="/api/geofences" endpointLinked={`/api/geofences?deviceId=${item.id}`} baseId={item.id} @@ -157,7 +152,6 @@ const DevicePage = () => { label={t('sharedGeofences')} /> <LinkField - margin="normal" endpointAll="/api/notifications" endpointLinked={`/api/notifications?deviceId=${item.id}`} baseId={item.id} @@ -167,7 +161,6 @@ const DevicePage = () => { label={t('sharedNotifications')} /> <LinkField - margin="normal" endpointAll="/api/drivers" endpointLinked={`/api/drivers?deviceId=${item.id}`} baseId={item.id} @@ -176,7 +169,6 @@ const DevicePage = () => { label={t('sharedDrivers')} /> <LinkField - margin="normal" endpointAll="/api/attributes/computed" endpointLinked={`/api/attributes/computed?deviceId=${item.id}`} baseId={item.id} @@ -186,7 +178,6 @@ const DevicePage = () => { label={t('sharedComputedAttributes')} /> <LinkField - margin="normal" endpointAll="/api/commands" endpointLinked={`/api/commands?deviceId=${item.id}`} baseId={item.id} @@ -196,7 +187,6 @@ const DevicePage = () => { label={t('sharedSavedCommands')} /> <LinkField - margin="normal" endpointAll="/api/maintenance" endpointLinked={`/api/maintenance?deviceId=${item.id}`} baseId={item.id} diff --git a/modern/src/settings/DriverPage.js b/modern/src/settings/DriverPage.js index 707e2977..30f5106f 100644 --- a/modern/src/settings/DriverPage.js +++ b/modern/src/settings/DriverPage.js @@ -10,9 +10,12 @@ import EditAttributesView from './components/EditAttributesView'; import { useTranslation } from '../common/components/LocalizationProvider'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -43,13 +46,11 @@ const DriverPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} /> <TextField - margin="normal" value={item.uniqueId || ''} onChange={(event) => setItem({ ...item, uniqueId: event.target.value })} label={t('deviceIdentifier')} diff --git a/modern/src/settings/GeofencePage.js b/modern/src/settings/GeofencePage.js index 353eb2b8..f372adb6 100644 --- a/modern/src/settings/GeofencePage.js +++ b/modern/src/settings/GeofencePage.js @@ -12,9 +12,12 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import useGeofenceAttributes from '../common/attributes/useGeofenceAttributes'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -47,7 +50,6 @@ const GeofencePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} diff --git a/modern/src/settings/GroupPage.js b/modern/src/settings/GroupPage.js index 3f4cc8d8..b817ba7e 100644 --- a/modern/src/settings/GroupPage.js +++ b/modern/src/settings/GroupPage.js @@ -16,9 +16,12 @@ import useCommonDeviceAttributes from '../common/attributes/useCommonDeviceAttri import useGroupAttributes from '../common/attributes/useGroupAttributes'; import { prefixString } from '../common/util/stringUtils'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -52,7 +55,6 @@ const GroupPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} @@ -67,7 +69,6 @@ const GroupPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <SelectField - margin="normal" value={item.groupId || 0} onChange={(event) => setItem({ ...item, groupId: Number(event.target.value) })} endpoint="/api/groups" @@ -98,7 +99,6 @@ const GroupPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <LinkField - margin="normal" endpointAll="/api/geofences" endpointLinked={`/api/geofences?groupId=${item.id}`} baseId={item.id} @@ -107,7 +107,6 @@ const GroupPage = () => { label={t('sharedGeofences')} /> <LinkField - margin="normal" endpointAll="/api/notifications" endpointLinked={`/api/notifications?groupId=${item.id}`} baseId={item.id} @@ -117,7 +116,6 @@ const GroupPage = () => { label={t('sharedNotifications')} /> <LinkField - margin="normal" endpointAll="/api/drivers" endpointLinked={`/api/drivers?groupId=${item.id}`} baseId={item.id} @@ -126,7 +124,6 @@ const GroupPage = () => { label={t('sharedDrivers')} /> <LinkField - margin="normal" endpointAll="/api/attributes/computed" endpointLinked={`/api/attributes/computed?groupId=${item.id}`} baseId={item.id} @@ -136,7 +133,6 @@ const GroupPage = () => { label={t('sharedComputedAttributes')} /> <LinkField - margin="normal" endpointAll="/api/commands" endpointLinked={`/api/commands?groupId=${item.id}`} baseId={item.id} @@ -146,7 +142,6 @@ const GroupPage = () => { label={t('sharedSavedCommands')} /> <LinkField - margin="normal" endpointAll="/api/maintenance" endpointLinked={`/api/maintenance?groupId=${item.id}`} baseId={item.id} diff --git a/modern/src/settings/MaintenancePage.js b/modern/src/settings/MaintenancePage.js index 5694d77b..d2cf02d9 100644 --- a/modern/src/settings/MaintenancePage.js +++ b/modern/src/settings/MaintenancePage.js @@ -24,9 +24,12 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; import SettingsMenu from './components/SettingsMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -125,12 +128,11 @@ const MaintenancePage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} /> - <FormControl margin="normal" fullWidth> + <FormControl> <InputLabel>{t('sharedType')}</InputLabel> <Select label={t('sharedType')} @@ -143,7 +145,6 @@ const MaintenancePage = () => { </Select> </FormControl> <TextField - margin="normal" type="number" value={rawToValue(item.start) || ''} onChange={(event) => setItem({ ...item, start: valueToRaw(event.target.value) })} @@ -153,7 +154,6 @@ const MaintenancePage = () => { }} /> <TextField - margin="normal" type="number" value={rawToValue(item.period) || ''} onChange={(event) => setItem({ ...item, period: valueToRaw(event.target.value) })} diff --git a/modern/src/settings/NotificationPage.js b/modern/src/settings/NotificationPage.js index a7c06f68..d307be9b 100644 --- a/modern/src/settings/NotificationPage.js +++ b/modern/src/settings/NotificationPage.js @@ -15,10 +15,14 @@ import EditItemView from './components/EditItemView'; import { prefixString, unprefixString } from '../common/util/stringUtils'; import SelectField from '../common/components/SelectField'; import SettingsMenu from './components/SettingsMenu'; +import { FormGroup } from '@material-ui/core'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -53,7 +57,6 @@ const NotificationPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <SelectField - margin="normal" value={item.type} emptyValue={null} onChange={(e) => setItem({ ...item, type: e.target.value })} @@ -64,7 +67,6 @@ const NotificationPage = () => { /> <SelectField multiple - margin="normal" value={item.notificators ? item.notificators.split(/[, ]+/) : []} onChange={(e) => setItem({ ...item, notificators: e.target.value.join() })} endpoint="/api/notifications/notificators" @@ -73,25 +75,26 @@ const NotificationPage = () => { label={t('notificationNotificators')} /> {(!item.type || item.type === 'alarm') && ( - <SelectField - multiple - margin="normal" - 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.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')} + /> )} - <FormControlLabel - control={( - <Checkbox - checked={item.always} - onChange={(event) => setItem({ ...item, always: event.target.checked })} - /> - )} - label={t('notificationAlways')} - /> + <FormGroup> + <FormControlLabel + control={( + <Checkbox + checked={item.always} + onChange={(event) => setItem({ ...item, always: event.target.checked })} + /> + )} + label={t('notificationAlways')} + /> + </FormGroup> </AccordionDetails> </Accordion> )} diff --git a/modern/src/settings/PreferencesPage.js b/modern/src/settings/PreferencesPage.js index 93ded1f0..e6638fe5 100644 --- a/modern/src/settings/PreferencesPage.js +++ b/modern/src/settings/PreferencesPage.js @@ -19,13 +19,17 @@ import usePersistedState from '../common/util/usePersistedState'; import PageLayout from '../common/components/PageLayout'; import SettingsMenu from './components/SettingsMenu'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; +import { FormGroup } from '@material-ui/core'; const useStyles = makeStyles((theme) => ({ container: { marginTop: theme.spacing(2), }, details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -53,7 +57,7 @@ const PreferencesPage = () => { </Typography> </AccordionSummary> <AccordionDetails className={classes.details}> - <FormControl fullWidth> + <FormControl> <InputLabel>{t('loginLanguage')}</InputLabel> <Select label={t('loginLanguage')} @@ -72,7 +76,7 @@ const PreferencesPage = () => { </Typography> </AccordionSummary> <AccordionDetails className={classes.details}> - <FormControl fullWidth> + <FormControl> <InputLabel>{t('sharedAttributes')}</InputLabel> <Select label={t('sharedAttributes')} @@ -86,18 +90,20 @@ const PreferencesPage = () => { ))} </Select> </FormControl> - <FormControlLabel - control={<Checkbox checked={mapLiveRoutes} onChange={(event) => setMapLiveRoutes(event.target.checked)} />} - label={t('mapLiveRoutes')} - /> - <FormControlLabel - control={<Checkbox checked={mapFollow} onChange={(event) => setMapFollow(event.target.checked)} />} - label={t('deviceFollow')} - /> - <FormControlLabel - control={<Checkbox checked={mapCluster} onChange={(event) => setMapCluster(event.target.checked)} />} - label={t('mapClustering')} - /> + <FormGroup> + <FormControlLabel + control={<Checkbox checked={mapLiveRoutes} onChange={(event) => setMapLiveRoutes(event.target.checked)} />} + label={t('mapLiveRoutes')} + /> + <FormControlLabel + control={<Checkbox checked={mapFollow} onChange={(event) => setMapFollow(event.target.checked)} />} + label={t('deviceFollow')} + /> + <FormControlLabel + control={<Checkbox checked={mapCluster} onChange={(event) => setMapCluster(event.target.checked)} />} + label={t('mapClustering')} + /> + </FormGroup> </AccordionDetails> </Accordion> </Container> diff --git a/modern/src/settings/ServerPage.js b/modern/src/settings/ServerPage.js index 80353deb..7bc2b203 100644 --- a/modern/src/settings/ServerPage.js +++ b/modern/src/settings/ServerPage.js @@ -28,12 +28,15 @@ import SettingsMenu from './components/SettingsMenu'; import useCommonDeviceAttributes from '../common/attributes/useCommonDeviceAttributes'; import useCommonUserAttributes from '../common/attributes/useCommonUserAttributes'; import { useCatch } from '../reactHelper'; +import { FormGroup } from '@material-ui/core'; const useStyles = makeStyles((theme) => ({ container: { marginTop: theme.spacing(2), }, buttons: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), display: 'flex', justifyContent: 'space-evenly', '& > *': { @@ -41,7 +44,10 @@ const useStyles = makeStyles((theme) => ({ }, }, details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -85,33 +91,29 @@ const ServerPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.mapUrl || ''} onChange={(event) => setItem({ ...item, mapUrl: event.target.value })} label={t('mapCustomLabel')} /> <TextField - margin="normal" type="number" value={item.latitude || 0} onChange={(event) => setItem({ ...item, latitude: Number(event.target.value) })} label={t('positionLatitude')} /> <TextField - margin="normal" type="number" value={item.longitude || 0} onChange={(event) => setItem({ ...item, longitude: Number(event.target.value) })} label={t('positionLongitude')} /> <TextField - margin="normal" type="number" value={item.zoom || 0} onChange={(event) => setItem({ ...item, zoom: Number(event.target.value) })} label={t('serverZoom')} /> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsCoordinateFormat')}</InputLabel> <Select label={t('settingsCoordinateFormat')} @@ -123,7 +125,7 @@ const ServerPage = () => { <MenuItem value="dms">{t('sharedDegreesMinutesSeconds')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsSpeedUnit')}</InputLabel> <Select label={t('settingsSpeedUnit')} @@ -135,7 +137,7 @@ const ServerPage = () => { <MenuItem value="mph">{t('sharedMph')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsDistanceUnit')}</InputLabel> <Select label={t('settingsDistanceUnit')} @@ -147,7 +149,7 @@ const ServerPage = () => { <MenuItem value="nmi">{t('sharedNmi')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsVolumeUnit')}</InputLabel> <Select label={t('settingsVolumeUnit')} @@ -160,7 +162,6 @@ const ServerPage = () => { </Select> </FormControl> <SelectField - margin="normal" value={item.attributes.timezone || ''} emptyValue="" onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, timezone: e.target.value } })} @@ -170,25 +171,25 @@ const ServerPage = () => { label={t('sharedTimezone')} /> <TextField - margin="normal" value={item.poiLayer || ''} onChange={(event) => setItem({ ...item, poiLayer: event.target.value })} label={t('mapPoiLayer')} /> <TextField - margin="normal" value={item.announcement || ''} onChange={(event) => setItem({ ...item, announcement: event.target.value })} label={t('serverAnnouncement')} /> - <FormControlLabel - control={<Checkbox checked={item.twelveHourFormat} onChange={(event) => setItem({ ...item, twelveHourFormat: event.target.checked })} />} - label={t('settingsTwelveHourFormat')} - /> - <FormControlLabel - control={<Checkbox checked={item.forceSettings} onChange={(event) => setItem({ ...item, forceSettings: event.target.checked })} />} - label={t('serverForceSettings')} - /> + <FormGroup> + <FormControlLabel + control={<Checkbox checked={item.twelveHourFormat} onChange={(event) => setItem({ ...item, twelveHourFormat: event.target.checked })} />} + label={t('settingsTwelveHourFormat')} + /> + <FormControlLabel + control={<Checkbox checked={item.forceSettings} onChange={(event) => setItem({ ...item, forceSettings: event.target.checked })} />} + label={t('serverForceSettings')} + /> + </FormGroup> </AccordionDetails> </Accordion> <Accordion> @@ -198,26 +199,28 @@ const ServerPage = () => { </Typography> </AccordionSummary> <AccordionDetails className={classes.details}> - <FormControlLabel - control={<Checkbox checked={item.registration} onChange={(event) => setItem({ ...item, registration: event.target.checked })} />} - label={t('serverRegistration')} - /> - <FormControlLabel - control={<Checkbox checked={item.readonly} onChange={(event) => setItem({ ...item, readonly: event.target.checked })} />} - label={t('serverReadonly')} - /> - <FormControlLabel - control={<Checkbox checked={item.deviceReadonly} onChange={(event) => setItem({ ...item, deviceReadonly: event.target.checked })} />} - label={t('userDeviceReadonly')} - /> - <FormControlLabel - control={<Checkbox checked={item.limitCommands} onChange={(event) => setItem({ ...item, limitCommands: event.target.checked })} />} - label={t('userLimitCommands')} - /> - <FormControlLabel - control={<Checkbox checked={item.disableReports} onChange={(event) => setItem({ ...item, disableReports: event.target.checked })} />} - label={t('userDisableReports')} - /> + <FormGroup> + <FormControlLabel + control={<Checkbox checked={item.registration} onChange={(event) => setItem({ ...item, registration: event.target.checked })} />} + label={t('serverRegistration')} + /> + <FormControlLabel + control={<Checkbox checked={item.readonly} onChange={(event) => setItem({ ...item, readonly: event.target.checked })} />} + label={t('serverReadonly')} + /> + <FormControlLabel + control={<Checkbox checked={item.deviceReadonly} onChange={(event) => setItem({ ...item, deviceReadonly: event.target.checked })} />} + label={t('userDeviceReadonly')} + /> + <FormControlLabel + control={<Checkbox checked={item.limitCommands} onChange={(event) => setItem({ ...item, limitCommands: event.target.checked })} />} + label={t('userLimitCommands')} + /> + <FormControlLabel + control={<Checkbox checked={item.disableReports} onChange={(event) => setItem({ ...item, disableReports: event.target.checked })} />} + label={t('userDisableReports')} + /> + </FormGroup> </AccordionDetails> </Accordion> <Accordion> @@ -236,16 +239,14 @@ const ServerPage = () => { </Accordion> </> )} - <FormControl fullWidth margin="normal"> - <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={handleSave}> - {t('sharedSave')} - </Button> - </div> - </FormControl> + <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={handleSave}> + {t('sharedSave')} + </Button> + </div> </Container> </PageLayout> ); diff --git a/modern/src/settings/UserPage.js b/modern/src/settings/UserPage.js index d9238c22..f8361399 100644 --- a/modern/src/settings/UserPage.js +++ b/modern/src/settings/UserPage.js @@ -32,10 +32,14 @@ import SettingsMenu from './components/SettingsMenu'; import useCommonUserAttributes from '../common/attributes/useCommonUserAttributes'; import { useAdministrator, useManager } from '../common/util/permissions'; import { prefixString } from '../common/util/stringUtils'; +import { FormGroup } from '@material-ui/core'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles((theme) => ({ details: { + display: 'flex', flexDirection: 'column', + gap: theme.spacing(2), + paddingBottom: theme.spacing(3), }, })); @@ -83,19 +87,16 @@ const UserPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.name || ''} onChange={(event) => setItem({ ...item, name: event.target.value })} label={t('sharedName')} /> <TextField - margin="normal" value={item.email || ''} onChange={(event) => setItem({ ...item, email: event.target.value })} label={t('userEmail')} /> <TextField - margin="normal" type="password" onChange={(event) => setItem({ ...item, password: event.target.value })} label={t('userPassword')} @@ -110,33 +111,29 @@ const UserPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <TextField - margin="normal" value={item.phone || ''} onChange={(event) => setItem({ ...item, phone: event.target.value })} label={t('sharedPhone')} /> <TextField - margin="normal" type="number" value={item.latitude || 0} onChange={(event) => setItem({ ...item, latitude: Number(event.target.value) })} label={t('positionLatitude')} /> <TextField - margin="normal" type="number" value={item.longitude || 0} onChange={(event) => setItem({ ...item, longitude: Number(event.target.value) })} label={t('positionLongitude')} /> <TextField - margin="normal" type="number" value={item.zoom || 0} onChange={(event) => setItem({ ...item, zoom: Number(event.target.value) })} label={t('serverZoom')} /> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsCoordinateFormat')}</InputLabel> <Select label={t('settingsCoordinateFormat')} @@ -148,7 +145,7 @@ const UserPage = () => { <MenuItem value="dms">{t('sharedDegreesMinutesSeconds')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsSpeedUnit')}</InputLabel> <Select label={t('settingsSpeedUnit')} @@ -160,7 +157,7 @@ const UserPage = () => { <MenuItem value="mph">{t('sharedMph')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsDistanceUnit')}</InputLabel> <Select label={t('settingsDistanceUnit')} @@ -172,7 +169,7 @@ const UserPage = () => { <MenuItem value="nmi">{t('sharedNmi')}</MenuItem> </Select> </FormControl> - <FormControl margin="normal" fullWidth> + <FormControl fullWidth> <InputLabel>{t('settingsVolumeUnit')}</InputLabel> <Select label={t('settingsVolumeUnit')} @@ -185,7 +182,6 @@ const UserPage = () => { </Select> </FormControl> <SelectField - margin="normal" value={(item.attributes && item.attributes.timezone) || ''} emptyValue="" onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, timezone: e.target.value } })} @@ -195,15 +191,16 @@ const UserPage = () => { label={t('sharedTimezone')} /> <TextField - margin="normal" value={item.poiLayer || ''} onChange={(event) => setItem({ ...item, poiLayer: event.target.value })} label={t('mapPoiLayer')} /> - <FormControlLabel - control={<Checkbox checked={item.twelveHourFormat} onChange={(event) => setItem({ ...item, twelveHourFormat: event.target.checked })} />} - label={t('settingsTwelveHourFormat')} - /> + <FormGroup> + <FormControlLabel + control={<Checkbox checked={item.twelveHourFormat} onChange={(event) => setItem({ ...item, twelveHourFormat: event.target.checked })} />} + label={t('settingsTwelveHourFormat')} + /> + </FormGroup> </AccordionDetails> </Accordion> <Accordion> @@ -213,7 +210,7 @@ const UserPage = () => { </Typography> </AccordionSummary> <AccordionDetails className={classes.details}> - <FormControl margin="normal"> + <FormControl> <InputLabel>{t('userToken')}</InputLabel> <OutlinedInput type="text" @@ -222,19 +219,19 @@ const UserPage = () => { endAdornment={( <InputAdornment position="end"> <IconButton + size="small" onClick={() => { const token = [...Array(30)].map(() => Math.random().toString(36)[2]).join(''); setItem({ ...item, token }); }} > - <CachedIcon /> + <CachedIcon fontSize="small" /> </IconButton> </InputAdornment> )} /> </FormControl> <TextField - margin="normal" label={t('userExpirationTime')} type="date" value={(item.expirationTime && item.expirationTime.format(moment.HTML5_FMT.DATE)) || '2999-01-01'} @@ -242,7 +239,6 @@ const UserPage = () => { disabled={!manager} /> <TextField - margin="normal" type="number" value={item.deviceLimit || 0} onChange={(e) => setItem({ ...item, deviceLimit: Number(e.target.value) })} @@ -250,43 +246,44 @@ const UserPage = () => { disabled={!admin} /> <TextField - margin="normal" type="number" value={item.userLimit || 0} onChange={(e) => setItem({ ...item, userLimit: Number(e.target.value) })} label={t('userUserLimit')} disabled={!admin} /> - <FormControlLabel - control={<Checkbox checked={item.disabled} onChange={(e) => setItem({ ...item, disabled: e.target.checked })} />} - label={t('sharedDisabled')} - disabled={!manager} - /> - <FormControlLabel - control={<Checkbox checked={item.administrator} onChange={(e) => setItem({ ...item, administrator: e.target.checked })} />} - label={t('userAdmin')} - disabled={!admin} - /> - <FormControlLabel - control={<Checkbox checked={item.readonly} onChange={(e) => setItem({ ...item, readonly: e.target.checked })} />} - label={t('serverReadonly')} - disabled={!manager} - /> - <FormControlLabel - control={<Checkbox checked={item.deviceReadonly} onChange={(e) => setItem({ ...item, deviceReadonly: e.target.checked })} />} - label={t('userDeviceReadonly')} - disabled={!manager} - /> - <FormControlLabel - control={<Checkbox checked={item.limitCommands} onChange={(e) => setItem({ ...item, limitCommands: e.target.checked })} />} - label={t('userLimitCommands')} - disabled={!manager} - /> - <FormControlLabel - control={<Checkbox checked={item.disableReports} onChange={(e) => setItem({ ...item, disableReports: e.target.checked })} />} - label={t('userDisableReports')} - disabled={!manager} - /> + <FormGroup> + <FormControlLabel + control={<Checkbox checked={item.disabled} onChange={(e) => setItem({ ...item, disabled: e.target.checked })} />} + label={t('sharedDisabled')} + disabled={!manager} + /> + <FormControlLabel + control={<Checkbox checked={item.administrator} onChange={(e) => setItem({ ...item, administrator: e.target.checked })} />} + label={t('userAdmin')} + disabled={!admin} + /> + <FormControlLabel + control={<Checkbox checked={item.readonly} onChange={(e) => setItem({ ...item, readonly: e.target.checked })} />} + label={t('serverReadonly')} + disabled={!manager} + /> + <FormControlLabel + control={<Checkbox checked={item.deviceReadonly} onChange={(e) => setItem({ ...item, deviceReadonly: e.target.checked })} />} + label={t('userDeviceReadonly')} + disabled={!manager} + /> + <FormControlLabel + control={<Checkbox checked={item.limitCommands} onChange={(e) => setItem({ ...item, limitCommands: e.target.checked })} />} + label={t('userLimitCommands')} + disabled={!manager} + /> + <FormControlLabel + control={<Checkbox checked={item.disableReports} onChange={(e) => setItem({ ...item, disableReports: e.target.checked })} />} + label={t('userDisableReports')} + disabled={!manager} + /> + </FormGroup> </AccordionDetails> </Accordion> <Accordion> @@ -312,7 +309,6 @@ const UserPage = () => { </AccordionSummary> <AccordionDetails className={classes.details}> <LinkField - margin="normal" endpointAll="/api/devices?all=true" endpointLinked={`/api/devices?userId=${item.id}`} baseId={item.id} @@ -321,7 +317,6 @@ const UserPage = () => { label={t('deviceTitle')} /> <LinkField - margin="normal" endpointAll="/api/groups?all=true" endpointLinked={`/api/groups?userId=${item.id}`} baseId={item.id} @@ -330,7 +325,6 @@ const UserPage = () => { label={t('settingsGroups')} /> <LinkField - margin="normal" endpointAll="/api/geofences?all=true" endpointLinked={`/api/geofences?userId=${item.id}`} baseId={item.id} @@ -339,7 +333,6 @@ const UserPage = () => { label={t('sharedGeofences')} /> <LinkField - margin="normal" endpointAll="/api/notifications?all=true" endpointLinked={`/api/notifications?userId=${item.id}`} baseId={item.id} @@ -349,7 +342,6 @@ const UserPage = () => { label={t('sharedNotifications')} /> <LinkField - margin="normal" endpointAll="/api/calendars?all=true" endpointLinked={`/api/calendars?userId=${item.id}`} baseId={item.id} @@ -358,7 +350,6 @@ const UserPage = () => { label={t('sharedCalendars')} /> <LinkField - margin="normal" endpointAll="/api/users?all=true" endpointLinked={`/api/users?userId=${item.id}`} baseId={item.id} @@ -367,7 +358,6 @@ const UserPage = () => { label={t('settingsUsers')} /> <LinkField - margin="normal" endpointAll="/api/attributes/computed?all=true" endpointLinked={`/api/attributes/computed?userId=${item.id}`} baseId={item.id} @@ -377,7 +367,6 @@ const UserPage = () => { label={t('sharedComputedAttributes')} /> <LinkField - margin="normal" endpointAll="/api/drivers?all=true" endpointLinked={`/api/drivers?userId=${item.id}`} baseId={item.id} @@ -386,7 +375,6 @@ const UserPage = () => { label={t('sharedDrivers')} /> <LinkField - margin="normal" endpointAll="/api/commands?all=true" endpointLinked={`/api/commands?userId=${item.id}`} baseId={item.id} @@ -396,7 +384,6 @@ const UserPage = () => { label={t('sharedSavedCommands')} /> <LinkField - margin="normal" endpointAll="/api/maintenance?all=true" endpointLinked={`/api/maintenance?userId=${item.id}`} baseId={item.id} diff --git a/modern/src/settings/components/BaseCommandView.js b/modern/src/settings/components/BaseCommandView.js index c578e111..ca81a854 100644 --- a/modern/src/settings/components/BaseCommandView.js +++ b/modern/src/settings/components/BaseCommandView.js @@ -25,7 +25,6 @@ const BaseCommandView = ({ item, setItem }) => { return ( <> <SelectField - margin="normal" value={item.type || ''} onChange={(e) => setItem({ ...item, type: e.target.value, attributes: {} })} endpoint="/api/commands/types" @@ -53,7 +52,6 @@ const BaseCommandView = ({ item, setItem }) => { } return ( <TextField - margin="normal" type={type === 'number' ? 'number' : 'text'} value={item.attributes[key]} onChange={(e) => { diff --git a/modern/src/settings/components/EditAttributesView.js b/modern/src/settings/components/EditAttributesView.js index e6e1ddf0..14577e71 100644 --- a/modern/src/settings/components/EditAttributesView.js +++ b/modern/src/settings/components/EditAttributesView.js @@ -24,7 +24,6 @@ import { const useStyles = makeStyles((theme) => ({ addButton: { marginTop: theme.spacing(2), - marginBottom: theme.spacing(1), }, removeButton: { marginRight: theme.spacing(1.5), @@ -166,23 +165,24 @@ const EditAttributesView = ({ attributes, setAttributes, definitions }) => { )} label={getAttributeName(key, subtype)} /> - <IconButton className={classes.removeButton} onClick={() => deleteAttribute(key)}> - <CloseIcon /> + <IconButton size="small" className={classes.removeButton} onClick={() => deleteAttribute(key)}> + <CloseIcon fontSize="small" /> </IconButton> </Grid> ); } return ( - <FormControl margin="normal" key={key}> + <FormControl key={key}> <InputLabel>{getAttributeName(key, subtype)}</InputLabel> <OutlinedInput + label={getAttributeName(key, subtype)} type={type === 'number' ? 'number' : 'text'} value={getDisplayValue(value, subtype)} onChange={(e) => updateAttribute(key, e.target.value, type, subtype)} endAdornment={( <InputAdornment position="end"> - <IconButton onClick={() => deleteAttribute(key)}> - <CloseIcon /> + <IconButton size="small" onClick={() => deleteAttribute(key)}> + <CloseIcon fontSize="small" /> </IconButton> </InputAdornment> )} diff --git a/modern/src/settings/components/EditItemView.js b/modern/src/settings/components/EditItemView.js index 83624b8f..8dca1e66 100644 --- a/modern/src/settings/components/EditItemView.js +++ b/modern/src/settings/components/EditItemView.js @@ -3,7 +3,6 @@ import { useNavigate, useParams } from 'react-router-dom'; import makeStyles from '@mui/styles/makeStyles'; import Container from '@mui/material/Container'; import Button from '@mui/material/Button'; -import FormControl from '@mui/material/FormControl'; import { useCatch, useEffectAsync } from '../../reactHelper'; import { useTranslation } from '../../common/components/LocalizationProvider'; @@ -14,6 +13,8 @@ const useStyles = makeStyles((theme) => ({ marginTop: theme.spacing(2), }, buttons: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), display: 'flex', justifyContent: 'space-evenly', '& > *': { @@ -70,27 +71,25 @@ const EditItemView = ({ <PageLayout menu={menu} breadcrumbs={breadcrumbs}> <Container maxWidth="xs" className={classes.container}> {children} - <FormControl fullWidth margin="normal"> - <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={handleSave} - disabled={!validate()} - > - {t('sharedSave')} - </Button> - </div> - </FormControl> + <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={handleSave} + disabled={!validate()} + > + {t('sharedSave')} + </Button> + </div> </Container> </PageLayout> ); |