add tags filter to main page

This commit is contained in:
NlightN22 2024-09-30 16:05:38 +07:00
parent f50bfa6cb6
commit 12b508661a
5 changed files with 51 additions and 16 deletions

View File

@ -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<string>()
const [filteredCameras, setFilteredCameras] = useState<GetCameraWHostWConfig[]>()
const [filteredTags, setFilteredTags] = useState<CameraTag[]>()
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 = () => {
</Flex>
<Flex justify='center' h='100%' direction='column' w='100%' >
<Grid mt='sm' justify="center" mb='sm' align='stretch'>
{/* TODO DELETE SLICE TO WORK */}
{cards.slice(0, 5)}
{cards}
</Grid>
</Flex>
</Flex>

View File

@ -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<UserTagsFilterProps> = ({
onChange
}) => {
const { t } = useTranslation()
const queryClient = useQueryClient()
const [selectedList, setSelectedList] = useState<string[]>([])
useEffect(() => {
if (onChange) onChange(selectedList)
}, [selectedList])
const { data, isPending, isError, refetch } = useQuery({
queryKey: [frigateQueryKeys.getUserTags],
queryFn: frigateApi.getUserTags

View File

@ -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)
}

View File

@ -18,6 +18,8 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
camera
}) => {
const queryClient = useQueryClient()
const [tagsList, setTagsList] = useState<CameraTag[]>(camera.tags)
useEffect(() => {
@ -35,6 +37,7 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
}),
onSuccess: (data) => {
setTagsList(data.tags)
queryClient.invalidateQueries({ queryKey: [frigateQueryKeys.getCamerasWHost] })
},
onError: (e) => {
if (e && e.message) {
@ -51,7 +54,6 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
}
})
const { mutate: deleteTagFromCamera } = useMutation({
mutationFn: (tagId: string) => frigateApi.deleteTagFromCamera(camera.id, tagId)
.catch(error => {
@ -60,7 +62,11 @@ const CameraTagsList: React.FC<CameraTagsListProps> = ({
}
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({

View File

@ -16,21 +16,28 @@ const MainFiltersRightSide = () => {
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 (
<>
<HostSelect
label={t('selectHost')}
valueId={selectedHostId}
defaultId={selectedHostId}
onChange={handleSelect}
onChange={handleSelectHost}
/>
<UserTagsFilter />
<UserTagsFilter
onChange={handleSelectTags}
/>
</>
);