fix errors message

add time validation
This commit is contained in:
NlightN22 2024-10-01 03:12:55 +07:00
parent f935de1eeb
commit 14df894b34
11 changed files with 67 additions and 13 deletions

View File

@ -17,6 +17,7 @@ const en = {
eventsPage: { eventsPage: {
selectStartTime: 'Select start time:', selectStartTime: 'Select start time:',
selectEndTime: 'Select end time:', selectEndTime: 'Select end time:',
startTimeBiggerThanEnd: 'Start time bigger than end time',
}, },
frigateConfigPage: { frigateConfigPage: {
copyConfig: 'Copy Config', copyConfig: 'Copy Config',

View File

@ -15,7 +15,7 @@ const ru = {
eventsPage: { eventsPage: {
selectStartTime: 'Выбери время начала:', selectStartTime: 'Выбери время начала:',
selectEndTime: 'Выбери время окончания:', selectEndTime: 'Выбери время окончания:',
maxEventsFetches: 'Ошибка: Невозможно получить события после {{maxRetries}} попыток. Пожалуйста попробуйте позже или установите меньший период.', startTimeBiggerThanEnd: 'Время начала больше времени окончания',
}, },
frigateConfigPage: { frigateConfigPage: {
copyConfig: 'Копировать Конфиг.', copyConfig: 'Копировать Конфиг.',
@ -97,6 +97,7 @@ const ru = {
doubleClickToFullHint: 'Двойное нажатие мышью для полноэкранного просмотра', doubleClickToFullHint: 'Двойное нажатие мышью для полноэкранного просмотра',
rating: 'Рейтинг', rating: 'Рейтинг',
}, },
maxRetries: 'Ошибка: невозможно получить данные после {{maxRetries}} попыток. Пожалуйста попробуйте позже или поменяйте период на меньший.',
config: 'Конфиг.', config: 'Конфиг.',
create: 'Создать', create: 'Создать',
clear: 'Очистить', clear: 'Очистить',

View File

@ -93,7 +93,7 @@ const EditCameraPage = () => {
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: false, autoClose: false,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,

View File

@ -1,12 +1,14 @@
import { Flex, Text } from '@mantine/core'; import { Flex, Text } from '@mantine/core';
import { notifications } from '@mantine/notifications';
import { t } from 'i18next'; import { t } from 'i18next';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useContext, useEffect } from 'react'; import { useContext, useEffect, useState } from 'react';
import { Context } from '..'; import { Context } from '..';
import { isStartBiggerThanEndTime } from '../shared/utils/dateUtil';
import EventsBody from '../widgets/EventsBody'; import EventsBody from '../widgets/EventsBody';
import EventsRightFilters from '../widgets/sidebars/EventsRightFilters'; import EventsRightFilters from '../widgets/sidebars/EventsRightFilters';
import { SideBarContext } from '../widgets/sidebars/SideBarContext'; import { SideBarContext } from '../widgets/sidebars/SideBarContext';
import { isProduction } from '../shared/env.const'; import { IconAlertCircle } from '@tabler/icons-react';
export const eventsPageQuery = { export const eventsPageQuery = {
hostId: 'hostId', hostId: 'hostId',
@ -16,8 +18,15 @@ export const eventsPageQuery = {
hour: 'hour', hour: 'hour',
} }
interface TimePeriod {
startTime: string,
endTime: string,
}
const EventsPage = () => { const EventsPage = () => {
const [timePeriod, setTimePeriod] = useState<TimePeriod>()
const { setRightChildren } = useContext(SideBarContext) const { setRightChildren } = useContext(SideBarContext)
useEffect(() => { useEffect(() => {
@ -25,17 +34,43 @@ const EventsPage = () => {
return () => setRightChildren(null) return () => setRightChildren(null)
}, []) }, [])
const { eventsStore } = useContext(Context) const { eventsStore } = useContext(Context)
const { hostId, cameraId, period, startTime, endTime } = eventsStore.filters const { hostId, cameraId, period, startTime, endTime } = eventsStore.filters
useEffect(() => {
const startTime = eventsStore.filters.startTime
const endTime = eventsStore.filters.endTime
if (startTime && endTime) {
if (isStartBiggerThanEndTime(startTime, endTime)) {
const message = t('eventsPage.startTimeBiggerThanEnd')
notifications.show({
id: message,
withCloseButton: true,
autoClose: 5000,
title: t('error'),
message: message,
color: 'red',
icon: <IconAlertCircle />,
})
return
}
setTimePeriod({
startTime,
endTime
})
}
}, [eventsStore.filters.startTime, eventsStore.filters.endTime])
if (hostId && cameraId && period && period[0] && period[1]) { if (hostId && cameraId && period && period[0] && period[1]) {
return ( return (
<EventsBody <EventsBody
hostId={hostId} hostId={hostId}
cameraId={cameraId} cameraId={cameraId}
period={[period[0], period[1]]} period={[period[0], period[1]]}
startTime={startTime} startTime={timePeriod?.startTime}
endTime={endTime} endTime={timePeriod?.endTime}
/> />
) )
} }

View File

@ -63,7 +63,7 @@ const FrigateHostsPage = () => {
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: 5000, autoClose: 5000,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,

View File

@ -85,7 +85,7 @@ const HostConfigPage = () => {
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: false, autoClose: false,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,

View File

@ -71,7 +71,7 @@ const UserTagsFilter: React.FC<UserTagsFilterProps> = ({
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: 5000, autoClose: 5000,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,
@ -100,7 +100,7 @@ const UserTagsFilter: React.FC<UserTagsFilterProps> = ({
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: 5000, autoClose: 5000,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,

View File

@ -168,6 +168,18 @@ export const dayTimeToUnixTime = (day: Date, time: string) => {
return Math.floor(day.getTime() / 1000) return Math.floor(day.getTime() / 1000)
} }
export const isStartBiggerThanEndTime = (startTime: string, endTime: string) => {
const [hours1, minutes1] = startTime.split(':').map(Number)
const [hours2, minutes2] = endTime.split(':').map(Number)
const date1 = new Date();
const date2 = new Date();
date1.setHours(hours1, minutes1, 0, 0)
date2.setHours(hours2, minutes2, 0, 0)
return date1 > date2
}
/** /**
* This function takes in a Unix timestamp, configuration options for date/time display, and an optional strftime format string, * This function takes in a Unix timestamp, configuration options for date/time display, and an optional strftime format string,
* and returns a formatted date/time string. * and returns a formatted date/time string.

View File

@ -8,6 +8,7 @@ import { GetCameraWHostWConfig } from '../services/frigate.proxy/frigate.schema'
import AddBadge from '../shared/components/AddBadge'; import AddBadge from '../shared/components/AddBadge';
import TagBadge from '../shared/components/TagBadge'; import TagBadge from '../shared/components/TagBadge';
import { CameraTag } from '../types/tags'; import { CameraTag } from '../types/tags';
import { useTranslation } from 'react-i18next';
interface CameraTagsListProps { interface CameraTagsListProps {
@ -18,6 +19,7 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
camera camera
}) => { }) => {
const { t } = useTranslation()
const queryClient = useQueryClient() const queryClient = useQueryClient()
const [tagsList, setTagsList] = useState<CameraTag[]>(camera.tags) const [tagsList, setTagsList] = useState<CameraTag[]>(camera.tags)
@ -45,7 +47,7 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: 5000, autoClose: 5000,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,
@ -73,7 +75,7 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
id: e.message, id: e.message,
withCloseButton: true, withCloseButton: true,
autoClose: 5000, autoClose: 5000,
title: "Error", title: t('error'),
message: e.message, message: e.message,
color: 'red', color: 'red',
icon: <IconAlertCircle />, icon: <IconAlertCircle />,

View File

@ -15,6 +15,7 @@ interface EventsBodyProps {
endTime?: string, endTime?: string,
} }
const EventsBody: FC<EventsBodyProps> = ({ const EventsBody: FC<EventsBodyProps> = ({
hostId, hostId,
cameraId, cameraId,

View File

@ -1,5 +1,5 @@
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useContext } from 'react'; import { useContext, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Context } from '../..'; import { Context } from '../..';
@ -9,6 +9,8 @@ import HostSelect from '../../shared/components/filters/HostSelect';
import TimePicker from '../../shared/components/filters/TimePicker'; import TimePicker from '../../shared/components/filters/TimePicker';
import { isProduction } from '../../shared/env.const'; import { isProduction } from '../../shared/env.const';
const EventsRightFilters = () => { const EventsRightFilters = () => {
const { t } = useTranslation() const { t } = useTranslation()