From 9bfda9e131ddda3076b4094a94795db41072a39c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Sep 2020 19:49:47 -0700 Subject: Implement attributes editing --- modern/src/attributes/AddAttributeDialog.js | 83 ++++++++++++++++ modern/src/attributes/EditAttributesView.js | 141 ++++++++++++++++++++++++++++ modern/src/attributes/userAttributes.js | 68 ++++++++++++++ 3 files changed, 292 insertions(+) create mode 100644 modern/src/attributes/AddAttributeDialog.js create mode 100644 modern/src/attributes/EditAttributesView.js create mode 100644 modern/src/attributes/userAttributes.js (limited to 'modern/src/attributes') diff --git a/modern/src/attributes/AddAttributeDialog.js b/modern/src/attributes/AddAttributeDialog.js new file mode 100644 index 0000000..ee4c48c --- /dev/null +++ b/modern/src/attributes/AddAttributeDialog.js @@ -0,0 +1,83 @@ +import React, { useState } from 'react'; +import { Button, Dialog, DialogActions, DialogContent, FormControl, InputLabel, MenuItem, Select, TextField } from "@material-ui/core"; + +import t from '../common/localization'; +import { Autocomplete, createFilterOptions } from '@material-ui/lab'; + +const AddAttributeDialog = ({ open, onResult, definitions }) => { + const filter = createFilterOptions({ + stringify: option => option.name, + }); + + const options = Object.entries(definitions).map(([key, value]) => ({ + key, + name: value.name, + type: value.type, + })); + + const [key, setKey] = useState(); + const [type, setType] = useState('string'); + + return ( + + + { + setKey(option && typeof option === 'object' ? option.key : option); + if (option && option.type) { + setType(option.type); + } + }} + filterOptions={(options, params) => { + const filtered = filter(options, params); + if (params.inputValue) { + filtered.push({ + key: params.inputValue, + name: params.inputValue, + }); + } + return filtered; + }} + options={options} + getOptionLabel={option => { + return option && typeof option === 'object' ? option.name : option; + }} + renderOption={option => option.name} + freeSolo + renderInput={(params) => ( + + )} + /> + + {t('sharedType')} + + + + + + + + + ) +} + +export default AddAttributeDialog; diff --git a/modern/src/attributes/EditAttributesView.js b/modern/src/attributes/EditAttributesView.js new file mode 100644 index 0000000..9491acc --- /dev/null +++ b/modern/src/attributes/EditAttributesView.js @@ -0,0 +1,141 @@ +import React, { useState } from 'react'; + +import t from '../common/localization'; + +import { Button, Checkbox, FilledInput, FormControl, FormControlLabel, Grid, IconButton, InputAdornment, InputLabel, makeStyles } from "@material-ui/core"; +import CloseIcon from '@material-ui/icons/Close'; +import AddIcon from '@material-ui/icons/Add'; +import AddAttributeDialog from './AddAttributeDialog'; + +const useStyles = makeStyles(theme => ({ + addButton: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(1), + }, + removeButton: { + marginRight: theme.spacing(1.5), + }, +})); + +const EditAttributesView = ({ attributes, setAttributes, definitions }) => { + const classes = useStyles(); + + const [addDialogShown, setAddDialogShown] = useState(false); + + const convertToList = (attributes) => { + let booleanList = []; + let otherList = []; + for (const key in attributes) { + const value = attributes[key]; + const type = getAttributeType(value); + if (type === 'boolean') { + booleanList.push({ key, value, type }); + } else { + otherList.push({ key, value, type }); + } + } + return otherList.concat(booleanList); + } + + const handleAddResult = (definition) => { + setAddDialogShown(false); + if (definition) { + switch(definition.type) { + case 'number': + updateAttribute(definition.key, 0); + break; + case 'boolean': + updateAttribute(definition.key, false); + break; + default: + updateAttribute(definition.key, ""); + break; + } + } + } + + const updateAttribute = (key, value) => { + let updatedAttributes = {...attributes}; + updatedAttributes[key] = value; + setAttributes(updatedAttributes); + }; + + const deleteAttribute = (key) => { + let updatedAttributes = {...attributes}; + delete updatedAttributes[key]; + setAttributes(updatedAttributes); + }; + + const getAttributeName = (key) => { + const definition = definitions[key]; + return definition ? definition.name : key; + }; + + const getAttributeType = (value) => { + if (typeof value === 'number') { + return 'number'; + } else if (typeof value === 'boolean') { + return 'boolean'; + } else { + return 'string'; + } + }; + + return ( + <> + {convertToList(attributes).map(({ key, value, type }) => { + if (type === 'boolean') { + return ( + + updateAttribute(key, e.target.checked)} + /> + } + label={getAttributeName(key)} /> + deleteAttribute(key)}> + + + + ); + } else { + return ( + + {getAttributeName(key)} + updateAttribute(key, e.target.value)} + endAdornment={ + + deleteAttribute(key)}> + + + + } + /> + + ); + } + })} + + + + ); +} + +export default EditAttributesView; diff --git a/modern/src/attributes/userAttributes.js b/modern/src/attributes/userAttributes.js new file mode 100644 index 0000000..bcec29f --- /dev/null +++ b/modern/src/attributes/userAttributes.js @@ -0,0 +1,68 @@ +import t from '../common/localization' + +export default { + 'notificationTokens': { + name: t('attributeNotificationTokens'), + type: 'string', + }, + 'web.liveRouteLength': { + name: t('attributeWebLiveRouteLength'), + type: 'number', + }, + 'web.selectZoom': { + name: t('attributeWebSelectZoom'), + type: 'number', + }, + 'web.maxZoom': { + name: t('attributeWebMaxZoom'), + type: 'number', + }, + 'ui.disableReport': { + name: t('attributeUiDisableReport'), + type: 'boolean', + }, + 'ui.disableEvents': { + name: t('attributeUiDisableEvents'), + type: 'boolean', + }, + 'ui.disableVehicleFetures': { + name: t('attributeUiDisableVehicleFetures'), + type: 'boolean', + }, + 'ui.disableDrivers': { + name: t('attributeUiDisableDrivers'), + type: 'boolean', + }, + 'ui.disableComputedAttributes': { + name: t('attributeUiDisableComputedAttributes'), + type: 'boolean', + }, + 'ui.disableCalendars': { + name: t('attributeUiDisableCalendars'), + type: 'boolean', + }, + 'ui.disableMaintenance': { + name: t('attributeUiDisableMaintenance'), + type: 'boolean', + }, + 'ui.hidePositionAttributes': { + name: t('attributeUiHidePositionAttributes'), + type: 'string', + }, + 'distanceUnit': { + name: t('settingsDistanceUnit'), + type: 'string', + }, + 'speedUnit': { + name: t('settingsSpeedUnit'), + type: 'string', + }, + 'volumeUnit': { + name: t('settingsVolumeUnit'), + type: 'string', + }, + 'timezone': { + name: t('sharedTimezone'), + type: 'string', + }, +}; -- cgit v1.2.3