diff options
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/common/components/PositionValue.js | 3 | ||||
-rw-r--r-- | modern/src/common/util/formatter.js | 17 | ||||
-rw-r--r-- | modern/src/main/EventsDrawer.js | 8 | ||||
-rw-r--r-- | modern/src/map/MapPositions.js | 5 | ||||
-rw-r--r-- | modern/src/other/ReplayPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/ChartReportPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/EventReportPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/StatisticsPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/StopReportPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/SummaryReportPage.js | 5 | ||||
-rw-r--r-- | modern/src/reports/TripReportPage.js | 5 | ||||
-rw-r--r-- | modern/src/settings/CalendarPage.js | 10 | ||||
-rw-r--r-- | modern/src/settings/UsersPage.js | 5 |
13 files changed, 60 insertions, 23 deletions
diff --git a/modern/src/common/components/PositionValue.js b/modern/src/common/components/PositionValue.js index a851c886..27f793c6 100644 --- a/modern/src/common/components/PositionValue.js +++ b/modern/src/common/components/PositionValue.js @@ -24,13 +24,14 @@ const PositionValue = ({ position, property, attribute }) => { const altitudeUnit = useAttributePreference('altitudeUnit'); const speedUnit = useAttributePreference('speedUnit'); const coordinateFormat = usePreference('coordinateFormat'); + const hours12 = usePreference('twelveHourFormat'); const formatValue = () => { switch (key) { case 'fixTime': case 'deviceTime': case 'serverTime': - return formatTime(value); + return formatTime(value, 'seconds', hours12); case 'latitude': return formatCoordinate('latitude', value, coordinateFormat); case 'longitude': diff --git a/modern/src/common/util/formatter.js b/modern/src/common/util/formatter.js index 88398c68..56c02547 100644 --- a/modern/src/common/util/formatter.js +++ b/modern/src/common/util/formatter.js @@ -17,7 +17,22 @@ export const formatNumber = (value, precision = 1) => Number(value.toFixed(preci export const formatPercentage = (value) => `${value}%`; -export const formatTime = (value, format = 'YYYY-MM-DD HH:mm:ss') => (value ? moment(value).format(format) : ''); +export const formatTime = (value, format, hours12) => { + if (value) { + const m = moment(value); + switch (format) { + case 'date': + return m.format('YYYY-MM-DD'); + case 'time': + return m.format(hours12 ? 'hh:mm:ss A' : 'HH:mm:ss'); + case 'minutes': + return m.format(hours12 ? 'YYYY-MM-DD hh:mm A' : 'YYYY-MM-DD HH:mm'); + default: + return m.format(hours12 ? 'YYYY-MM-DD hh:mm:ss A' : 'YYYY-MM-DD HH:mm:ss'); + } + } + return ''; +}; export const formatStatus = (value, t) => t(prefixString('deviceStatus', value)); export const formatAlarm = (value, t) => (value ? t(prefixString('alarm', value)) : ''); diff --git a/modern/src/main/EventsDrawer.js b/modern/src/main/EventsDrawer.js index 46664f87..67700fc4 100644 --- a/modern/src/main/EventsDrawer.js +++ b/modern/src/main/EventsDrawer.js @@ -9,6 +9,7 @@ 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: { @@ -29,6 +30,8 @@ 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); @@ -61,7 +64,10 @@ const EventsDrawer = ({ open, onClose }) => { onClick={() => navigate(`/event/${event.id}`)} disabled={!event.id} > - <ListItemText primary={`${devices[event.deviceId]?.name} • ${formatType(event)}`} secondary={formatTime(event.eventTime)} /> + <ListItemText + primary={`${devices[event.deviceId]?.name} • ${formatType(event)}`} + secondary={formatTime(event.eventTime, 'seconds', hours12)} + /> <IconButton size="small" onClick={() => dispatch(eventsActions.delete(event))}> <DeleteIcon fontSize="small" className={classes.negative} /> </IconButton> diff --git a/modern/src/map/MapPositions.js b/modern/src/map/MapPositions.js index e334800c..2f038ec6 100644 --- a/modern/src/map/MapPositions.js +++ b/modern/src/map/MapPositions.js @@ -4,7 +4,7 @@ import { map } from './core/MapView'; import { formatTime, getStatusColor } from '../common/util/formatter'; import { mapIconKey } from './core/preloadImages'; import { findFonts } from './core/mapUtil'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleField }) => { const id = useId(); @@ -15,6 +15,7 @@ const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleF const iconScale = useAttributePreference('iconScale', 1); const mapCluster = useAttributePreference('mapCluster', true); + const hours12 = usePreference('twelveHourFormat'); const createFeature = (devices, position, selectedPositionId) => { const device = devices[position.deviceId]; @@ -22,7 +23,7 @@ const MapPositions = ({ positions, onClick, showStatus, selectedPosition, titleF id: position.id, deviceId: position.deviceId, name: device.name, - fixTime: formatTime(position.fixTime), + fixTime: formatTime(position.fixTime, 'seconds', hours12), category: mapIconKey(device.category), color: showStatus ? position.attributes.color || getStatusColor(device.status) : 'neutral', rotation: position.course, diff --git a/modern/src/other/ReplayPage.js b/modern/src/other/ReplayPage.js index 8839138f..1050b976 100644 --- a/modern/src/other/ReplayPage.js +++ b/modern/src/other/ReplayPage.js @@ -25,6 +25,7 @@ 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: { @@ -81,6 +82,8 @@ const ReplayPage = () => { const navigate = useNavigate(); const timerRef = useRef(); + const hours12 = usePreference('twelveHourFormat'); + const defaultDeviceId = useSelector((state) => state.devices.selectedId); const [positions, setPositions] = useState([]); @@ -207,7 +210,7 @@ const ReplayPage = () => { <IconButton onClick={() => setIndex((index) => index + 1)} disabled={playing || index >= positions.length - 1}> <FastForwardIcon /> </IconButton> - {formatTime(positions[index].fixTime)} + {formatTime(positions[index].fixTime, 'seconds', hours12)} </div> </> ) : ( diff --git a/modern/src/reports/ChartReportPage.js b/modern/src/reports/ChartReportPage.js index 4605a5b9..3a4aeb4f 100644 --- a/modern/src/reports/ChartReportPage.js +++ b/modern/src/reports/ChartReportPage.js @@ -12,7 +12,7 @@ import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; import { useCatch } from '../reactHelper'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; import { altitudeFromMeters, distanceFromMeters, speedFromKnots, volumeFromLiters, } from '../common/util/converter'; @@ -28,6 +28,7 @@ const ChartReportPage = () => { const altitudeUnit = useAttributePreference('altitudeUnit'); const speedUnit = useAttributePreference('speedUnit'); const volumeUnit = useAttributePreference('volumeUnit'); + const hours12 = usePreference('twelveHourFormat'); const [items, setItems] = useState([]); const [type, setType] = useState('speed'); @@ -47,7 +48,7 @@ const ChartReportPage = () => { const formattedPositions = positions.map((position) => { const data = { ...position, ...position.attributes }; const formatted = {}; - formatted.fixTime = formatTime(position.fixTime, 'HH:mm:ss'); + formatted.fixTime = formatTime(position.fixTime, 'time', hours12); Object.keys(data).forEach((key) => { const value = data[key]; if (typeof value === 'number') { diff --git a/modern/src/reports/EventReportPage.js b/modern/src/reports/EventReportPage.js index ce1772e4..67bbd888 100644 --- a/modern/src/reports/EventReportPage.js +++ b/modern/src/reports/EventReportPage.js @@ -16,7 +16,7 @@ import ColumnSelect from './components/ColumnSelect'; import { useCatch, useEffectAsync } from '../reactHelper'; import useReportStyles from './common/useReportStyles'; import TableShimmer from '../common/components/TableShimmer'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; import MapView from '../map/core/MapView'; import MapGeofence from '../map/MapGeofence'; import MapPositions from '../map/MapPositions'; @@ -39,6 +39,7 @@ const EventReportPage = () => { const geofences = useSelector((state) => state.geofences.items); const speedUnit = useAttributePreference('speedUnit'); + const hours12 = usePreference('twelveHourFormat'); const [allEventTypes, setAllEventTypes] = useState([['allEvents', 'eventAll']]); @@ -105,7 +106,7 @@ const EventReportPage = () => { const formatValue = (item, key) => { switch (key) { case 'eventTime': - return formatTime(item[key]); + return formatTime(item[key], 'seconds', hours12); case 'type': return t(prefixString('event', item[key])); case 'geofenceId': diff --git a/modern/src/reports/StatisticsPage.js b/modern/src/reports/StatisticsPage.js index 254a912d..7b3f2879 100644 --- a/modern/src/reports/StatisticsPage.js +++ b/modern/src/reports/StatisticsPage.js @@ -12,6 +12,7 @@ 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'], @@ -31,6 +32,8 @@ 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); @@ -68,7 +71,7 @@ const StatisticsPage = () => { <TableRow key={item.id}> {columns.map((key) => ( <TableCell key={key}> - {key === 'captureTime' ? formatTime(item[key], 'YYYY-MM-DD') : item[key]} + {key === 'captureTime' ? formatTime(item[key], 'date', hours12) : item[key]} </TableCell> ))} </TableRow> diff --git a/modern/src/reports/StopReportPage.js b/modern/src/reports/StopReportPage.js index a322304e..ce790401 100644 --- a/modern/src/reports/StopReportPage.js +++ b/modern/src/reports/StopReportPage.js @@ -9,7 +9,7 @@ import { formatDistance, formatHours, formatVolume, formatTime, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -41,6 +41,7 @@ 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([]); @@ -77,7 +78,7 @@ const StopReportPage = () => { switch (key) { case 'startTime': case 'endTime': - return formatTime(item[key], 'YYYY-MM-DD HH:mm'); + return formatTime(item[key], 'minutes', hours12); case 'startOdometer': return formatDistance(item[key], distanceUnit, t); case 'duration': diff --git a/modern/src/reports/SummaryReportPage.js b/modern/src/reports/SummaryReportPage.js index f8216155..d66d58c6 100644 --- a/modern/src/reports/SummaryReportPage.js +++ b/modern/src/reports/SummaryReportPage.js @@ -7,7 +7,7 @@ import { formatDistance, formatHours, formatSpeed, formatVolume, formatTime, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -38,6 +38,7 @@ 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); @@ -77,7 +78,7 @@ const SummaryReportPage = () => { case 'deviceId': return devices[item[key]].name; case 'startTime': - return item[key] ? formatTime(item[key], 'YYYY-MM-DD') : null; + return formatTime(item[key], 'date', hours12); case 'startOdometer': case 'endOdometer': case 'distance': diff --git a/modern/src/reports/TripReportPage.js b/modern/src/reports/TripReportPage.js index 63988850..ffe16241 100644 --- a/modern/src/reports/TripReportPage.js +++ b/modern/src/reports/TripReportPage.js @@ -8,7 +8,7 @@ import { formatDistance, formatSpeed, formatHours, formatVolume, formatTime, } from '../common/util/formatter'; import ReportFilter from './components/ReportFilter'; -import { useAttributePreference } from '../common/util/preferences'; +import { useAttributePreference, usePreference } from '../common/util/preferences'; import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; @@ -47,6 +47,7 @@ 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([]); @@ -119,7 +120,7 @@ const TripReportPage = () => { switch (key) { case 'startTime': case 'endTime': - return formatTime(item[key], 'YYYY-MM-DD HH:mm'); + return formatTime(item[key], 'minutes', hours12); case 'startOdometer': case 'endOdometer': case 'distance': diff --git a/modern/src/settings/CalendarPage.js b/modern/src/settings/CalendarPage.js index 81f0021d..17848484 100644 --- a/modern/src/settings/CalendarPage.js +++ b/modern/src/settings/CalendarPage.js @@ -13,7 +13,7 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import SettingsMenu from './components/SettingsMenu'; import { prefixString } from '../common/util/stringUtils'; -const formatTime = (time) => { +const formatCalendarTime = (time) => { const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone; return `TZID=${tzid}:${time.locale('en').format('YYYYMMDDTHHmmss')}`; }; @@ -47,8 +47,8 @@ const simpleCalendar = () => window.btoa([ 'PRODID:-//Traccar//NONSGML Traccar//EN', 'BEGIN:VEVENT', 'UID:00000000-0000-0000-0000-000000000000', - `DTSTART;${formatTime(moment())}`, - `DTEND;${formatTime(moment().add(1, 'hours'))}`, + `DTSTART;${formatCalendarTime(moment())}`, + `DTEND;${formatCalendarTime(moment().add(1, 'hours'))}`, 'RRULE:FREQ=DAILY', 'SUMMARY:Event', 'END:VEVENT', @@ -133,7 +133,7 @@ const CalendarPage = () => { type="datetime-local" value={moment(lines[5].slice(-15)).locale('en').format(moment.HTML5_FMT.DATETIME_LOCAL)} onChange={(e) => { - const time = formatTime(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL)); + const time = formatCalendarTime(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL)); setItem({ ...item, data: updateCalendar(lines, 5, `DTSTART;${time}`) }); }} /> @@ -142,7 +142,7 @@ const CalendarPage = () => { type="datetime-local" value={moment(lines[6].slice(-15)).locale('en').format(moment.HTML5_FMT.DATETIME_LOCAL)} onChange={(e) => { - const time = formatTime(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL)); + const time = formatCalendarTime(moment(e.target.value, moment.HTML5_FMT.DATETIME_LOCAL)); setItem({ ...item, data: updateCalendar(lines, 6, `DTEND;${time}`) }); }} /> diff --git a/modern/src/settings/UsersPage.js b/modern/src/settings/UsersPage.js index bdebb1bb..6cb10d25 100644 --- a/modern/src/settings/UsersPage.js +++ b/modern/src/settings/UsersPage.js @@ -14,6 +14,7 @@ import CollectionActions from './components/CollectionActions'; import TableShimmer from '../common/components/TableShimmer'; import { useAdministrator } from '../common/util/permissions'; import SearchHeader, { filterByKeyword } from './components/SearchHeader'; +import { usePreference } from '../common/util/preferences'; const useStyles = makeStyles((theme) => ({ columnAction: { @@ -28,6 +29,8 @@ const UsersPage = () => { const admin = useAdministrator(); + const hours12 = usePreference('twelveHourFormat'); + const [timestamp, setTimestamp] = useState(Date.now()); const [items, setItems] = useState([]); const [searchKeyword, setSearchKeyword] = useState(''); @@ -83,7 +86,7 @@ const UsersPage = () => { <TableCell>{item.email}</TableCell> <TableCell>{formatBoolean(item.administrator, t)}</TableCell> <TableCell>{formatBoolean(item.disabled, t)}</TableCell> - <TableCell>{formatTime(item.expirationTime, 'YYYY-MM-DD')}</TableCell> + <TableCell>{formatTime(item.expirationTime, 'date', hours12)}</TableCell> <TableCell className={classes.columnAction} padding="none"> <CollectionActions itemId={item.id} |