diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2021-09-06 11:59:42 -0700 |
---|---|---|
committer | Ashutosh Bishnoi <mail2bishnoi@gmail.com> | 2022-02-15 11:28:09 +0530 |
commit | 682bc9db991ef5d550b6b0b780371f19359511ad (patch) | |
tree | 261e25a5edc102fa31c19af1fe365ebb89cd8d34 /modern/src | |
parent | 158f8ba27f354b53f4d25613d1ff1828cbad0bea (diff) | |
download | trackermap-web-682bc9db991ef5d550b6b0b780371f19359511ad.tar.gz trackermap-web-682bc9db991ef5d550b6b0b780371f19359511ad.tar.bz2 trackermap-web-682bc9db991ef5d550b6b0b780371f19359511ad.zip |
# This is a combination of 30 commits.
# This is the 1st commit message:
Close socket on logout (fix #896)
# This is the commit message #2:
Fix lint
# This is the commit message #3:
Add calendar menu
# This is the commit message #4:
Add calendar file upload
# This is the commit message #5:
Disable icon tinting in Firefox
# This is the commit message #6:
Move ignition icon
# This is the commit message #7:
Specify icon sizes
# This is the commit message #8:
Fix lint issues
# This is the commit message #9:
Add accuracy button
# This is the commit message #10:
Merge shock and vibration alarms
# This is the commit message #11:
Add events alarm column
# This is the commit message #12:
Enable LocationIQ by default
# This is the commit message #13:
Update LocationIQ keys
# This is the commit message #14:
Fix selector style
# This is the commit message #15:
Support server change
# This is the commit message #16:
Update localization script
# This is the commit message #17:
Update localization
# This is the commit message #18:
Command to install dependency
# This is the commit message #19:
Update JavaScript libraries
# This is the commit message #20:
Fix modern app issues
# This is the commit message #21:
Fix image URL
# This is the commit message #22:
Fix user list (fix #898)
# This is the commit message #23:
Fix formatting issue
# This is the commit message #24:
Add option to disable reports
# This is the commit message #25:
Fix add button position
# This is the commit message #26:
Select device based on uniqueId
# This is the commit message #27:
Update devices list search
# This is the commit message #28:
Fix lint problems
# This is the commit message #29:
Changed devices list search
# This is the commit message #30:
Changed device list search
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/App.js | 4 | ||||
-rw-r--r-- | modern/src/DevicesList.js | 23 | ||||
-rw-r--r-- | modern/src/EditCollectionView.js | 6 | ||||
-rw-r--r-- | modern/src/MainPage.js | 12 | ||||
-rw-r--r-- | modern/src/SocketController.js | 25 | ||||
-rw-r--r-- | modern/src/admin/UsersPage.js | 4 | ||||
-rw-r--r-- | modern/src/attributes/useUserAttributes.js | 4 | ||||
-rw-r--r-- | modern/src/components/SideNav.js | 2 | ||||
-rw-r--r-- | modern/src/map/Map.js | 6 | ||||
-rw-r--r-- | modern/src/map/mapStyles.js | 2 | ||||
-rw-r--r-- | modern/src/map/mapUtil.js | 34 | ||||
-rw-r--r-- | modern/src/reactHelper.js | 9 | ||||
-rw-r--r-- | modern/src/reports/ReportFilter.js | 4 | ||||
-rw-r--r-- | modern/src/settings/CalendarPage.js | 82 | ||||
-rw-r--r-- | modern/src/settings/CalendarsPage.js | 63 | ||||
-rw-r--r-- | modern/src/settings/OptionsLayout/useRoutes.js | 7 | ||||
-rw-r--r-- | modern/src/theme/index.js | 4 | ||||
-rw-r--r-- | modern/src/theme/overrides.js | 11 |
18 files changed, 259 insertions, 43 deletions
diff --git a/modern/src/App.js b/modern/src/App.js index eb1a8818..a53ffc6c 100644 --- a/modern/src/App.js +++ b/modern/src/App.js @@ -24,6 +24,8 @@ import SummaryReportPage from './reports/SummaryReportPage'; import ChartReportPage from './reports/ChartReportPage'; import DriversPage from './settings/DriversPage'; import DriverPage from './settings/DriverPage'; +import CalendarsPage from './settings/CalendarsPage'; +import CalendarPage from './settings/CalendarPage'; import ComputedAttributesPage from './settings/ComputedAttributesPage'; import ComputedAttributePage from './settings/ComputedAttributePage'; import MaintenancesPage from './settings/MaintenancesPage'; @@ -69,6 +71,8 @@ const App = () => { <Route exact path="/settings/group/:id?" component={GroupPage} /> <Route exact path="/settings/drivers" component={DriversPage} /> <Route exact path="/settings/driver/:id?" component={DriverPage} /> + <Route exact path="/settings/calendars" component={CalendarsPage} /> + <Route exact path="/settings/calendar/:id?" component={CalendarPage} /> <Route exact path="/settings/attributes" component={ComputedAttributesPage} /> <Route exact path="/settings/attribute/:id?" component={ComputedAttributePage} /> <Route exact path="/settings/maintenances" component={MaintenancesPage} /> diff --git a/modern/src/DevicesList.js b/modern/src/DevicesList.js index cea7c38c..10ac4fc7 100644 --- a/modern/src/DevicesList.js +++ b/modern/src/DevicesList.js @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { makeStyles } from '@material-ui/core/styles'; import Avatar from '@material-ui/core/Avatar'; @@ -12,7 +12,7 @@ import SvgIcon from '@material-ui/core/SvgIcon'; import { FixedSizeList } from 'react-window'; import AutoSizer from 'react-virtualized-auto-sizer'; import BatteryFullIcon from '@material-ui/icons/BatteryFull'; -import { ReactComponent as IgnitionIcon } from '../public/images/icon/ignition.svg'; +import { ReactComponent as IgnitionIcon } from '../public/images/ignition.svg'; import { devicesActions } from './store'; import EditCollectionView from './EditCollectionView'; @@ -126,12 +126,21 @@ const DeviceRow = ({ data, index, style }) => { ); }; -const DeviceView = ({ updateTimestamp, onMenuClick }) => { +const DeviceView = ({ updateTimestamp, onMenuClick, filter }) => { const classes = useStyles(); const dispatch = useDispatch(); const listInnerEl = useRef(null); const items = useSelector(getDevices); + const [filteredItems, setFilteredItems] = useState(null); + + useEffect(() => { + setFilteredItems( + filter.trim().length > 0 + ? items.filter((item) => `${item.name} ${item.uniqueId}`.toLowerCase().includes(filter?.toLowerCase())) + : items, + ); + }, [filter, items]); if (listInnerEl.current) { listInnerEl.current.className = classes.listInner; @@ -151,8 +160,8 @@ const DeviceView = ({ updateTimestamp, onMenuClick }) => { <FixedSizeList width={width} height={height} - itemCount={items.length} - itemData={{ items, onMenuClick }} + itemCount={filteredItems.length} + itemData={{ items: filteredItems, onMenuClick }} itemSize={72} overscanCount={10} innerRef={listInnerEl} @@ -165,8 +174,8 @@ const DeviceView = ({ updateTimestamp, onMenuClick }) => { ); }; -const DevicesList = () => ( - <EditCollectionView content={DeviceView} editPath="/device" endpoint="devices" disableAdd /> +const DevicesList = ({ filter }) => ( + <EditCollectionView content={DeviceView} editPath="/device" endpoint="devices" disableAdd filter={filter} /> ); export default DevicesList; diff --git a/modern/src/EditCollectionView.js b/modern/src/EditCollectionView.js index 0bfec615..2d011302 100644 --- a/modern/src/EditCollectionView.js +++ b/modern/src/EditCollectionView.js @@ -12,14 +12,14 @@ import { useTranslation } from './LocalizationProvider'; const useStyles = makeStyles((theme) => ({ fab: { - position: 'absolute', + position: 'fixed', bottom: theme.spacing(2), right: theme.spacing(2), }, })); const EditCollectionView = ({ - content, editPath, endpoint, disableAdd, + content, editPath, endpoint, disableAdd, filter, }) => { const classes = useStyles(); const history = useHistory(); @@ -64,7 +64,7 @@ const EditCollectionView = ({ return ( <> - <Content updateTimestamp={updateTimestamp} onMenuClick={menuShow} /> + <Content updateTimestamp={updateTimestamp} onMenuClick={menuShow} filter={filter} /> {adminEnabled && !disableAdd && ( <Fab size="medium" color="primary" className={classes.fab} onClick={handleAdd}> diff --git a/modern/src/MainPage.js b/modern/src/MainPage.js index 7fd43154..0176c7f0 100644 --- a/modern/src/MainPage.js +++ b/modern/src/MainPage.js @@ -98,7 +98,7 @@ const MainPage = () => { const isTablet = useMediaQuery(theme.breakpoints.down('md')); const isPhone = useMediaQuery(theme.breakpoints.down('xs')); - const [deviceName, setDeviceName] = useState(''); + const [searchKeyword, setSearchKeyword] = useState(''); const [collapsed, setCollapsed] = useState(false); const handleClose = () => { @@ -139,11 +139,11 @@ const MainPage = () => { )} <TextField fullWidth - name="deviceName" - value={deviceName} - autoComplete="deviceName" + name="searchKeyword" + value={searchKeyword} + autoComplete="searchKeyword" autoFocus - onChange={(event) => setDeviceName(event.target.value)} + onChange={(event) => setSearchKeyword(event.target.value)} placeholder="Search Devices" variant="filled" /> @@ -158,7 +158,7 @@ const MainPage = () => { </Toolbar> </Paper> <div className={classes.deviceList}> - <DevicesList /> + <DevicesList filter={searchKeyword} /> </div> </Paper> <BottomMenu /> diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js index ae82d134..ac950190 100644 --- a/modern/src/SocketController.js +++ b/modern/src/SocketController.js @@ -1,3 +1,4 @@ +import { useRef } from 'react'; import { useDispatch, useSelector, connect } from 'react-redux'; import { useHistory } from 'react-router-dom'; @@ -24,13 +25,17 @@ const displayNotifications = (events) => { const SocketController = () => { const dispatch = useDispatch(); const history = useHistory(); + const authenticated = useSelector((state) => !!state.session.user); + const socketRef = useRef(); + const connectSocket = () => { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`); + socketRef.current = socket; - socket.onclose = () => { + socket.onerror = () => { setTimeout(() => connectSocket(), 60 * 1000); }; @@ -62,14 +67,20 @@ const SocketController = () => { dispatch(devicesActions.refresh(await response.json())); } connectSocket(); + return () => { + const socket = socketRef.current; + if (socket) { + socket.close(); + } + }; + } + const response = await fetch('/api/session'); + if (response.ok) { + dispatch(sessionActions.updateUser(await response.json())); } else { - const response = await fetch('/api/session'); - if (response.ok) { - dispatch(sessionActions.updateUser(await response.json())); - } else { - history.push('/login'); - } + history.push('/login'); } + return null; }, [authenticated]); return null; diff --git a/modern/src/admin/UsersPage.js b/modern/src/admin/UsersPage.js index bd2a0033..289598e7 100644 --- a/modern/src/admin/UsersPage.js +++ b/modern/src/admin/UsersPage.js @@ -51,8 +51,8 @@ const UsersView = ({ updateTimestamp, onMenuClick }) => { </TableCell> <TableCell>{item.name}</TableCell> <TableCell>{item.email}</TableCell> - <TableCell>{formatBoolean(item, 'administrator', t)}</TableCell> - <TableCell>{formatBoolean(item, 'disabled', t)}</TableCell> + <TableCell>{formatBoolean(item.administrator, t)}</TableCell> + <TableCell>{formatBoolean(item.disabled, t)}</TableCell> </TableRow> ))} </TableBody> diff --git a/modern/src/attributes/useUserAttributes.js b/modern/src/attributes/useUserAttributes.js index 61c61899..0101d2f5 100644 --- a/modern/src/attributes/useUserAttributes.js +++ b/modern/src/attributes/useUserAttributes.js @@ -17,10 +17,6 @@ export default (t) => useMemo(() => ({ name: t('attributeWebMaxZoom'), type: 'number', }, - 'ui.disableReport': { - name: t('attributeUiDisableReport'), - type: 'boolean', - }, 'ui.disableEvents': { name: t('attributeUiDisableEvents'), type: 'boolean', diff --git a/modern/src/components/SideNav.js b/modern/src/components/SideNav.js index bcf8ecd5..62c64fd2 100644 --- a/modern/src/components/SideNav.js +++ b/modern/src/components/SideNav.js @@ -21,7 +21,7 @@ const SideNav = ({ routes }) => { key={route.href || route.subheader} button to={route.href} - selected={location.pathname.match(route.match || route.href)} + selected={location.pathname.match(route.match || route.href) !== null} > <ListItemIcon>{route.icon}</ListItemIcon> <ListItemText primary={route.name} /> diff --git a/modern/src/map/Map.js b/modern/src/map/Map.js index 5e182a44..b020423a 100644 --- a/modern/src/map/Map.js +++ b/modern/src/map/Map.js @@ -8,7 +8,7 @@ import { SwitcherControl } from './switcher/switcher'; import deviceCategories from '../common/deviceCategories'; import { prepareIcon, loadImage } from './mapUtil'; import { - styleCarto, styleMapbox, styleMapTiler, styleOsm, + styleCarto, styleLocationIq, styleMapbox, styleMapTiler, styleOsm, } from './mapStyles'; import { useAttributePreference } from '../common/preferences'; import palette from '../theme/palette'; @@ -89,6 +89,7 @@ const Map = ({ children }) => { const mapboxAccessToken = useAttributePreference('mapboxAccessToken'); const mapTilerKey = useAttributePreference('mapTilerKey'); + const locationIqKey = useAttributePreference('locationIqKey', 'pk.0f147952a41c555a5b70614039fd148b'); useEffect(() => { maplibregl.accessToken = mapboxAccessToken; @@ -96,6 +97,9 @@ const Map = ({ children }) => { useEffect(() => { switcher.updateStyles([ + { id: 'locationIqStreets', title: t('mapLocationIqStreets'), uri: styleLocationIq('streets', locationIqKey) }, + { id: 'locationIqEarth', title: t('mapLocationIqEarth'), uri: styleLocationIq('earth', locationIqKey) }, + { id: 'locationIqHybrid', title: t('mapLocationIqHybrid'), uri: styleLocationIq('hybrid', locationIqKey) }, { id: 'osm', title: t('mapOsm'), uri: styleOsm() }, { id: 'carto', title: t('mapCarto'), uri: styleCarto() }, { id: 'mapboxStreets', title: t('mapMapboxStreets'), uri: styleMapbox('streets-v11') }, diff --git a/modern/src/map/mapStyles.js b/modern/src/map/mapStyles.js index 9650ead5..86813a13 100644 --- a/modern/src/map/mapStyles.js +++ b/modern/src/map/mapStyles.js @@ -51,3 +51,5 @@ export const styleCarto = () => ({ export const styleMapbox = (style) => `mapbox://styles/mapbox/${style}`; export const styleMapTiler = (style, key) => `https://api.maptiler.com/maps/${style}/style.json?key=${key}`; + +export const styleLocationIq = (style, key) => `https://tiles.locationiq.com/v3/${style}/vector.json?key=${key}`; diff --git a/modern/src/map/mapUtil.js b/modern/src/map/mapUtil.js index e3c32f46..2aa86c68 100644 --- a/modern/src/map/mapUtil.js +++ b/modern/src/map/mapUtil.js @@ -1,5 +1,4 @@ import { parse, stringify } from 'wellknown'; -import canvasTintImage from 'canvas-tint-image'; import circle from '@turf/circle'; export const loadImage = (url) => new Promise((imageLoaded) => { @@ -8,12 +7,31 @@ export const loadImage = (url) => new Promise((imageLoaded) => { image.src = url; }); -export const prepareIcon = (background, icon, color) => { - const pixelRatio = window.devicePixelRatio; +const canvasTintImage = (image, color) => { + const canvas = document.createElement('canvas'); + canvas.width = image.width * devicePixelRatio; + canvas.height = image.height * devicePixelRatio; + canvas.style.width = `${image.width}px`; + canvas.style.height = `${image.height}px`; + + const context = canvas.getContext('2d'); + + context.save(); + context.fillStyle = color; + context.globalAlpha = 1; + context.fillRect(0, 0, canvas.width, canvas.height); + context.globalCompositeOperation = 'destination-atop'; + context.globalAlpha = 1; + context.drawImage(image, 0, 0, canvas.width, canvas.height); + context.restore(); + return canvas; +}; + +export const prepareIcon = (background, icon, color) => { const canvas = document.createElement('canvas'); - canvas.width = background.width * pixelRatio; - canvas.height = background.height * pixelRatio; + canvas.width = background.width * devicePixelRatio; + canvas.height = background.height * devicePixelRatio; canvas.style.width = `${background.width}px`; canvas.style.height = `${background.height}px`; @@ -24,7 +42,11 @@ export const prepareIcon = (background, icon, color) => { const iconRatio = 0.5; const imageWidth = canvas.width * iconRatio; const imageHeight = canvas.height * iconRatio; - context.drawImage(canvasTintImage(icon, color, 1), (canvas.width - imageWidth) / 2, (canvas.height - imageHeight) / 2, imageWidth, imageHeight); + if (navigator.userAgent.indexOf('Firefox') > 0) { + context.drawImage(icon, (canvas.width - imageWidth) / 2, (canvas.height - imageHeight) / 2, imageWidth, imageHeight); + } else { + context.drawImage(canvasTintImage(icon, color), (canvas.width - imageWidth) / 2, (canvas.height - imageHeight) / 2, imageWidth, imageHeight); + } } return context.getImageData(0, 0, canvas.width, canvas.height); diff --git a/modern/src/reactHelper.js b/modern/src/reactHelper.js index f3ef78dd..7503360a 100644 --- a/modern/src/reactHelper.js +++ b/modern/src/reactHelper.js @@ -9,7 +9,14 @@ export const usePrevious = (value) => { }; export const useEffectAsync = (effect, deps) => { + const ref = useRef(); useEffect(() => { - effect(); + effect().then((result) => ref.current = result); + return () => { + const result = ref.current; + if (result) { + result(); + } + }; }, deps); }; diff --git a/modern/src/reports/ReportFilter.js b/modern/src/reports/ReportFilter.js index 23c7fc00..bfd8a540 100644 --- a/modern/src/reports/ReportFilter.js +++ b/modern/src/reports/ReportFilter.js @@ -60,13 +60,13 @@ const ReportFilter = ({ children, handleSubmit, showOnly }) => { }; return ( - <Grid container spacing={2} justify="flex-end"> + <Grid container spacing={2} justifyContent="flex-end"> <Grid item xs={12} sm={period === 'custom' ? 3 : 6}> <FormControl variant="filled" fullWidth> <InputLabel>{t('reportDevice')}</InputLabel> <Select value={deviceId} onChange={(e) => setDeviceId(e.target.value)}> {devices.map((device) => ( - <MenuItem value={device.id}>{device.name}</MenuItem> + <MenuItem key={device.id} value={device.id}>{device.name}</MenuItem> ))} </Select> </FormControl> diff --git a/modern/src/settings/CalendarPage.js b/modern/src/settings/CalendarPage.js new file mode 100644 index 00000000..60d4ef76 --- /dev/null +++ b/modern/src/settings/CalendarPage.js @@ -0,0 +1,82 @@ +import React, { useState } from 'react'; +import TextField from '@material-ui/core/TextField'; +import { + Accordion, AccordionSummary, AccordionDetails, makeStyles, Typography, +} from '@material-ui/core'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { DropzoneArea } from 'material-ui-dropzone'; +import EditItemView from '../EditItemView'; +import EditAttributesView from '../attributes/EditAttributesView'; +import { useTranslation } from '../LocalizationProvider'; + +const useStyles = makeStyles(() => ({ + details: { + flexDirection: 'column', + }, +})); + +const CalendarPage = () => { + const classes = useStyles(); + const t = useTranslation(); + + const [item, setItem] = useState(); + + const handleFiles = (files) => { + if (files.length > 0) { + const reader = new FileReader(); + reader.onload = (event) => { + const { result } = event.target; + setItem({ ...item, data: result.substr(result.indexOf(',') + 1) }); + }; + reader.readAsDataURL(files[0]); + } else { + setItem({ ...item, data: null }); + } + }; + + return ( + <EditItemView endpoint="calendars" item={item} setItem={setItem}> + {item + && ( + <> + <Accordion defaultExpanded> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1"> + {t('sharedRequired')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <TextField + margin="normal" + value={item.name || ''} + onChange={(event) => setItem({ ...item, name: event.target.value })} + label={t('sharedName')} + variant="filled" + /> + <DropzoneArea + filesLimit={1} + onChange={handleFiles} + /> + </AccordionDetails> + </Accordion> + <Accordion> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1"> + {t('sharedAttributes')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <EditAttributesView + attributes={item.attributes} + setAttributes={(attributes) => setItem({ ...item, attributes })} + definitions={{}} + /> + </AccordionDetails> + </Accordion> + </> + )} + </EditItemView> + ); +}; + +export default CalendarPage; diff --git a/modern/src/settings/CalendarsPage.js b/modern/src/settings/CalendarsPage.js new file mode 100644 index 00000000..076f30ca --- /dev/null +++ b/modern/src/settings/CalendarsPage.js @@ -0,0 +1,63 @@ +import React, { useState } from 'react'; +import { + TableContainer, Table, TableRow, TableCell, TableHead, TableBody, makeStyles, IconButton, +} from '@material-ui/core'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import { useEffectAsync } from '../reactHelper'; +import EditCollectionView from '../EditCollectionView'; +import OptionsLayout from './OptionsLayout'; +import { useTranslation } from '../LocalizationProvider'; + +const useStyles = makeStyles((theme) => ({ + columnAction: { + width: theme.spacing(1), + padding: theme.spacing(0, 1), + }, +})); + +const CalendarsView = ({ updateTimestamp, onMenuClick }) => { + const classes = useStyles(); + const t = useTranslation(); + + const [items, setItems] = useState([]); + + useEffectAsync(async () => { + const response = await fetch('/api/calendars'); + if (response.ok) { + setItems(await response.json()); + } + }, [updateTimestamp]); + + 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 onClick={(event) => onMenuClick(event.currentTarget, item.id)}> + <MoreVertIcon /> + </IconButton> + </TableCell> + <TableCell>{item.name}</TableCell> + </TableRow> + ))} + </TableBody> + </Table> + </TableContainer> + ); +}; + +const CalendarsPage = () => ( + <OptionsLayout> + <EditCollectionView content={CalendarsView} editPath="/settings/calendar" endpoint="calendars" /> + </OptionsLayout> +); + +export default CalendarsPage; diff --git a/modern/src/settings/OptionsLayout/useRoutes.js b/modern/src/settings/OptionsLayout/useRoutes.js index 8be4ec30..efbd9eb2 100644 --- a/modern/src/settings/OptionsLayout/useRoutes.js +++ b/modern/src/settings/OptionsLayout/useRoutes.js @@ -8,6 +8,7 @@ import StorageIcon from '@material-ui/icons/Storage'; import BuildIcon from '@material-ui/icons/Build'; import PeopleIcon from '@material-ui/icons/People'; import BarChartIcon from '@material-ui/icons/BarChart'; +import TodayIcon from '@material-ui/icons/Today'; import { getIsAdmin, getUserId } from '../../common/selectors'; import { useTranslation } from '../../LocalizationProvider'; @@ -61,6 +62,12 @@ const useMainRoutes = (t, userId) => useMemo(() => [ icon: <PersonIcon />, }, { + match: 'calendar', + name: t('sharedCalendars'), + href: '/settings/calendars', + icon: <TodayIcon />, + }, + { match: 'attribute', name: t('sharedComputedAttributes'), href: '/settings/attributes', diff --git a/modern/src/theme/index.js b/modern/src/theme/index.js index dc0a35bf..02865c23 100644 --- a/modern/src/theme/index.js +++ b/modern/src/theme/index.js @@ -1,9 +1,9 @@ -import { createMuiTheme } from '@material-ui/core/styles'; +import { createTheme } from '@material-ui/core/styles'; import palette from './palette'; import overrides from './overrides'; import dimensions from './dimensions'; -const theme = createMuiTheme({ +const theme = createTheme({ palette, overrides, dimensions, diff --git a/modern/src/theme/overrides.js b/modern/src/theme/overrides.js index a6d08cf1..d1fe844c 100644 --- a/modern/src/theme/overrides.js +++ b/modern/src/theme/overrides.js @@ -24,7 +24,8 @@ export default { input: { height: dimensions.inputHeight, borderRadius: dimensions.borderRadius, - paddingTop: '10px', + paddingTop: '11.5px', + paddingBottom: '11.5px', boxSizing: 'border-box', '&:-webkit-autofill': { WebkitBoxShadow: '0 0 0 100px #eeeeee inset', @@ -42,6 +43,14 @@ export default { }, }, }, + MuiSelect: { + select: { + borderRadius: dimensions.borderRadius, + '&&:focus': { + borderRadius: dimensions.borderRadius, + }, + }, + }, MuiButton: { root: { height: dimensions.inputHeight, |