mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add severity filter (#11190)
* Allow viewing all types on single screen * Implement for mobile as well * fix import * Show all is optional
This commit is contained in:
parent
499f70cfd3
commit
b5b819c866
@ -3,24 +3,27 @@ import { Label } from "../ui/label";
|
||||
|
||||
type FilterSwitchProps = {
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
isChecked: boolean;
|
||||
onCheckedChange: (checked: boolean) => void;
|
||||
};
|
||||
export default function FilterSwitch({
|
||||
label,
|
||||
disabled = false,
|
||||
isChecked,
|
||||
onCheckedChange,
|
||||
}: FilterSwitchProps) {
|
||||
return (
|
||||
<div className="flex justify-between items-center gap-1">
|
||||
<Label
|
||||
className="w-full mx-2 text-primary capitalize cursor-pointer"
|
||||
className={`w-full mx-2 text-primary capitalize cursor-pointer ${disabled ? "text-secondary-foreground" : ""}`}
|
||||
htmlFor={label}
|
||||
>
|
||||
{label}
|
||||
</Label>
|
||||
<Switch
|
||||
id={label}
|
||||
disabled={disabled}
|
||||
checked={isChecked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
/>
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "../ui/dropdown-menu";
|
||||
import { ReviewFilter, ReviewSummary } from "@/types/review";
|
||||
import { ReviewFilter, ReviewSeverity, ReviewSummary } from "@/types/review";
|
||||
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
||||
import {
|
||||
@ -49,19 +49,21 @@ const DEFAULT_REVIEW_FILTERS: ReviewFilters[] = [
|
||||
|
||||
type ReviewFilterGroupProps = {
|
||||
filters?: ReviewFilters[];
|
||||
currentSeverity?: ReviewSeverity;
|
||||
reviewSummary?: ReviewSummary;
|
||||
filter?: ReviewFilter;
|
||||
onUpdateFilter: (filter: ReviewFilter) => void;
|
||||
motionOnly: boolean;
|
||||
onUpdateFilter: (filter: ReviewFilter) => void;
|
||||
setMotionOnly: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
};
|
||||
|
||||
export default function ReviewFilterGroup({
|
||||
filters = DEFAULT_REVIEW_FILTERS,
|
||||
currentSeverity,
|
||||
reviewSummary,
|
||||
filter,
|
||||
onUpdateFilter,
|
||||
motionOnly,
|
||||
onUpdateFilter,
|
||||
setMotionOnly,
|
||||
}: ReviewFilterGroupProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
@ -179,6 +181,11 @@ export default function ReviewFilterGroup({
|
||||
<GeneralFilterButton
|
||||
allLabels={filterValues.labels}
|
||||
selectedLabels={filter?.labels}
|
||||
currentSeverity={currentSeverity}
|
||||
showAll={filter?.showAll == true}
|
||||
setShowAll={(showAll) => {
|
||||
onUpdateFilter({ ...filter, showAll });
|
||||
}}
|
||||
updateLabelFilter={(newLabels) => {
|
||||
onUpdateFilter({ ...filter, labels: newLabels });
|
||||
}}
|
||||
@ -188,6 +195,7 @@ export default function ReviewFilterGroup({
|
||||
<MobileReviewSettingsDrawer
|
||||
features={mobileSettingsFeatures}
|
||||
filter={filter}
|
||||
currentSeverity={currentSeverity}
|
||||
reviewSummary={reviewSummary}
|
||||
onUpdateFilter={onUpdateFilter}
|
||||
// not applicable as exports are not used
|
||||
@ -477,11 +485,17 @@ function CalendarFilterButton({
|
||||
type GeneralFilterButtonProps = {
|
||||
allLabels: string[];
|
||||
selectedLabels: string[] | undefined;
|
||||
currentSeverity?: ReviewSeverity;
|
||||
showAll: boolean;
|
||||
setShowAll: (showAll: boolean) => void;
|
||||
updateLabelFilter: (labels: string[] | undefined) => void;
|
||||
};
|
||||
function GeneralFilterButton({
|
||||
allLabels,
|
||||
selectedLabels,
|
||||
currentSeverity,
|
||||
showAll,
|
||||
setShowAll,
|
||||
updateLabelFilter,
|
||||
}: GeneralFilterButtonProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
@ -510,6 +524,9 @@ function GeneralFilterButton({
|
||||
allLabels={allLabels}
|
||||
selectedLabels={selectedLabels}
|
||||
currentLabels={currentLabels}
|
||||
currentSeverity={currentSeverity}
|
||||
showAll={showAll}
|
||||
setShowAll={setShowAll}
|
||||
updateLabelFilter={updateLabelFilter}
|
||||
setCurrentLabels={setCurrentLabels}
|
||||
onClose={() => setOpen(false)}
|
||||
@ -557,6 +574,9 @@ type GeneralFilterContentProps = {
|
||||
allLabels: string[];
|
||||
selectedLabels: string[] | undefined;
|
||||
currentLabels: string[] | undefined;
|
||||
currentSeverity?: ReviewSeverity;
|
||||
showAll?: boolean;
|
||||
setShowAll?: (showAll: boolean) => void;
|
||||
updateLabelFilter: (labels: string[] | undefined) => void;
|
||||
setCurrentLabels: (labels: string[] | undefined) => void;
|
||||
onClose: () => void;
|
||||
@ -565,6 +585,9 @@ export function GeneralFilterContent({
|
||||
allLabels,
|
||||
selectedLabels,
|
||||
currentLabels,
|
||||
currentSeverity,
|
||||
showAll,
|
||||
setShowAll,
|
||||
updateLabelFilter,
|
||||
setCurrentLabels,
|
||||
onClose,
|
||||
@ -572,6 +595,25 @@ export function GeneralFilterContent({
|
||||
return (
|
||||
<>
|
||||
<div className="h-auto max-h-[80dvh] overflow-y-auto overflow-x-hidden">
|
||||
{currentSeverity && setShowAll && (
|
||||
<div className="my-2.5 flex flex-col gap-2.5">
|
||||
<FilterSwitch
|
||||
label="Alerts"
|
||||
disabled={currentSeverity == "alert"}
|
||||
isChecked={currentSeverity == "alert" ? true : showAll == true}
|
||||
onCheckedChange={setShowAll}
|
||||
/>
|
||||
<FilterSwitch
|
||||
label="Detections"
|
||||
disabled={currentSeverity == "detection"}
|
||||
isChecked={
|
||||
currentSeverity == "detection" ? true : showAll == true
|
||||
}
|
||||
onCheckedChange={setShowAll}
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between items-center my-2.5">
|
||||
<Label
|
||||
className="mx-2 text-primary cursor-pointer"
|
||||
|
@ -7,7 +7,7 @@ import { ExportContent } from "./ExportDialog";
|
||||
import { ExportMode } from "@/types/filter";
|
||||
import ReviewActivityCalendar from "./ReviewActivityCalendar";
|
||||
import { SelectSeparator } from "../ui/select";
|
||||
import { ReviewFilter, ReviewSummary } from "@/types/review";
|
||||
import { ReviewFilter, ReviewSeverity, ReviewSummary } from "@/types/review";
|
||||
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
||||
import { GeneralFilterContent } from "../filter/ReviewFilterGroup";
|
||||
import useSWR from "swr";
|
||||
@ -31,6 +31,7 @@ type MobileReviewSettingsDrawerProps = {
|
||||
features?: DrawerFeatures[];
|
||||
camera: string;
|
||||
filter?: ReviewFilter;
|
||||
currentSeverity?: ReviewSeverity;
|
||||
latestTime: number;
|
||||
currentTime: number;
|
||||
range?: TimeRange;
|
||||
@ -44,6 +45,7 @@ export default function MobileReviewSettingsDrawer({
|
||||
features = DEFAULT_DRAWER_FEATURES,
|
||||
camera,
|
||||
filter,
|
||||
currentSeverity,
|
||||
latestTime,
|
||||
currentTime,
|
||||
range,
|
||||
@ -263,6 +265,11 @@ export default function MobileReviewSettingsDrawer({
|
||||
allLabels={allLabels}
|
||||
selectedLabels={filter?.labels}
|
||||
currentLabels={currentLabels}
|
||||
currentSeverity={currentSeverity}
|
||||
showAll={filter?.showAll == true}
|
||||
setShowAll={(showAll) => {
|
||||
onUpdateFilter({ ...filter, showAll });
|
||||
}}
|
||||
setCurrentLabels={setCurrentLabels}
|
||||
updateLabelFilter={(newLabels) =>
|
||||
onUpdateFilter({ ...filter, labels: newLabels })
|
||||
|
@ -26,6 +26,7 @@ export type ReviewFilter = {
|
||||
before?: number;
|
||||
after?: number;
|
||||
showReviewed?: 0 | 1;
|
||||
showAll?: boolean;
|
||||
};
|
||||
|
||||
type ReviewSummaryDay = {
|
||||
|
@ -270,6 +270,7 @@ export default function EventView({
|
||||
? ["cameras", "date", "motionOnly"]
|
||||
: ["cameras", "reviewed", "date", "general"]
|
||||
}
|
||||
currentSeverity={severityToggle}
|
||||
reviewSummary={reviewSummary}
|
||||
filter={filter}
|
||||
onUpdateFilter={updateFilter}
|
||||
@ -370,7 +371,13 @@ function DetectionReview({
|
||||
return null;
|
||||
}
|
||||
|
||||
const current = reviewItems[severity];
|
||||
let current;
|
||||
|
||||
if (filter?.showAll) {
|
||||
current = reviewItems.all;
|
||||
} else {
|
||||
current = reviewItems[severity];
|
||||
}
|
||||
|
||||
if (!current || current.length == 0) {
|
||||
return [];
|
||||
|
Loading…
Reference in New Issue
Block a user