mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 15:05:26 +03:00
reusable tabs component
This commit is contained in:
parent
5f4de57bc3
commit
348d40d7fd
@ -119,12 +119,6 @@ export default function SearchDetailDialog({
|
||||
100,
|
||||
);
|
||||
|
||||
// tracking details state
|
||||
|
||||
const [trackingTimeIndex, setTrackingTimeIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined);
|
||||
|
||||
// dialog and mobile page
|
||||
|
||||
const [isOpen, setIsOpen] = useState(search != undefined);
|
||||
@ -184,6 +178,42 @@ export default function SearchDetailDialog({
|
||||
}
|
||||
}, [pageToggle, searchTabs, setSearchPage]);
|
||||
|
||||
// Tabs component for reuse
|
||||
const tabsComponent = (
|
||||
<ScrollArea className="w-full whitespace-nowrap">
|
||||
<div className="flex flex-row">
|
||||
<ToggleGroup
|
||||
className="*:rounded-md *:px-3 *:py-4"
|
||||
type="single"
|
||||
size="sm"
|
||||
value={pageToggle}
|
||||
onValueChange={(value: SearchTab) => {
|
||||
if (value) {
|
||||
setPageToggle(value);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{Object.values(searchTabs).map((item) => (
|
||||
<ToggleGroupItem
|
||||
key={item}
|
||||
className={`flex scroll-mx-10 items-center justify-between gap-2 ${page == "details" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
|
||||
value={item}
|
||||
data-nav-item={item}
|
||||
aria-label={`Select ${item}`}
|
||||
>
|
||||
{item == "details" && <FaRegListAlt className="size-4" />}
|
||||
{item == "snapshot" && <FaImage className="size-4" />}
|
||||
{item == "video" && <FaVideo className="size-4" />}
|
||||
{item == "tracking_details" && <PiPath className="size-4" />}
|
||||
<div className="smart-capitalize">{t(`type.${item}`)}</div>
|
||||
</ToggleGroupItem>
|
||||
))}
|
||||
</ToggleGroup>
|
||||
<ScrollBar orientation="horizontal" className="h-0" />
|
||||
</div>
|
||||
</ScrollArea>
|
||||
);
|
||||
|
||||
if (!search) {
|
||||
return;
|
||||
}
|
||||
@ -220,8 +250,15 @@ export default function SearchDetailDialog({
|
||||
</Description>
|
||||
</Header>
|
||||
{isDesktop ? (
|
||||
page === "tracking_details" ? (
|
||||
<TrackingDetails
|
||||
className="size-full"
|
||||
event={search as unknown as Event}
|
||||
tabs={tabsComponent}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full gap-4 overflow-hidden">
|
||||
<div className="scrollbar-container flex-[3] overflow-y-auto">
|
||||
<div className="scrollbar-container flex-[3] overflow-y-hidden">
|
||||
{page === "snapshot" && search.has_snapshot && (
|
||||
<ObjectSnapshotTab
|
||||
search={
|
||||
@ -240,15 +277,6 @@ export default function SearchDetailDialog({
|
||||
{page === "video" && search.has_clip && (
|
||||
<VideoTab search={search} />
|
||||
)}
|
||||
{page === "tracking_details" && (
|
||||
<TrackingDetails
|
||||
event={search as unknown as Event}
|
||||
showImage={true}
|
||||
showLifecycle={false}
|
||||
timeIndex={trackingTimeIndex}
|
||||
setTimeIndex={setTrackingTimeIndex}
|
||||
/>
|
||||
)}
|
||||
{(page === "details" ||
|
||||
(!search.has_snapshot && page === "snapshot") ||
|
||||
(!search.has_clip && page === "video")) && (
|
||||
@ -268,44 +296,7 @@ export default function SearchDetailDialog({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-[2] flex-col gap-4 overflow-hidden">
|
||||
<ScrollArea className="w-full whitespace-nowrap">
|
||||
<div className="flex flex-row">
|
||||
<ToggleGroup
|
||||
className="*:rounded-md *:px-3 *:py-4"
|
||||
type="single"
|
||||
size="sm"
|
||||
value={pageToggle}
|
||||
onValueChange={(value: SearchTab) => {
|
||||
if (value) {
|
||||
setPageToggle(value);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{Object.values(searchTabs).map((item) => (
|
||||
<ToggleGroupItem
|
||||
key={item}
|
||||
className={`flex scroll-mx-10 items-center justify-between gap-2 ${page == "details" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
|
||||
value={item}
|
||||
data-nav-item={item}
|
||||
aria-label={`Select ${item}`}
|
||||
>
|
||||
{item == "details" && (
|
||||
<FaRegListAlt className="size-4" />
|
||||
)}
|
||||
{item == "snapshot" && <FaImage className="size-4" />}
|
||||
{item == "video" && <FaVideo className="size-4" />}
|
||||
{item == "tracking_details" && (
|
||||
<PiPath className="size-4" />
|
||||
)}
|
||||
<div className="smart-capitalize">
|
||||
{t(`type.${item}`)}
|
||||
</div>
|
||||
</ToggleGroupItem>
|
||||
))}
|
||||
</ToggleGroup>
|
||||
<ScrollBar orientation="horizontal" className="h-0" />
|
||||
</div>
|
||||
</ScrollArea>
|
||||
{tabsComponent}
|
||||
<div className="scrollbar-container flex-1 overflow-y-auto">
|
||||
{page == "details" && (
|
||||
<ObjectDetailsTab
|
||||
@ -337,19 +328,10 @@ export default function SearchDetailDialog({
|
||||
showThumbnail={false}
|
||||
/>
|
||||
)}
|
||||
{page == "tracking_details" && (
|
||||
<TrackingDetails
|
||||
className="w-full overflow-x-hidden"
|
||||
event={search as unknown as Event}
|
||||
showImage={false}
|
||||
showLifecycle={true}
|
||||
timeIndex={trackingTimeIndex}
|
||||
setTimeIndex={setTrackingTimeIndex}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
<ScrollArea
|
||||
@ -419,10 +401,6 @@ export default function SearchDetailDialog({
|
||||
<TrackingDetails
|
||||
className="w-full overflow-x-hidden"
|
||||
event={search as unknown as Event}
|
||||
showImage={true}
|
||||
showLifecycle={true}
|
||||
timeIndex={trackingTimeIndex}
|
||||
setTimeIndex={setTrackingTimeIndex}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user