add host and tags params to main page
This commit is contained in:
parent
e2bd0c20c5
commit
ab3bf6f162
@ -3,13 +3,13 @@ import { notifications } from '@mantine/notifications';
|
|||||||
import { IconAlertCircle } from '@tabler/icons-react';
|
import { IconAlertCircle } from '@tabler/icons-react';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { useContext, useEffect, useMemo } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { Context } from '..';
|
import { Context } from '..';
|
||||||
import { isStartBiggerThanEndTime } from '../shared/utils/dateUtil';
|
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 { useLocation, useSearchParams } from 'react-router-dom';
|
|
||||||
|
|
||||||
export const eventsQueryParams = {
|
export const eventsQueryParams = {
|
||||||
hostId: 'hostId',
|
hostId: 'hostId',
|
||||||
@ -28,6 +28,13 @@ const EventsPage = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRightChildren(<EventsRightFilters />)
|
setRightChildren(<EventsRightFilters />)
|
||||||
|
const paramHostId = searchParams.get(eventsQueryParams.hostId) || undefined
|
||||||
|
const paramCameraId = searchParams.get(eventsQueryParams.cameraId) || undefined
|
||||||
|
const paramStartDate = searchParams.get(eventsQueryParams.startDate) || undefined
|
||||||
|
const paramEndDate = searchParams.get(eventsQueryParams.endDate) || undefined
|
||||||
|
const paramStartTime = searchParams.get(eventsQueryParams.startTime) || undefined
|
||||||
|
const paramEndTime = searchParams.get(eventsQueryParams.endTime) || undefined
|
||||||
|
eventsStore.loadFiltersFromPage(paramHostId, paramCameraId, paramStartDate, paramEndDate, paramStartTime, paramEndTime)
|
||||||
return () => setRightChildren(null)
|
return () => setRightChildren(null)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -37,13 +44,7 @@ const EventsPage = () => {
|
|||||||
const { hostId, cameraId, period, startTime, endTime } = eventsStore.filters
|
const { hostId, cameraId, period, startTime, endTime } = eventsStore.filters
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const paramHostId = searchParams.get(eventsQueryParams.hostId) || undefined
|
|
||||||
const paramCameraId = searchParams.get(eventsQueryParams.cameraId) || undefined
|
|
||||||
const paramStartDate = searchParams.get(eventsQueryParams.startDate) || undefined
|
|
||||||
const paramEndDate = searchParams.get(eventsQueryParams.endDate) || undefined
|
|
||||||
const paramStartTime = searchParams.get(eventsQueryParams.startTime) || undefined
|
|
||||||
const paramEndTime = searchParams.get(eventsQueryParams.endTime) || undefined
|
|
||||||
eventsStore.loadFiltersFromPage(paramHostId, paramCameraId, paramStartDate, paramEndDate, paramStartTime, paramEndTime)
|
|
||||||
}, [searchParams])
|
}, [searchParams])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Flex, Grid } from '@mantine/core';
|
import { Flex, Grid } from '@mantine/core';
|
||||||
|
import { IconSearch } from '@tabler/icons-react';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
import { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
@ -7,24 +8,30 @@ import { Context } from '..';
|
|||||||
import { useRealmUser } from '../hooks/useRealmUser';
|
import { useRealmUser } from '../hooks/useRealmUser';
|
||||||
import { frigateApi, frigateQueryKeys } from '../services/frigate.proxy/frigate.api';
|
import { frigateApi, frigateQueryKeys } from '../services/frigate.proxy/frigate.api';
|
||||||
import { GetCameraWHostWConfig } from '../services/frigate.proxy/frigate.schema';
|
import { GetCameraWHostWConfig } from '../services/frigate.proxy/frigate.schema';
|
||||||
|
import ClearableTextInput from '../shared/components/inputs/ClearableTextInput';
|
||||||
import CenterLoader from '../shared/components/loaders/CenterLoader';
|
import CenterLoader from '../shared/components/loaders/CenterLoader';
|
||||||
import { isProduction } from '../shared/env.const';
|
import { isProduction } from '../shared/env.const';
|
||||||
import CameraCard from '../widgets/CameraCard';
|
import CameraCard from '../widgets/CameraCard';
|
||||||
import MainFiltersRightSide from '../widgets/sidebars/MainFiltersRightSide';
|
import MainFiltersRightSide from '../widgets/sidebars/MainFiltersRightSide';
|
||||||
import { SideBarContext } from '../widgets/sidebars/SideBarContext';
|
import { SideBarContext } from '../widgets/sidebars/SideBarContext';
|
||||||
import RetryErrorPage from './RetryErrorPage';
|
import RetryErrorPage from './RetryErrorPage';
|
||||||
import { IconSearch } from '@tabler/icons-react';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import ClearableTextInput from '../shared/components/inputs/ClearableTextInput';
|
|
||||||
import { CameraTag } from '../types/tags';
|
export const mainPageParams = {
|
||||||
|
hostId: 'hostId',
|
||||||
|
selectedTags: 'selectedTags',
|
||||||
|
searchQuery: 'searchQuery',
|
||||||
|
}
|
||||||
|
|
||||||
const MainPage = () => {
|
const MainPage = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { mainStore } = useContext(Context)
|
const { mainStore } = useContext(Context)
|
||||||
|
const [searchParams] = useSearchParams()
|
||||||
|
|
||||||
const { setRightChildren } = useContext(SideBarContext)
|
const { setRightChildren } = useContext(SideBarContext)
|
||||||
const { selectedHostId, selectedTags } = mainStore
|
const { hostId: selectedHostId, selectedTags } = mainStore.filters
|
||||||
const [searchQuery, setSearchQuery] = useState<string>()
|
const [searchQuery, setSearchQuery] = useState<string>()
|
||||||
const [filteredCameras, setFilteredCameras] = useState<GetCameraWHostWConfig[]>()
|
const [filteredCameras, setFilteredCameras] = useState<GetCameraWHostWConfig[]>()
|
||||||
const [filteredTags, setFilteredTags] = useState<CameraTag[]>()
|
|
||||||
|
|
||||||
const realmUser = useRealmUser()
|
const realmUser = useRealmUser()
|
||||||
if (!isProduction) console.log('Realmuser:', realmUser)
|
if (!isProduction) console.log('Realmuser:', realmUser)
|
||||||
@ -36,6 +43,13 @@ const MainPage = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRightChildren(<MainFiltersRightSide />);
|
setRightChildren(<MainFiltersRightSide />);
|
||||||
|
const serializedTags = searchParams.get(mainPageParams.selectedTags)
|
||||||
|
const deSerializedTags = serializedTags ? mainStore.getArrayParam(serializedTags) : []
|
||||||
|
mainStore.loadFiltersFromPage({
|
||||||
|
hostId: searchParams.get(mainPageParams.hostId) || undefined,
|
||||||
|
searchQuery: searchParams.get(mainPageParams.searchQuery) || undefined,
|
||||||
|
selectedTags: deSerializedTags,
|
||||||
|
})
|
||||||
return () => setRightChildren(null);
|
return () => setRightChildren(null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@ -15,20 +15,6 @@ export class EventsStore {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
// this.loadFiltersFromURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadFiltersFromURL() {
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
|
||||||
this.filters.hostId = params.get(eventsQueryParams.hostId) || undefined;
|
|
||||||
this.filters.cameraId = params.get(eventsQueryParams.cameraId) || undefined;
|
|
||||||
const startDate = params.get(eventsQueryParams.startDate);
|
|
||||||
const endDate = params.get(eventsQueryParams.endDate);
|
|
||||||
if (startDate && endDate) {
|
|
||||||
this.filters.period = [new Date(startDate), new Date(endDate)]
|
|
||||||
}
|
|
||||||
this.filters.startTime = params.get(eventsQueryParams.startTime) || undefined
|
|
||||||
this.filters.endTime = params.get(eventsQueryParams.endTime) || undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFiltersFromPage(
|
loadFiltersFromPage(
|
||||||
@ -74,20 +60,20 @@ export class EventsStore {
|
|||||||
|
|
||||||
updateURL(navigate: (path: string, options?: NavigateOptions) => void) {
|
updateURL(navigate: (path: string, options?: NavigateOptions) => void) {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
if (this.filters.hostId) params.set('hostId', this.filters.hostId);
|
if (this.filters.hostId) params.set(eventsQueryParams.hostId, this.filters.hostId);
|
||||||
if (this.filters.cameraId) params.set('cameraId', this.filters.cameraId);
|
if (this.filters.cameraId) params.set(eventsQueryParams.cameraId, this.filters.cameraId);
|
||||||
if (this.filters.period) {
|
if (this.filters.period) {
|
||||||
const [startDate, endDate] = this.filters.period;
|
const [startDate, endDate] = this.filters.period;
|
||||||
if (startDate instanceof Date && !isNaN(startDate.getTime())) {
|
if (startDate instanceof Date && !isNaN(startDate.getTime())) {
|
||||||
params.set('startDate', startDate.toISOString());
|
params.set(eventsQueryParams.startDate, startDate.toISOString());
|
||||||
}
|
}
|
||||||
if (endDate instanceof Date && !isNaN(endDate.getTime())) {
|
if (endDate instanceof Date && !isNaN(endDate.getTime())) {
|
||||||
params.set('endDate', endDate.toISOString());
|
params.set(eventsQueryParams.endDate, endDate.toISOString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.filters.startTime) params.set('startTime', this.filters.startTime)
|
if (this.filters.startTime) params.set(eventsQueryParams.startTime, this.filters.startTime)
|
||||||
if (this.filters.endTime) params.set('endTime', this.filters.endTime)
|
if (this.filters.endTime) params.set(eventsQueryParams.endTime, this.filters.endTime)
|
||||||
|
|
||||||
navigate(`?${params.toString()}`, { replace: true });
|
navigate(`?${params.toString()}`, { replace: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,57 @@
|
|||||||
import { makeAutoObservable } from "mobx";
|
import { makeAutoObservable } from "mobx";
|
||||||
import { CameraTag } from "../../types/tags";
|
import { NavigateOptions } from "react-router-dom";
|
||||||
|
import { mainPageParams } from "../../pages/MainPage";
|
||||||
|
import { isProduction } from "../env.const";
|
||||||
|
|
||||||
|
|
||||||
|
interface Filters {
|
||||||
|
hostId?: string | null
|
||||||
|
searchQuery?: string | null
|
||||||
|
selectedTags: string[]
|
||||||
|
}
|
||||||
|
|
||||||
export class MainStore {
|
export class MainStore {
|
||||||
|
filters: Filters = { selectedTags: []}
|
||||||
private _selectedHostId: string | undefined
|
|
||||||
public get selectedHostId(): string | undefined {
|
|
||||||
return this._selectedHostId;
|
|
||||||
}
|
|
||||||
public set selectedHostId(value: string | undefined) {
|
|
||||||
this._selectedHostId = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private _selectedTags: string[] = [];
|
|
||||||
public get selectedTags(): string[] {
|
|
||||||
return this._selectedTags;
|
|
||||||
}
|
|
||||||
public set selectedTags(value: string[]) {
|
|
||||||
this._selectedTags = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this)
|
makeAutoObservable(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadFiltersFromPage(filters: Filters) {
|
||||||
|
if (!isProduction) console.log('MainPage load filters')
|
||||||
|
this.filters = filters
|
||||||
|
}
|
||||||
|
|
||||||
|
updateURL(navigate: (path: string, options?: NavigateOptions) => void) {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (this.filters.hostId) params.set(mainPageParams.hostId, this.filters.hostId);
|
||||||
|
if (this.filters.searchQuery) params.set(mainPageParams.searchQuery, this.filters.searchQuery);
|
||||||
|
if (this.filters.selectedTags) {
|
||||||
|
const serializedTags = this.filters.selectedTags.join(",")
|
||||||
|
params.set(mainPageParams.selectedTags, serializedTags);
|
||||||
|
}
|
||||||
|
navigate(`?${params.toString()}`, { replace: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
setHostId(hostId: string, navigate: (path: string, options?: NavigateOptions) => void) {
|
||||||
|
this.filters.hostId = hostId;
|
||||||
|
this.updateURL(navigate)
|
||||||
|
}
|
||||||
|
|
||||||
|
setSearchQuery(searchQuery: string, navigate: (path: string, options?: NavigateOptions) => void) {
|
||||||
|
this.filters.searchQuery = searchQuery;
|
||||||
|
this.updateURL(navigate)
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedTags(selectedTags: string[], navigate: (path: string, options?: NavigateOptions) => void) {
|
||||||
|
if (!isProduction) console.log('MainPage set filters.selectedTags ', selectedTags)
|
||||||
|
this.filters.selectedTags = selectedTags ? selectedTags : []
|
||||||
|
this.updateURL(navigate)
|
||||||
|
}
|
||||||
|
|
||||||
|
getArrayParam = (key: string): string[] => {
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
const paramValue = searchParams.get(key);
|
||||||
|
return paramValue ? paramValue.split(",") : [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,33 +5,32 @@ import { Context } from '../..';
|
|||||||
import HostSelect from '../../shared/components/filters/HostSelect';
|
import HostSelect from '../../shared/components/filters/HostSelect';
|
||||||
import UserTagsFilter from '../../shared/components/filters/UserTagsFilter';
|
import UserTagsFilter from '../../shared/components/filters/UserTagsFilter';
|
||||||
import { isProduction } from '../../shared/env.const';
|
import { isProduction } from '../../shared/env.const';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const MainFiltersRightSide = () => {
|
const MainFiltersRightSide = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const { mainStore } = useContext(Context)
|
const { mainStore } = useContext(Context)
|
||||||
const { selectedHostId } = mainStore
|
const { hostId } = mainStore.filters
|
||||||
|
|
||||||
const handleSelectHost = (value: string) => {
|
const handleSelectHost = (value: string) => {
|
||||||
if (!isProduction) console.log('handleSelectHost value', value)
|
if (!isProduction) console.log('handleSelectHost value', value)
|
||||||
mainStore.selectedHostId = value
|
mainStore.setHostId(value, navigate)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSelectTags = (tags: string[]) => {
|
const handleSelectTags = (tags: string[]) => {
|
||||||
if (!isProduction) console.log('handleSelectTags value', tags)
|
if (!isProduction) console.log('handleSelectTags value', tags)
|
||||||
mainStore.selectedTags = tags
|
mainStore.setSelectedTags(tags, navigate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HostSelect
|
<HostSelect
|
||||||
label={t('selectHost')}
|
label={t('selectHost')}
|
||||||
valueId={selectedHostId}
|
valueId={hostId || undefined}
|
||||||
defaultId={selectedHostId}
|
defaultId={hostId || undefined}
|
||||||
onChange={handleSelectHost}
|
onChange={handleSelectHost}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user