diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index 56614f7..181e5c6 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -15,14 +15,16 @@ import { SideBarContext } from '../widgets/sidebars/SideBarContext'; import RetryErrorPage from './RetryErrorPage'; import { IconSearch } from '@tabler/icons-react'; import ClearableTextInput from '../shared/components/inputs/ClearableTextInput'; +import { CameraTag } from '../types/tags'; const MainPage = () => { const { t } = useTranslation() const { mainStore } = useContext(Context) const { setChildrenComponent } = useContext(SideBarContext) - const { selectedHostId } = mainStore + const { selectedHostId, selectedTags } = mainStore const [searchQuery, setSearchQuery] = useState() const [filteredCameras, setFilteredCameras] = useState() + const [filteredTags, setFilteredTags] = useState() const realmUser = useRealmUser() if (!isProduction) console.log('Realmuser:', realmUser) @@ -46,11 +48,12 @@ const MainPage = () => { const filterCameras = (camera: GetCameraWHostWConfig) => { const matchesHostId = selectedHostId ? camera.frigateHost?.id === selectedHostId : true const matchesSearchQuery = searchQuery ? camera.name.toLowerCase().includes(searchQuery.toLowerCase()) : true - return matchesHostId && matchesSearchQuery + const matchesTags = selectedTags.length === 0 || camera.tags.some( tag => selectedTags.includes(tag.id)) + return matchesHostId && matchesSearchQuery && matchesTags } setFilteredCameras(cameras.filter(filterCameras)) - }, [searchQuery, cameras, selectedHostId]) + }, [searchQuery, cameras, selectedHostId, selectedTags]) const cards = useMemo(() => { @@ -100,8 +103,7 @@ const MainPage = () => { - {/* TODO DELETE SLICE TO WORK */} - {cards.slice(0, 5)} + {cards} diff --git a/src/shared/components/filters/UserTagsFilter.tsx b/src/shared/components/filters/UserTagsFilter.tsx index 057116a..ab02b20 100644 --- a/src/shared/components/filters/UserTagsFilter.tsx +++ b/src/shared/components/filters/UserTagsFilter.tsx @@ -1,6 +1,6 @@ import { SelectItem } from '@mantine/core'; import { t } from 'i18next'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { z } from 'zod'; import CreatableMultiSelect from './CreatableMultiSelect'; import { useTranslation } from 'react-i18next'; @@ -13,13 +13,23 @@ import { notifications } from '@mantine/notifications'; import { IconAlertCircle } from '@tabler/icons-react'; +interface UserTagsFilterProps { + onChange?(tagIds: string[]): void +} -const UserTagsFilter = () => { + +const UserTagsFilter: React.FC = ({ + onChange +}) => { const { t } = useTranslation() const queryClient = useQueryClient() const [selectedList, setSelectedList] = useState([]) + useEffect(() => { + if (onChange) onChange(selectedList) + }, [selectedList]) + const { data, isPending, isError, refetch } = useQuery({ queryKey: [frigateQueryKeys.getUserTags], queryFn: frigateApi.getUserTags diff --git a/src/shared/stores/main.store.ts b/src/shared/stores/main.store.ts index 1dddcfe..ae20fe2 100644 --- a/src/shared/stores/main.store.ts +++ b/src/shared/stores/main.store.ts @@ -1,4 +1,5 @@ import { makeAutoObservable } from "mobx"; +import { CameraTag } from "../../types/tags"; export class MainStore { @@ -10,6 +11,15 @@ export class MainStore { this._selectedHostId = value; } + + private _selectedTags: string[] = []; + public get selectedTags(): string[] { + return this._selectedTags; + } + public set selectedTags(value: string[]) { + this._selectedTags = value; + } + constructor() { makeAutoObservable(this) } diff --git a/src/widgets/CameraTagsList.tsx b/src/widgets/CameraTagsList.tsx index 6cfec66..755abc3 100644 --- a/src/widgets/CameraTagsList.tsx +++ b/src/widgets/CameraTagsList.tsx @@ -18,11 +18,13 @@ const CameraTagsList: React.FC = ({ camera }) => { + const queryClient = useQueryClient() + const [tagsList, setTagsList] = useState(camera.tags) - useEffect(()=>{ + useEffect(() => { setTagsList(camera.tags) - },[camera]) + }, [camera]) const { mutate: addTagToCamera } = useMutation({ @@ -35,6 +37,7 @@ const CameraTagsList: React.FC = ({ }), onSuccess: (data) => { setTagsList(data.tags) + queryClient.invalidateQueries({ queryKey: [frigateQueryKeys.getCamerasWHost] }) }, onError: (e) => { if (e && e.message) { @@ -51,7 +54,6 @@ const CameraTagsList: React.FC = ({ } }) - const { mutate: deleteTagFromCamera } = useMutation({ mutationFn: (tagId: string) => frigateApi.deleteTagFromCamera(camera.id, tagId) .catch(error => { @@ -60,7 +62,11 @@ const CameraTagsList: React.FC = ({ } return Promise.reject(error) }), - onSuccess: (data) => setTagsList(data.tags), + onSuccess: (data) => { + setTagsList(data.tags) + queryClient.invalidateQueries({ queryKey: [frigateQueryKeys.getCamerasWHost] }) + } + , onError: (e) => { if (e && e.message) { notifications.show({ @@ -95,7 +101,7 @@ const CameraTagsList: React.FC = ({ onClose={handleDeleteTagClick} /> )) - : <> + : <> } { const { mainStore } = useContext(Context) const { selectedHostId } = mainStore - const handleSelect = (value: string) => { - if (!isProduction) console.log('handleSelect value', value) + const handleSelectHost = (value: string) => { + if (!isProduction) console.log('handleSelectHost value', value) mainStore.selectedHostId = value } + const handleSelectTags = (tags: string[]) => { + if (!isProduction) console.log('handleSelectTags value', tags) + mainStore.selectedTags = tags + } + return ( <> - + );