diff --git a/web/src/App.tsx b/web/src/App.tsx index 60488cb56..07e901735 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -13,6 +13,7 @@ import { isPWA } from "./utils/isPWA"; const Live = lazy(() => import("@/pages/Live")); const Events = lazy(() => import("@/pages/Events")); +const Search = lazy(() => import("@/pages/Search")); const Exports = lazy(() => import("@/pages/Exports")); const SubmitPlus = lazy(() => import("@/pages/SubmitPlus")); const ConfigEditor = lazy(() => import("@/pages/ConfigEditor")); @@ -44,6 +45,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/web/src/hooks/use-navigation.ts b/web/src/hooks/use-navigation.ts index 771dde088..fde200839 100644 --- a/web/src/hooks/use-navigation.ts +++ b/web/src/hooks/use-navigation.ts @@ -4,10 +4,18 @@ import { FrigateConfig } from "@/types/frigateConfig"; import { NavData } from "@/types/navigation"; import { useMemo } from "react"; import { FaCompactDisc, FaVideo } from "react-icons/fa"; +import { IoSearch } from "react-icons/io5"; import { LuConstruction } from "react-icons/lu"; import { MdVideoLibrary } from "react-icons/md"; import useSWR from "swr"; +export const ID_LIVE = 1; +export const ID_REVIEW = 2; +export const ID_SEARCH = 3; +export const ID_EXPORT = 4; +export const ID_PLUS = 5; +export const ID_PLAYGROUND = 6; + export default function useNavigation( variant: "primary" | "secondary" = "primary", ) { @@ -17,28 +25,36 @@ export default function useNavigation( () => [ { - id: 1, + id: ID_LIVE, variant, icon: FaVideo, title: "Live", url: "/", }, { - id: 2, + id: ID_REVIEW, variant, icon: MdVideoLibrary, title: "Review", url: "/review", }, { - id: 3, + id: ID_SEARCH, + variant, + icon: IoSearch, + title: "Search", + url: "/search", + enabled: config?.semantic_search?.enabled, + }, + { + id: ID_EXPORT, variant, icon: FaCompactDisc, title: "Export", url: "/export", }, { - id: 5, + id: ID_PLUS, variant, icon: Logo, title: "Frigate+", @@ -46,7 +62,7 @@ export default function useNavigation( enabled: config?.plus?.enabled == true, }, { - id: 4, + id: ID_PLAYGROUND, variant, icon: LuConstruction, title: "UI Playground", @@ -54,6 +70,6 @@ export default function useNavigation( enabled: ENV !== "production", }, ] as NavData[], - [config?.plus.enabled, variant], + [config?.plus.enabled, config?.semantic_search.enabled, variant], ); } diff --git a/web/src/pages/Search.tsx b/web/src/pages/Search.tsx new file mode 100644 index 000000000..4b5809c9a --- /dev/null +++ b/web/src/pages/Search.tsx @@ -0,0 +1,32 @@ +import { Input } from "@/components/ui/input"; +import { Toaster } from "@/components/ui/sonner"; +import { useState } from "react"; +import { LuSearchCheck } from "react-icons/lu"; + +export default function Search() { + const [searchTerm, setSearchTerm] = useState(""); + + return ( +
+ + +
+ setSearchTerm(e.target.value)} + /> +
+ +
+ {searchTerm == "" && ( +
+ + Search For Detections +
+ )} +
+
+ ); +} diff --git a/web/src/types/frigateConfig.ts b/web/src/types/frigateConfig.ts index 2eb7622d6..1c60f2971 100644 --- a/web/src/types/frigateConfig.ts +++ b/web/src/types/frigateConfig.ts @@ -391,6 +391,10 @@ export interface FrigateConfig { enabled: boolean; }; + semantic_search: { + enabled: boolean; + } + snapshots: { bounding_box: boolean; clean_copy: boolean;