Search and search filter UI tweaks (#14381)

* fix search type switches

* select/unselect style for more filters button

* fix reset button

* fix labels scrollbar

* set min width and remove modal to allow scrolling with filters open

* hover colors

* better match of font size

* stop sheet from displaying console errors

* fix detail dialog behavior
This commit is contained in:
Josh Hawkins 2024-10-16 07:15:25 -05:00 committed by GitHub
parent 3f1ab66899
commit eda52a3b82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 86 additions and 45 deletions

View File

@ -113,7 +113,7 @@ export default function SearchThumbnailFooter({
}}
/>
<div className="flex flex-col items-start text-xs">
<div className="flex flex-col items-start text-xs text-primary-variant">
{searchResult.end_time ? (
<TimeAgo time={searchResult.start_time * 1000} dense />
) : (
@ -132,7 +132,7 @@ export default function SearchThumbnailFooter({
<Tooltip>
<TooltipTrigger>
<FrigatePlusIcon
className="size-5 cursor-pointer text-primary"
className="size-5 cursor-pointer text-primary-variant hover:text-primary"
onClick={() => setShowFrigatePlus(true)}
/>
</TooltipTrigger>
@ -144,7 +144,7 @@ export default function SearchThumbnailFooter({
<Tooltip>
<TooltipTrigger>
<MdImageSearch
className="size-5 cursor-pointer text-primary"
className="size-5 cursor-pointer text-primary-variant hover:text-primary"
onClick={findSimilar}
/>
</TooltipTrigger>
@ -154,7 +154,7 @@ export default function SearchThumbnailFooter({
<DropdownMenu>
<DropdownMenuTrigger>
<LuMoreVertical className="size-5 cursor-pointer text-primary" />
<LuMoreVertical className="size-5 cursor-pointer text-primary-variant hover:text-primary" />
</DropdownMenuTrigger>
<DropdownMenuContent align={"end"}>
{searchResult.has_clip && (

View File

@ -253,7 +253,11 @@ function GeneralFilterButton({
<PlatformAwareDialog
trigger={trigger}
content={content}
contentClassName={isDesktop ? "" : "max-h-[75dvh] overflow-hidden p-4"}
contentClassName={
isDesktop
? "scrollbar-container h-auto max-h-[80dvh] overflow-y-auto"
: "max-h-[75dvh] overflow-hidden p-4"
}
open={open}
onOpenChange={(open) => {
if (!open) {
@ -284,7 +288,7 @@ export function GeneralFilterContent({
}: GeneralFilterContentProps) {
return (
<>
<div className="scrollbar-container h-auto max-h-[80dvh] overflow-y-auto overflow-x-hidden">
<div className="overflow-x-hidden">
<div className="mb-5 mt-2.5 flex items-center justify-between">
<Label
className="mx-2 cursor-pointer text-primary"

View File

@ -102,7 +102,9 @@ export default function SearchDetailDialog({
const [isOpen, setIsOpen] = useState(search != undefined);
useEffect(() => {
if (search) {
setIsOpen(search != undefined);
}
}, [search]);
const searchTabs = useMemo(() => {
@ -122,12 +124,6 @@ export default function SearchDetailDialog({
views.splice(index, 1);
}
// TODO implement
//if (!config.semantic_search.enabled) {
// const index = views.indexOf("similar-calendar");
// views.splice(index, 1);
// }
return views;
}, [config, search]);
@ -154,14 +150,7 @@ export default function SearchDetailDialog({
const Description = isDesktop ? DialogDescription : MobilePageDescription;
return (
<Overlay
open={isOpen}
onOpenChange={(open) => {
if (!open) {
setSearch(undefined);
}
}}
>
<Overlay open={isOpen} onOpenChange={() => setIsOpen(!isOpen)}>
<Content
className={cn(
"scrollbar-container overflow-y-auto",

View File

@ -10,7 +10,14 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import { isMobile } from "react-device-detect";
type PlatformAwareDialogProps = {
@ -52,16 +59,20 @@ export default function PlatformAwareDialog({
type PlatformAwareSheetProps = {
trigger: JSX.Element;
title?: string | JSX.Element;
content: JSX.Element;
triggerClassName?: string;
titleClassName?: string;
contentClassName?: string;
open: boolean;
onOpenChange: (open: boolean) => void;
};
export function PlatformAwareSheet({
trigger,
title,
content,
triggerClassName = "",
titleClassName = "",
contentClassName = "",
open,
onOpenChange,
@ -86,11 +97,19 @@ export function PlatformAwareSheet({
}
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<Sheet open={open} onOpenChange={onOpenChange} modal={false}>
<SheetTrigger asChild className={triggerClassName}>
{trigger}
</SheetTrigger>
<SheetContent className={contentClassName}>{content}</SheetContent>
<SheetContent className={contentClassName}>
<SheetHeader>
<SheetTitle className={title ? titleClassName : "sr-only"}>
{title ?? ""}
</SheetTitle>
<SheetDescription className="sr-only">Information</SheetDescription>
</SheetHeader>
{content}
</SheetContent>
</Sheet>
);
}

View File

@ -18,7 +18,6 @@ import {
} from "@/components/ui/popover";
import { isDesktop, isMobileOnly } from "react-device-detect";
import { useFormattedHour } from "@/hooks/use-date-utils";
import Heading from "@/components/ui/heading";
import FilterSwitch from "@/components/filter/FilterSwitch";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
@ -51,9 +50,27 @@ export default function SearchFilterDialog({
const [open, setOpen] = useState(false);
const moreFiltersSelected = useMemo(
() =>
currentFilter &&
(currentFilter.time_range ||
(currentFilter.zones?.length ?? 0) > 0 ||
(currentFilter.sub_labels?.length ?? 0) > 0 ||
(currentFilter.search_type?.length ?? 2) !== 2),
[currentFilter],
);
const trigger = (
<Button className="flex items-center gap-2" size="sm">
<FaCog className={"text-secondary-foreground"} />
<Button
className="flex items-center gap-2"
size="sm"
variant={moreFiltersSelected ? "select" : "default"}
>
<FaCog
className={cn(
moreFiltersSelected ? "text-white" : "text-secondary-foreground",
)}
/>
More Filters
</Button>
);
@ -80,14 +97,20 @@ export default function SearchFilterDialog({
setCurrentFilter({ ...currentFilter, sub_labels: newSubLabels })
}
/>
{config?.semantic_search?.enabled &&
!currentFilter?.search_type?.includes("similarity") && (
<SearchTypeContent
searchSources={
currentFilter?.search_type ?? ["thumbnail", "description"]
}
setSearchSources={(newSearchSource) =>
onUpdateFilter({ ...currentFilter, search_type: newSearchSource })
setCurrentFilter({
...currentFilter,
search_type: newSearchSource,
})
}
/>
)}
{isDesktop && <DropdownMenuSeparator />}
<div className="flex items-center justify-evenly p-2">
<Button
@ -104,7 +127,13 @@ export default function SearchFilterDialog({
</Button>
<Button
onClick={() => {
setCurrentFilter(filter ?? {});
setCurrentFilter((prevFilter) => ({
...prevFilter,
time_range: undefined,
zones: undefined,
sub_labels: undefined,
search_type: ["thumbnail", "description"],
}));
}}
>
Reset
@ -118,7 +147,7 @@ export default function SearchFilterDialog({
trigger={trigger}
content={content}
contentClassName={cn(
"w-auto lg:w-[300px] scrollbar-container h-full overflow-auto px-4",
"w-auto lg:min-w-[275px] scrollbar-container h-full overflow-auto px-4",
isMobileOnly && "pb-20",
)}
open={open}
@ -184,8 +213,8 @@ function TimeRangeFilterContent({
return (
<div className="overflow-x-hidden">
<Heading as="h4">Time Range</Heading>
<div className="my-3 flex flex-row items-center justify-center gap-2">
<div className="text-lg">Time Range</div>
<div className="mt-3 flex flex-row items-center justify-center gap-2">
<Popover
open={startOpen}
onOpenChange={(open) => {
@ -280,7 +309,7 @@ export function ZoneFilterContent({
<>
<div className="overflow-x-hidden">
<DropdownMenuSeparator className="mb-3" />
<Heading as="h4">Zones</Heading>
<div className="text-lg">Zones</div>
{allZones && (
<>
<div className="mb-5 mt-2.5 flex items-center justify-between">
@ -301,7 +330,7 @@ export function ZoneFilterContent({
}}
/>
</div>
<div className="my-2.5 flex flex-col gap-2.5">
<div className="mt-2.5 flex flex-col gap-2.5">
{allZones.map((item) => (
<FilterSwitch
key={item}
@ -346,7 +375,7 @@ export function SubFilterContent({
return (
<div className="overflow-x-hidden">
<DropdownMenuSeparator className="mb-3" />
<Heading as="h4">Sub Labels</Heading>
<div className="text-lg">Sub Labels</div>
<div className="mb-5 mt-2.5 flex items-center justify-between">
<Label className="mx-2 cursor-pointer text-primary" htmlFor="allLabels">
All Sub Labels
@ -362,7 +391,7 @@ export function SubFilterContent({
}}
/>
</div>
<div className="my-2.5 flex flex-col gap-2.5">
<div className="mt-2.5 flex flex-col gap-2.5">
{allSubLabels.map((item) => (
<FilterSwitch
key={item}
@ -403,8 +432,8 @@ export function SearchTypeContent({
<>
<div className="overflow-x-hidden">
<DropdownMenuSeparator className="mb-3" />
<Heading as="h4">Search Sources</Heading>
<div className="my-2.5 flex flex-col gap-2.5">
<div className="text-lg">Search Sources</div>
<div className="mt-2.5 flex flex-col gap-2.5">
<FilterSwitch
label="Thumbnail Image"
isChecked={searchSources?.includes("thumbnail") ?? false}