fixes and changes (#10587)

This commit is contained in:
Josh Hawkins 2024-03-21 09:00:04 -05:00 committed by GitHub
parent 865c26ff18
commit 4040191101
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 156 additions and 114 deletions

View File

@ -43,7 +43,7 @@ export default function NewReviewData({
return ( return (
<div className={className}> <div className={className}>
<div className="flex justify-center items-center md:mr-[115px] pointer-events-auto"> <div className="flex justify-center items-center mr-[65px] md:mr-[115px] pointer-events-auto">
<Button <Button
className={`${ className={`${
hasUpdate hasUpdate

View File

@ -197,7 +197,12 @@ export function EventSegment({
}, [startTimestamp]); }, [startTimestamp]);
return ( return (
<div key={segmentKey} className={segmentClasses}> <div
key={segmentKey}
className={segmentClasses}
onClick={segmentClick}
onTouchEnd={(event) => handleTouchStart(event, segmentClick)}
>
<MinimapBounds <MinimapBounds
isFirstSegmentInMinimap={isFirstSegmentInMinimap} isFirstSegmentInMinimap={isFirstSegmentInMinimap}
isLastSegmentInMinimap={isLastSegmentInMinimap} isLastSegmentInMinimap={isLastSegmentInMinimap}
@ -219,34 +224,36 @@ export function EventSegment({
{severity.map((severityValue: number, index: number) => ( {severity.map((severityValue: number, index: number) => (
<React.Fragment key={index}> <React.Fragment key={index}>
{severityValue === displaySeverityType && ( {severityValue === displaySeverityType && (
<HoverCard openDelay={200} closeDelay={100}> <div className="absolute left-1/2 transform -translate-x-1/2 w-[20px] md:w-[40px] h-2 z-10 cursor-pointer">
<div <div className="flex flex-row justify-center w-[20px] md:w-[40px]">
className="absolute left-1/2 transform -translate-x-1/2 w-[8px] h-2 ml-[2px] z-10 cursor-pointer" <div className="flex justify-center">
data-severity={severityValue} <HoverCard openDelay={200} closeDelay={100}>
> <div
<HoverCardTrigger asChild> className="absolute left-1/2 transform -translate-x-1/2 w-[8px] h-2 ml-[2px] z-10 cursor-pointer"
<div data-severity={severityValue}
key={`${segmentKey}_${index}_primary_data`} >
className={`w-full h-2 bg-gradient-to-r ${roundBottomPrimary ? "rounded-bl-full rounded-br-full" : ""} ${roundTopPrimary ? "rounded-tl-full rounded-tr-full" : ""} ${severityColors[severityValue]}`} <HoverCardTrigger asChild>
onClick={segmentClick} <div
onTouchEnd={(event) => key={`${segmentKey}_${index}_primary_data`}
handleTouchStart(event, segmentClick) className={`w-full h-2 bg-gradient-to-r ${roundBottomPrimary ? "rounded-bl-full rounded-br-full" : ""} ${roundTopPrimary ? "rounded-tl-full rounded-tr-full" : ""} ${severityColors[severityValue]}`}
} ></div>
></div> </HoverCardTrigger>
</HoverCardTrigger> <HoverCardPortal>
<HoverCardPortal> <HoverCardContent
<HoverCardContent className="rounded-2xl w-[250px] p-2"
className="rounded-2xl w-[250px] p-2" side="left"
side="left" >
> <img
<img className="rounded-lg"
className="rounded-lg" src={`${apiHost}${eventThumbnail.replace("/media/frigate/", "")}`}
src={`${apiHost}${eventThumbnail.replace("/media/frigate/", "")}`} />
/> </HoverCardContent>
</HoverCardContent> </HoverCardPortal>
</HoverCardPortal> </div>
</HoverCard>
</div>
</div> </div>
</HoverCard> </div>
)} )}
</React.Fragment> </React.Fragment>
))} ))}

View File

@ -11,6 +11,7 @@ import MotionSegment from "./MotionSegment";
import { useTimelineUtils } from "@/hooks/use-timeline-utils"; import { useTimelineUtils } from "@/hooks/use-timeline-utils";
import { MotionData, ReviewSegment, ReviewSeverity } from "@/types/review"; import { MotionData, ReviewSegment, ReviewSeverity } from "@/types/review";
import ReviewTimeline from "./ReviewTimeline"; import ReviewTimeline from "./ReviewTimeline";
import { isDesktop } from "react-device-detect";
export type MotionReviewTimelineProps = { export type MotionReviewTimelineProps = {
segmentDuration: number; segmentDuration: number;
@ -218,7 +219,7 @@ export function MotionReviewTimeline({
const segmentsObserver = useRef<IntersectionObserver | null>(null); const segmentsObserver = useRef<IntersectionObserver | null>(null);
const selectedTimelineRef = timelineRef || internalTimelineRef; const selectedTimelineRef = timelineRef || internalTimelineRef;
useEffect(() => { useEffect(() => {
if (selectedTimelineRef.current && segments) { if (selectedTimelineRef.current && segments && isDesktop) {
segmentsObserver.current = new IntersectionObserver( segmentsObserver.current = new IntersectionObserver(
(entries) => { (entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {

View File

@ -5,7 +5,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
import scrollIntoView from "scroll-into-view-if-needed"; import scrollIntoView from "scroll-into-view-if-needed";
import { MinimapBounds, Tick, Timestamp } from "./segment-metadata"; import { MinimapBounds, Tick, Timestamp } from "./segment-metadata";
import { useMotionSegmentUtils } from "@/hooks/use-motion-segment-utils"; import { useMotionSegmentUtils } from "@/hooks/use-motion-segment-utils";
import { isMobile } from "react-device-detect"; import { isDesktop, isMobile } from "react-device-detect";
import useTapUtils from "@/hooks/use-tap-utils"; import useTapUtils from "@/hooks/use-tap-utils";
type MotionSegmentProps = { type MotionSegmentProps = {
@ -155,6 +155,11 @@ export function MotionSegment({
: "" : ""
}`; }`;
const animationClassesSecondHalf = `motion-segment ${secondHalfSegmentWidth > 1 ? "hidden" : ""}
zoom-in-[0.2] ${secondHalfSegmentWidth < 5 ? "duration-200" : "duration-1000"}`;
const animationClassesFirstHalf = `motion-segment ${firstHalfSegmentWidth > 1 ? "hidden" : ""}
zoom-in-[0.2] ${firstHalfSegmentWidth < 5 ? "duration-200" : "duration-1000"}`;
const severityColors: { [key: number]: string } = { const severityColors: { [key: number]: string } = {
1: reviewed 1: reviewed
? "from-severity_motion-dimmed/50 to-severity_motion/50" ? "from-severity_motion-dimmed/50 to-severity_motion/50"
@ -204,7 +209,7 @@ export function MotionSegment({
<div className="flex justify-center"> <div className="flex justify-center">
<div <div
key={`${segmentKey}_motion_data_1`} key={`${segmentKey}_motion_data_1`}
className={`motion-segment ${secondHalfSegmentWidth > 1 ? "hidden" : ""} zoom-in-[0.2] ${secondHalfSegmentWidth < 5 ? "duration-200" : "duration-1000"} h-[2px] rounded-full ${severity[0] != 0 ? "bg-motion_review-dimmed" : "bg-motion_review"}`} className={`${isDesktop && animationClassesSecondHalf} h-[2px] rounded-full ${severity[0] != 0 ? "bg-motion_review-dimmed" : "bg-motion_review"}`}
style={{ style={{
width: secondHalfSegmentWidth, width: secondHalfSegmentWidth,
}} }}
@ -216,7 +221,7 @@ export function MotionSegment({
<div className="flex justify-center"> <div className="flex justify-center">
<div <div
key={`${segmentKey}_motion_data_2`} key={`${segmentKey}_motion_data_2`}
className={`motion-segment ${firstHalfSegmentWidth > 1 ? "hidden" : ""} zoom-in-[0.2] ${firstHalfSegmentWidth < 5 ? "duration-200" : "duration-1000"} h-[2px] rounded-full ${severity[0] != 0 ? "bg-motion_review-dimmed" : "bg-motion_review"}`} className={`${isDesktop && animationClassesFirstHalf} h-[2px] rounded-full ${severity[0] != 0 ? "bg-motion_review-dimmed" : "bg-motion_review"}`}
style={{ style={{
width: firstHalfSegmentWidth, width: firstHalfSegmentWidth,
}} }}

View File

@ -14,16 +14,8 @@ export type ReviewTimelineProps = {
timelineRef: RefObject<HTMLDivElement>; timelineRef: RefObject<HTMLDivElement>;
handlebarRef: RefObject<HTMLDivElement>; handlebarRef: RefObject<HTMLDivElement>;
handlebarTimeRef: RefObject<HTMLDivElement>; handlebarTimeRef: RefObject<HTMLDivElement>;
handlebarMouseMove: ( handlebarMouseMove: (e: MouseEvent | TouchEvent) => void;
e: handlebarMouseUp: (e: MouseEvent | TouchEvent) => void;
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
handlebarMouseUp: (
e:
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
handlebarMouseDown: ( handlebarMouseDown: (
e: e:
| React.MouseEvent<HTMLDivElement, MouseEvent> | React.MouseEvent<HTMLDivElement, MouseEvent>
@ -37,31 +29,15 @@ export type ReviewTimelineProps = {
exportStartTimeRef: RefObject<HTMLDivElement>; exportStartTimeRef: RefObject<HTMLDivElement>;
exportEndRef: RefObject<HTMLDivElement>; exportEndRef: RefObject<HTMLDivElement>;
exportEndTimeRef: RefObject<HTMLDivElement>; exportEndTimeRef: RefObject<HTMLDivElement>;
exportStartMouseMove: ( exportStartMouseMove: (e: MouseEvent | TouchEvent) => void;
e: exportStartMouseUp: (e: MouseEvent | TouchEvent) => void;
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
exportStartMouseUp: (
e:
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
exportStartMouseDown: ( exportStartMouseDown: (
e: e:
| React.MouseEvent<HTMLDivElement, MouseEvent> | React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>, | React.TouchEvent<HTMLDivElement>,
) => void; ) => void;
exportEndMouseMove: ( exportEndMouseMove: (e: MouseEvent | TouchEvent) => void;
e: exportEndMouseUp: (e: MouseEvent | TouchEvent) => void;
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
exportEndMouseUp: (
e:
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => void;
exportEndMouseDown: ( exportEndMouseDown: (
e: e:
| React.MouseEvent<HTMLDivElement, MouseEvent> | React.MouseEvent<HTMLDivElement, MouseEvent>
@ -152,11 +128,7 @@ export function ReviewTimeline({
); );
const handleMouseMove = useCallback( const handleMouseMove = useCallback(
( (e: MouseEvent | TouchEvent) => {
e:
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => {
switch (draggableElementType) { switch (draggableElementType) {
case "export_start": case "export_start":
exportStartMouseMove(e); exportStartMouseMove(e);
@ -181,11 +153,7 @@ export function ReviewTimeline({
); );
const handleMouseUp = useCallback( const handleMouseUp = useCallback(
( (e: MouseEvent | TouchEvent) => {
e:
| React.MouseEvent<HTMLDivElement, MouseEvent>
| React.TouchEvent<HTMLDivElement>,
) => {
switch (draggableElementType) { switch (draggableElementType) {
case "export_start": case "export_start":
exportStartMouseUp(e); exportStartMouseUp(e);
@ -227,13 +195,32 @@ export function ReviewTimeline({
exportEndPosition, exportEndPosition,
]); ]);
const documentRef = useRef<Document | null>(document);
useEffect(() => {
const documentInstance = documentRef.current;
if (isDragging) {
documentInstance?.addEventListener("mousemove", handleMouseMove);
documentInstance?.addEventListener("touchmove", handleMouseMove);
documentInstance?.addEventListener("mouseup", handleMouseUp);
documentInstance?.addEventListener("touchend", handleMouseUp);
} else {
documentInstance?.removeEventListener("mousemove", handleMouseMove);
documentInstance?.removeEventListener("touchmove", handleMouseMove);
documentInstance?.removeEventListener("mouseup", handleMouseUp);
documentInstance?.removeEventListener("touchend", handleMouseUp);
}
return () => {
documentInstance?.removeEventListener("mousemove", handleMouseMove);
documentInstance?.removeEventListener("touchmove", handleMouseMove);
documentInstance?.removeEventListener("mouseup", handleMouseUp);
documentInstance?.removeEventListener("touchend", handleMouseUp);
};
}, [handleMouseMove, handleMouseUp, isDragging]);
return ( return (
<div <div
ref={timelineRef} ref={timelineRef}
onMouseMove={handleMouseMove}
onTouchMove={handleMouseMove}
onMouseUp={handleMouseUp}
onTouchEnd={handleMouseUp}
className={`relative h-full overflow-y-auto no-scrollbar select-none bg-secondary ${ className={`relative h-full overflow-y-auto no-scrollbar select-none bg-secondary ${
isDragging && (showHandlebar || showExportHandles) isDragging && (showHandlebar || showExportHandles)
? "cursor-grabbing" ? "cursor-grabbing"

View File

@ -1,5 +1,5 @@
import { useEventSegmentUtils } from "@/hooks/use-event-segment-utils"; import { useEventSegmentUtils } from "@/hooks/use-event-segment-utils";
import { ReviewSegment } from "@/types/review"; import { ReviewSegment, ReviewSeverity } from "@/types/review";
import React, { useMemo } from "react"; import React, { useMemo } from "react";
// import useTapUtils from "@/hooks/use-tap-utils"; // import useTapUtils from "@/hooks/use-tap-utils";
@ -8,6 +8,7 @@ type SummarySegmentProps = {
segmentTime: number; segmentTime: number;
segmentDuration: number; segmentDuration: number;
segmentHeight: number; segmentHeight: number;
severityType: ReviewSeverity;
}; };
export function SummarySegment({ export function SummarySegment({
@ -15,8 +16,8 @@ export function SummarySegment({
segmentTime, segmentTime,
segmentDuration, segmentDuration,
segmentHeight, segmentHeight,
severityType,
}: SummarySegmentProps) { }: SummarySegmentProps) {
const severityType = "all";
const { getSeverity, getReviewed, displaySeverityType } = const { getSeverity, getReviewed, displaySeverityType } =
useEventSegmentUtils(segmentDuration, events, severityType); useEventSegmentUtils(segmentDuration, events, severityType);
@ -44,9 +45,9 @@ export function SummarySegment({
className="relative w-full" className="relative w-full"
style={{ height: segmentHeight }} style={{ height: segmentHeight }}
> >
{severity.map((severityValue: number, index: number) => { {severity.map((severityValue: number, index: number) => (
return ( <React.Fragment key={index}>
<React.Fragment key={index}> {severityValue === displaySeverityType && (
<div <div
className="flex justify-end cursor-pointer" className="flex justify-end cursor-pointer"
style={{ height: segmentHeight }} style={{ height: segmentHeight }}
@ -57,9 +58,9 @@ export function SummarySegment({
className={`w-[10px] ${severityColors[severityValue]}`} className={`w-[10px] ${severityColors[severityValue]}`}
></div> ></div>
</div> </div>
</React.Fragment> )}
); </React.Fragment>
})} ))}
</div> </div>
); );
} }

View File

@ -8,7 +8,7 @@ import {
} from "react"; } from "react";
import { SummarySegment } from "./SummarySegment"; import { SummarySegment } from "./SummarySegment";
import { useTimelineUtils } from "@/hooks/use-timeline-utils"; import { useTimelineUtils } from "@/hooks/use-timeline-utils";
import { ReviewSegment } from "@/types/review"; import { ReviewSegment, ReviewSeverity } from "@/types/review";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
export type SummaryTimelineProps = { export type SummaryTimelineProps = {
@ -17,6 +17,7 @@ export type SummaryTimelineProps = {
timelineEnd: number; timelineEnd: number;
segmentDuration: number; segmentDuration: number;
events: ReviewSegment[]; events: ReviewSegment[];
severityType: ReviewSeverity;
}; };
export function SummaryTimeline({ export function SummaryTimeline({
@ -25,6 +26,7 @@ export function SummaryTimeline({
timelineEnd, timelineEnd,
segmentDuration, segmentDuration,
events, events,
severityType,
}: SummaryTimelineProps) { }: SummaryTimelineProps) {
const summaryTimelineRef = useRef<HTMLDivElement>(null); const summaryTimelineRef = useRef<HTMLDivElement>(null);
const visibleSectionRef = useRef<HTMLDivElement>(null); const visibleSectionRef = useRef<HTMLDivElement>(null);
@ -35,6 +37,8 @@ export function SummaryTimeline({
const [initialReviewTimelineScrollTop, setInitialReviewTimelineScrollTop] = const [initialReviewTimelineScrollTop, setInitialReviewTimelineScrollTop] =
useState<number>(0); useState<number>(0);
const observer = useRef<ResizeObserver | null>(null);
const { alignStartDateToTimeline } = useTimelineUtils(segmentDuration); const { alignStartDateToTimeline } = useTimelineUtils(segmentDuration);
const timelineStartAligned = useMemo( const timelineStartAligned = useMemo(
@ -62,6 +66,7 @@ export function SummaryTimeline({
segmentDuration={segmentDuration} segmentDuration={segmentDuration}
segmentTime={segmentTime} segmentTime={segmentTime}
segmentHeight={segmentHeight} segmentHeight={segmentHeight}
severityType={severityType}
/> />
); );
}); });
@ -72,6 +77,7 @@ export function SummaryTimeline({
events, events,
reviewTimelineDuration, reviewTimelineDuration,
segmentHeight, segmentHeight,
severityType,
]); ]);
const segments = useMemo( const segments = useMemo(
@ -86,34 +92,73 @@ export function SummaryTimeline({
reviewTimelineDuration, reviewTimelineDuration,
segmentHeight, segmentHeight,
generateSegments, generateSegments,
severityType,
], ],
); );
const setVisibleSectionStyles = useCallback(() => {
if (
reviewTimelineRef.current &&
summaryTimelineRef.current &&
visibleSectionRef.current
) {
const content = reviewTimelineRef.current;
const summary = summaryTimelineRef.current;
const {
clientHeight: reviewTimelineVisibleHeight,
scrollHeight: reviewTimelineFullHeight,
scrollTop: scrolled,
} = content;
const { clientHeight: summaryTimelineVisibleHeight } = summary;
visibleSectionRef.current.style.top = `${
summaryTimelineVisibleHeight * (scrolled / reviewTimelineFullHeight)
}px`;
visibleSectionRef.current.style.height = `${
reviewTimelineVisibleHeight *
(reviewTimelineVisibleHeight / reviewTimelineFullHeight)
}px`;
}
}, [reviewTimelineRef, summaryTimelineRef, visibleSectionRef]);
useEffect(() => { useEffect(() => {
if (reviewTimelineRef.current && summaryTimelineRef.current) { if (reviewTimelineRef.current && summaryTimelineRef.current) {
const content = reviewTimelineRef.current; const content = reviewTimelineRef.current;
const summary = summaryTimelineRef.current;
const handleScroll = () => { const handleScroll = () => {
const { setVisibleSectionStyles();
clientHeight: reviewTimelineVisibleHeight,
scrollHeight: reviewTimelineFullHeight,
scrollTop: scrolled,
} = content;
const { clientHeight: summaryTimelineVisibleHeight } = summary;
if (visibleSectionRef.current) {
visibleSectionRef.current.style.top = `${summaryTimelineVisibleHeight * (scrolled / reviewTimelineFullHeight)}px`;
visibleSectionRef.current.style.height = `${reviewTimelineVisibleHeight * (reviewTimelineVisibleHeight / reviewTimelineFullHeight)}px`;
}
}; };
// Set initial styles
setVisibleSectionStyles();
observer.current = new ResizeObserver(() => {
setVisibleSectionStyles();
if (summaryTimelineRef.current) {
const { clientHeight: summaryTimelineVisibleHeight } =
summaryTimelineRef.current;
setSegmentHeight(
summaryTimelineVisibleHeight /
(reviewTimelineDuration / segmentDuration),
);
}
});
observer.current.observe(content);
content.addEventListener("scroll", handleScroll); content.addEventListener("scroll", handleScroll);
return () => { return () => {
content.removeEventListener("scroll", handleScroll); content.removeEventListener("scroll", handleScroll);
}; };
} }
}, [reviewTimelineRef, summaryTimelineRef]); }, [
reviewTimelineRef,
summaryTimelineRef,
setVisibleSectionStyles,
reviewTimelineDuration,
segmentDuration,
]);
useEffect(() => { useEffect(() => {
if (summaryTimelineRef.current) { if (summaryTimelineRef.current) {

View File

@ -63,14 +63,12 @@ function useDraggableElement({
}, [clientYPosition, timelineRef, isDragging]); }, [clientYPosition, timelineRef, isDragging]);
const getClientYPosition = useCallback( const getClientYPosition = useCallback(
( (e: MouseEvent | TouchEvent) => {
e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>,
) => {
let clientY; let clientY;
if (isMobile && e.nativeEvent instanceof TouchEvent) { if (isMobile && e instanceof TouchEvent) {
clientY = e.nativeEvent.touches[0].clientY; clientY = e.touches[0].clientY;
} else if (e.nativeEvent instanceof MouseEvent) { } else if (e instanceof MouseEvent) {
clientY = e.nativeEvent.clientY; clientY = e.clientY;
} }
if (clientY) { if (clientY) {
@ -113,9 +111,7 @@ function useDraggableElement({
); );
const handleMouseUp = useCallback( const handleMouseUp = useCallback(
( (e: MouseEvent | TouchEvent) => {
e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>,
) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (isDragging) { if (isDragging) {
@ -187,9 +183,7 @@ function useDraggableElement({
); );
const handleMouseMove = useCallback( const handleMouseMove = useCallback(
( (e: MouseEvent | TouchEvent) => {
e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>,
) => {
if ( if (
!contentRef.current || !contentRef.current ||
!timelineRef.current || !timelineRef.current ||

View File

@ -405,18 +405,19 @@ function UIPlayground() {
events={mockEvents} // events, including new has_been_reviewed and severity properties events={mockEvents} // events, including new has_been_reviewed and severity properties
severityType={"alert"} // choose the severity type for the middle line - all other severity types are to the right severityType={"alert"} // choose the severity type for the middle line - all other severity types are to the right
contentRef={contentRef} // optional content ref where previews are, can be used for observing/scrolling later contentRef={contentRef} // optional content ref where previews are, can be used for observing/scrolling later
timelineRef={reviewTimelineRef} timelineRef={reviewTimelineRef} // save a ref to this timeline to connect with the summary timeline
/> />
)} )}
</div> </div>
{isEventsReviewTimeline && ( {isEventsReviewTimeline && (
<div className="w-[10px]"> <div className="w-[10px]">
<SummaryTimeline <SummaryTimeline
reviewTimelineRef={reviewTimelineRef} reviewTimelineRef={reviewTimelineRef} // the ref to the review timeline
timelineStart={Math.floor(Date.now() / 1000)} // timestamp start of the timeline - the earlier time timelineStart={Math.floor(Date.now() / 1000)} // timestamp start of the timeline - the earlier time
timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time
segmentDuration={zoomSettings.segmentDuration} segmentDuration={zoomSettings.segmentDuration}
events={mockEvents} events={mockEvents}
severityType={"alert"} // show only events of this severity on the summary timeline
/> />
</div> </div>
)} )}

View File

@ -555,6 +555,7 @@ function DetectionReview({
timelineEnd={timeRange.after} timelineEnd={timeRange.after}
segmentDuration={segmentDuration} segmentDuration={segmentDuration}
events={reviewItems?.all ?? []} events={reviewItems?.all ?? []}
severityType={severity}
/> />
</div> </div>
</div> </div>