From f6d15a1a445a1abd18d89a803b8617957c6970b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 May 2024 06:34:04 -0700 Subject: Fix number formatting --- src/common/util/formatter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/common/util') diff --git a/src/common/util/formatter.js b/src/common/util/formatter.js index 7b7fc96d..0463df2b 100644 --- a/src/common/util/formatter.js +++ b/src/common/util/formatter.js @@ -23,11 +23,11 @@ export const formatNumber = (value, precision = 1) => Number(value.toFixed(preci export const formatPercentage = (value) => `${value}%`; -export const formatTemperature = (value) => `${value}°C`; +export const formatTemperature = (value) => `${value.toFixed(1)}°C`; -export const formatVoltage = (value, t) => `${value} ${t('sharedVoltAbbreviation')}`; +export const formatVoltage = (value, t) => `${value.toFixed(2)} ${t('sharedVoltAbbreviation')}`; -export const formatConsumption = (value, t) => `${value} ${t('sharedLiterPerHourAbbreviation')}`; +export const formatConsumption = (value, t) => `${value.toFixed(2)} ${t('sharedLiterPerHourAbbreviation')}`; export const formatTime = (value, format, hours12) => { if (value) { -- cgit v1.2.3 From c4754d0befac1a0bfb85f56419dade8378b98b32 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 May 2024 07:24:14 -0700 Subject: Automatic locale time formatting --- src/common/components/PositionValue.jsx | 3 +-- src/common/util/formatter.js | 12 +++++++----- src/main/EventsDrawer.jsx | 5 +---- src/map/MapPositions.js | 5 ++--- src/other/ReplayPage.jsx | 5 +---- src/reports/ChartReportPage.jsx | 7 +++---- src/reports/CombinedReportPage.jsx | 5 +---- src/reports/EventReportPage.jsx | 5 ++--- src/reports/StatisticsPage.jsx | 5 +---- src/reports/StopReportPage.jsx | 5 ++--- src/reports/SummaryReportPage.jsx | 5 ++--- src/reports/TripReportPage.jsx | 5 ++--- src/settings/DevicesPage.jsx | 5 +---- src/settings/ServerPage.jsx | 4 ---- src/settings/UserPage.jsx | 6 ------ src/settings/UsersPage.jsx | 5 +---- 16 files changed, 27 insertions(+), 60 deletions(-) (limited to 'src/common/util') diff --git a/src/common/components/PositionValue.jsx b/src/common/components/PositionValue.jsx index b1f8f656..cedf47c9 100644 --- a/src/common/components/PositionValue.jsx +++ b/src/common/components/PositionValue.jsx @@ -42,14 +42,13 @@ const PositionValue = ({ position, property, attribute }) => { const speedUnit = useAttributePreference('speedUnit'); const volumeUnit = useAttributePreference('volumeUnit'); const coordinateFormat = usePreference('coordinateFormat'); - const hours12 = usePreference('twelveHourFormat'); const formatValue = () => { switch (key) { case 'fixTime': case 'deviceTime': case 'serverTime': - return formatTime(value, 'seconds', hours12); + return formatTime(value, 'seconds'); case 'latitude': return formatCoordinate('latitude', value, coordinateFormat); case 'longitude': diff --git a/src/common/util/formatter.js b/src/common/util/formatter.js index 0463df2b..b10d737a 100644 --- a/src/common/util/formatter.js +++ b/src/common/util/formatter.js @@ -1,6 +1,7 @@ import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration'; import relativeTime from 'dayjs/plugin/relativeTime'; +import localizedFormat from 'dayjs/plugin/localizedFormat'; import { altitudeFromMeters, @@ -16,6 +17,7 @@ import { prefixString } from './stringUtils'; dayjs.extend(duration); dayjs.extend(relativeTime); +dayjs.extend(localizedFormat); export const formatBoolean = (value, t) => (value ? t('sharedYes') : t('sharedNo')); @@ -29,18 +31,18 @@ export const formatVoltage = (value, t) => `${value.toFixed(2)} ${t('sharedVoltA export const formatConsumption = (value, t) => `${value.toFixed(2)} ${t('sharedLiterPerHourAbbreviation')}`; -export const formatTime = (value, format, hours12) => { +export const formatTime = (value, format) => { if (value) { const d = dayjs(value); switch (format) { case 'date': - return d.format('YYYY-MM-DD'); + return d.format('L'); case 'time': - return d.format(hours12 ? 'hh:mm:ss A' : 'HH:mm:ss'); + return d.format('LTS'); case 'minutes': - return d.format(hours12 ? 'YYYY-MM-DD hh:mm A' : 'YYYY-MM-DD HH:mm'); + return d.format('L LT'); default: - return d.format(hours12 ? 'YYYY-MM-DD hh:mm:ss A' : 'YYYY-MM-DD HH:mm:ss'); + return d.format('L LTS'); } } return ''; diff --git a/src/main/EventsDrawer.jsx b/src/main/EventsDrawer.jsx index f9602e95..57a95eb2 100644 --- a/src/main/EventsDrawer.jsx +++ b/src/main/EventsDrawer.jsx @@ -9,7 +9,6 @@ import DeleteIcon from '@mui/icons-material/Delete'; import { formatNotificationTitle, formatTime } from '../common/util/formatter'; import { useTranslation } from '../common/components/LocalizationProvider'; import { eventsActions } from '../store'; -import { usePreference } from '../common/util/preferences'; const useStyles = makeStyles((theme) => ({ drawer: { @@ -30,8 +29,6 @@ const EventsDrawer = ({ open, onClose }) => { const dispatch = useDispatch(); const t = useTranslation(); - const hours12 = usePreference('twelveHourFormat'); - const devices = useSelector((state) => state.devices.items); const events = useSelector((state) => state.events.items); @@ -66,7 +63,7 @@ const EventsDrawer = ({ open, onClose }) => { > dispatch(eventsActions.delete(event))}> diff --git a/src/map/MapPositions.js b/src/map/MapPositions.js index 08bc6b83..d1b16299 100644 --- a/src/map/MapPositions.js +++ b/src/map/MapPositions.js @@ -5,7 +5,7 @@ import { useTheme } from '@mui/styles'; import { map } from './core/MapView'; import { formatTime, getStatusColor } from '../common/util/formatter'; import { mapIconKey } from './core/preloadImages'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import { useCatchCallback } from '../reactHelper'; const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleField }) => { @@ -21,7 +21,6 @@ const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleF const selectedDeviceId = useSelector((state) => state.devices.selectedId); const mapCluster = useAttributePreference('mapCluster', true); - const hours12 = usePreference('twelveHourFormat'); const directionType = useAttributePreference('mapDirection', 'selected'); const createFeature = (devices, position, selectedPositionId) => { @@ -42,7 +41,7 @@ const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleF id: position.id, deviceId: position.deviceId, name: device.name, - fixTime: formatTime(position.fixTime, 'seconds', hours12), + fixTime: formatTime(position.fixTime, 'seconds'), category: mapIconKey(device.category), color: showStatus ? position.attributes.color || getStatusColor(device.status) : 'neutral', rotation: position.course, diff --git a/src/other/ReplayPage.jsx b/src/other/ReplayPage.jsx index 1050b976..1425c495 100644 --- a/src/other/ReplayPage.jsx +++ b/src/other/ReplayPage.jsx @@ -25,7 +25,6 @@ import { useCatch } from '../reactHelper'; import MapCamera from '../map/MapCamera'; import MapGeofence from '../map/MapGeofence'; import StatusCard from '../common/components/StatusCard'; -import { usePreference } from '../common/util/preferences'; const useStyles = makeStyles((theme) => ({ root: { @@ -82,8 +81,6 @@ const ReplayPage = () => { const navigate = useNavigate(); const timerRef = useRef(); - const hours12 = usePreference('twelveHourFormat'); - const defaultDeviceId = useSelector((state) => state.devices.selectedId); const [positions, setPositions] = useState([]); @@ -210,7 +207,7 @@ const ReplayPage = () => { setIndex((index) => index + 1)} disabled={playing || index >= positions.length - 1}> - {formatTime(positions[index].fixTime, 'seconds', hours12)} + {formatTime(positions[index].fixTime, 'seconds')} ) : ( diff --git a/src/reports/ChartReportPage.jsx b/src/reports/ChartReportPage.jsx index 6175e1d8..8a3d01b8 100644 --- a/src/reports/ChartReportPage.jsx +++ b/src/reports/ChartReportPage.jsx @@ -13,7 +13,7 @@ import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; import { useCatch } from '../reactHelper'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import { altitudeFromMeters, distanceFromMeters, speedFromKnots, volumeFromLiters, } from '../common/util/converter'; @@ -29,7 +29,6 @@ const ChartReportPage = () => { const altitudeUnit = useAttributePreference('altitudeUnit'); const speedUnit = useAttributePreference('speedUnit'); const volumeUnit = useAttributePreference('volumeUnit'); - const hours12 = usePreference('twelveHourFormat'); const [items, setItems] = useState([]); const [types, setTypes] = useState(['speed']); @@ -126,7 +125,7 @@ const ChartReportPage = () => { formatTime(value, 'time', hours12)} + tickFormatter={(value) => formatTime(value, 'time')} domain={['dataMin', 'dataMax']} scale="time" /> @@ -138,7 +137,7 @@ const ChartReportPage = () => { [value, positionAttributes[key]?.name || key]} - labelFormatter={(value) => formatTime(value, 'seconds', hours12)} + labelFormatter={(value) => formatTime(value, 'seconds')} /> diff --git a/src/reports/CombinedReportPage.jsx b/src/reports/CombinedReportPage.jsx index a5000839..ab472dfa 100644 --- a/src/reports/CombinedReportPage.jsx +++ b/src/reports/CombinedReportPage.jsx @@ -15,7 +15,6 @@ import TableShimmer from '../common/components/TableShimmer'; import MapCamera from '../map/MapCamera'; import MapGeofence from '../map/MapGeofence'; import { formatTime } from '../common/util/formatter'; -import { usePreference } from '../common/util/preferences'; import { prefixString } from '../common/util/stringUtils'; import MapMarkers from '../map/MapMarkers'; @@ -25,8 +24,6 @@ const CombinedReportPage = () => { const devices = useSelector((state) => state.devices.items); - const hours12 = usePreference('twelveHourFormat'); - const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); @@ -90,7 +87,7 @@ const CombinedReportPage = () => { {!loading ? items.flatMap((item) => item.events.map((event, index) => ( {index ? '' : devices[item.deviceId].name} - {formatTime(event.eventTime, 'seconds', hours12)} + {formatTime(event.eventTime, 'seconds')} {t(prefixString('event', event.type))} ))) : ()} diff --git a/src/reports/EventReportPage.jsx b/src/reports/EventReportPage.jsx index 5dd97741..55c1452c 100644 --- a/src/reports/EventReportPage.jsx +++ b/src/reports/EventReportPage.jsx @@ -17,7 +17,7 @@ import ColumnSelect from './components/ColumnSelect'; import { useCatch, useEffectAsync } from '../reactHelper'; import useReportStyles from './common/useReportStyles'; import TableShimmer from '../common/components/TableShimmer'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import MapView from '../map/core/MapView'; import MapGeofence from '../map/MapGeofence'; import MapPositions from '../map/MapPositions'; @@ -42,7 +42,6 @@ const EventReportPage = () => { const geofences = useSelector((state) => state.geofences.items); const speedUnit = useAttributePreference('speedUnit'); - const hours12 = usePreference('twelveHourFormat'); const [allEventTypes, setAllEventTypes] = useState([['allEvents', 'eventAll']]); @@ -123,7 +122,7 @@ const EventReportPage = () => { const value = item[key]; switch (key) { case 'eventTime': - return formatTime(value, 'seconds', hours12); + return formatTime(value, 'seconds'); case 'type': return t(prefixString('event', value)); case 'geofenceId': diff --git a/src/reports/StatisticsPage.jsx b/src/reports/StatisticsPage.jsx index 7b3f2879..3d5dcf8c 100644 --- a/src/reports/StatisticsPage.jsx +++ b/src/reports/StatisticsPage.jsx @@ -12,7 +12,6 @@ import ColumnSelect from './components/ColumnSelect'; import { useCatch } from '../reactHelper'; import useReportStyles from './common/useReportStyles'; import TableShimmer from '../common/components/TableShimmer'; -import { usePreference } from '../common/util/preferences'; const columnsArray = [ ['captureTime', 'statisticsCaptureTime'], @@ -32,8 +31,6 @@ const StatisticsPage = () => { const classes = useReportStyles(); const t = useTranslation(); - const hours12 = usePreference('twelveHourFormat'); - const [columns, setColumns] = usePersistedState('statisticsColumns', ['captureTime', 'activeUsers', 'activeDevices', 'messagesStored']); const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); @@ -71,7 +68,7 @@ const StatisticsPage = () => { {columns.map((key) => ( - {key === 'captureTime' ? formatTime(item[key], 'date', hours12) : item[key]} + {key === 'captureTime' ? formatTime(item[key], 'date') : item[key]} ))} diff --git a/src/reports/StopReportPage.jsx b/src/reports/StopReportPage.jsx index 13a42cd4..c26351cd 100644 --- a/src/reports/StopReportPage.jsx +++ b/src/reports/StopReportPage.jsx @@ -10,7 +10,7 @@ import { formatDistance, formatVolume, formatTime, formatNumericHours, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -44,7 +44,6 @@ const StopReportPage = () => { const distanceUnit = useAttributePreference('distanceUnit'); const volumeUnit = useAttributePreference('volumeUnit'); - const hours12 = usePreference('twelveHourFormat'); const [columns, setColumns] = usePersistedState('stopColumns', ['startTime', 'endTime', 'startOdometer', 'address']); const [items, setItems] = useState([]); @@ -92,7 +91,7 @@ const StopReportPage = () => { switch (key) { case 'startTime': case 'endTime': - return formatTime(value, 'minutes', hours12); + return formatTime(value, 'minutes'); case 'startOdometer': return formatDistance(value, distanceUnit, t); case 'duration': diff --git a/src/reports/SummaryReportPage.jsx b/src/reports/SummaryReportPage.jsx index 4172514c..4d3d8b30 100644 --- a/src/reports/SummaryReportPage.jsx +++ b/src/reports/SummaryReportPage.jsx @@ -8,7 +8,7 @@ import { formatDistance, formatSpeed, formatVolume, formatTime, formatNumericHours, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -41,7 +41,6 @@ const SummaryReportPage = () => { const distanceUnit = useAttributePreference('distanceUnit'); const speedUnit = useAttributePreference('speedUnit'); const volumeUnit = useAttributePreference('volumeUnit'); - const hours12 = usePreference('twelveHourFormat'); const [columns, setColumns] = usePersistedState('summaryColumns', ['startTime', 'distance', 'averageSpeed']); const [daily, setDaily] = useState(false); @@ -93,7 +92,7 @@ const SummaryReportPage = () => { case 'deviceId': return devices[value].name; case 'startTime': - return formatTime(value, 'date', hours12); + return formatTime(value, 'date'); case 'startOdometer': case 'endOdometer': case 'distance': diff --git a/src/reports/TripReportPage.jsx b/src/reports/TripReportPage.jsx index 29bf33e5..67eca586 100644 --- a/src/reports/TripReportPage.jsx +++ b/src/reports/TripReportPage.jsx @@ -9,7 +9,7 @@ import { formatDistance, formatSpeed, formatVolume, formatTime, formatNumericHours, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference, usePreference } from '../common/util/preferences'; +import { useAttributePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -50,7 +50,6 @@ const TripReportPage = () => { const distanceUnit = useAttributePreference('distanceUnit'); const speedUnit = useAttributePreference('speedUnit'); const volumeUnit = useAttributePreference('volumeUnit'); - const hours12 = usePreference('twelveHourFormat'); const [columns, setColumns] = usePersistedState('tripColumns', ['startTime', 'endTime', 'distance', 'averageSpeed']); const [items, setItems] = useState([]); @@ -134,7 +133,7 @@ const TripReportPage = () => { switch (key) { case 'startTime': case 'endTime': - return formatTime(value, 'minutes', hours12); + return formatTime(value, 'minutes'); case 'startOdometer': case 'endOdometer': case 'distance': diff --git a/src/settings/DevicesPage.jsx b/src/settings/DevicesPage.jsx index c0da0ba7..831736e4 100644 --- a/src/settings/DevicesPage.jsx +++ b/src/settings/DevicesPage.jsx @@ -13,7 +13,6 @@ import CollectionFab from './components/CollectionFab'; import CollectionActions from './components/CollectionActions'; import TableShimmer from '../common/components/TableShimmer'; import SearchHeader, { filterByKeyword } from './components/SearchHeader'; -import { usePreference } from '../common/util/preferences'; import { formatTime } from '../common/util/formatter'; import { useDeviceReadonly } from '../common/util/permissions'; import useSettingsStyles from './common/useSettingsStyles'; @@ -25,8 +24,6 @@ const DevicesPage = () => { const groups = useSelector((state) => state.groups.items); - const hours12 = usePreference('twelveHourFormat'); - const deviceReadonly = useDeviceReadonly(); const [timestamp, setTimestamp] = useState(Date.now()); @@ -84,7 +81,7 @@ const DevicesPage = () => { {item.phone} {item.model} {item.contact} - {formatTime(item.expirationTime, 'date', hours12)} + {formatTime(item.expirationTime, 'date')} { label={t('serverAnnouncement')} /> - setItem({ ...item, twelveHourFormat: event.target.checked })} />} - label={t('settingsTwelveHourFormat')} - /> setItem({ ...item, forceSettings: event.target.checked })} />} label={t('serverForceSettings')} diff --git a/src/settings/UserPage.jsx b/src/settings/UserPage.jsx index 6748dd31..03a016c1 100644 --- a/src/settings/UserPage.jsx +++ b/src/settings/UserPage.jsx @@ -270,12 +270,6 @@ const UserPage = () => { onChange={(e) => setItem({ ...item, poiLayer: e.target.value })} label={t('mapPoiLayer')} /> - - setItem({ ...item, twelveHourFormat: e.target.checked })} />} - label={t('settingsTwelveHourFormat')} - /> - diff --git a/src/settings/UsersPage.jsx b/src/settings/UsersPage.jsx index 2941965b..030f6a18 100644 --- a/src/settings/UsersPage.jsx +++ b/src/settings/UsersPage.jsx @@ -15,7 +15,6 @@ import CollectionActions from './components/CollectionActions'; import TableShimmer from '../common/components/TableShimmer'; import { useManager } from '../common/util/permissions'; import SearchHeader, { filterByKeyword } from './components/SearchHeader'; -import { usePreference } from '../common/util/preferences'; import useSettingsStyles from './common/useSettingsStyles'; const UsersPage = () => { @@ -25,8 +24,6 @@ const UsersPage = () => { const manager = useManager(); - const hours12 = usePreference('twelveHourFormat'); - const [timestamp, setTimestamp] = useState(Date.now()); const [items, setItems] = useState([]); const [searchKeyword, setSearchKeyword] = useState(''); @@ -91,7 +88,7 @@ const UsersPage = () => { {item.email} {formatBoolean(item.administrator, t)} {formatBoolean(item.disabled, t)} - {formatTime(item.expirationTime, 'date', hours12)} + {formatTime(item.expirationTime, 'date')}