UI improvements (#19659)

* Add indicator when GenAI review infers suspicious activity

* Fix score filtering logic

* Enable mobile view for classification and optimize for mobile layout

* Add missing keys

* Don't require face rec

* fix key
This commit is contained in:
Nicolas Mowen
2025-08-20 08:28:47 -05:00
committed by GitHub
parent 9fb09408d1
commit 361014f01c
8 changed files with 100 additions and 15 deletions
@@ -65,6 +65,7 @@ import { useTranslation } from "react-i18next";
import { supportedLanguageKeys } from "@/lib/const";
import { useDocDomain } from "@/hooks/use-doc-domain";
import { MdCategory } from "react-icons/md";
type GeneralSettingsProps = {
className?: string;
@@ -315,6 +316,19 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
</Link>
</>
)}
{isAdmin && isMobile && (
<>
<Link to="/classification">
<MenuItem
className="flex w-full items-center p-2 text-sm"
aria-label={t("menu.classification")}
>
<MdCategory className="mr-2 size-4" />
<span>{t("menu.classification")}</span>
</MenuItem>
</Link>
</>
)}
</DropdownMenuGroup>
<DropdownMenuLabel className={isDesktop ? "mt-3" : "mt-1"}>
{t("menu.appearance")}
@@ -86,10 +86,10 @@ export default function ReviewDetailDialog({
let concerns = "";
switch (aiAnalysis.potential_threat_level) {
case ThreatLevel.SUSPICIOUS:
concerns = "• Suspicious Activity\n";
concerns = `${t("suspiciousActivity", { ns: "views/events" })}\n`;
break;
case ThreatLevel.DANGER:
concerns = "• Danger\n";
concerns = `${t("threateningActivity", { ns: "views/events" })}\n`;
break;
}
@@ -98,7 +98,7 @@ export default function ReviewDetailDialog({
});
return concerns || "None";
}, [aiAnalysis]);
}, [aiAnalysis, t]);
const hasMismatch = useMemo(() => {
if (!review || !events) {
@@ -270,12 +270,18 @@ export default function ReviewDetailDialog({
isDesktop && "m-2 w-[90%]",
)}
>
AI Analysis
<div className="text-sm text-primary/40">Description</div>
{t("aiAnalysis.title")}
<div className="text-sm text-primary/40">
{t("details.description.label")}
</div>
<div className="text-sm">{aiAnalysis.scene}</div>
<div className="text-sm text-primary/40">Score</div>
<div className="text-sm text-primary/40">
{t("details.score.label")}
</div>
<div className="text-sm">{aiAnalysis.confidence * 100}%</div>
<div className="text-sm text-primary/40">Concerns</div>
<div className="text-sm text-primary/40">
{t("concerns.label")}
</div>
<div className="text-sm">{aiThreatLevel}</div>
</div>
)}
@@ -60,7 +60,7 @@ export default function TrainFilterDialog({
moreFiltersSelected ? "text-white" : "text-secondary-foreground",
)}
/>
{t("more")}
{isDesktop && t("more")}
</Button>
);
const content = (
@@ -22,6 +22,8 @@ import { InProgressPreview, VideoPreview } from "../preview/ScrubbablePreview";
import { Preview } from "@/types/preview";
import { baseUrl } from "@/api/baseUrl";
import { useTranslation } from "react-i18next";
import { FaExclamationTriangle } from "react-icons/fa";
import { MdOutlinePersonSearch } from "react-icons/md";
type PreviewPlayerProps = {
review: ReviewSegment;
@@ -234,7 +236,12 @@ export default function PreviewThumbnailPlayer({
)}
/>
)}
<div className={cn("absolute left-0 top-2", !isSafari && "z-40")}>
<div
className={cn(
"absolute left-0 top-2 flex gap-2",
!isSafari && "z-40",
)}
>
<Tooltip>
<div
className="flex"
@@ -242,7 +249,7 @@ export default function PreviewThumbnailPlayer({
onMouseLeave={() => setTooltipHovering(false)}
>
<TooltipTrigger asChild>
<div className="mx-3 pb-1 text-sm text-white">
<div className="ml-3 pb-1 text-sm text-white">
{(review.severity == "alert" ||
review.severity == "detection") && (
<>
@@ -279,6 +286,45 @@ export default function PreviewThumbnailPlayer({
.replaceAll("-verified", "")}
</TooltipContent>
</Tooltip>
{!!(
review.data.metadata?.potential_threat_level &&
!review.has_been_reviewed
) && (
<Tooltip>
<div
className="flex"
onMouseEnter={() => setTooltipHovering(true)}
onMouseLeave={() => setTooltipHovering(false)}
>
<TooltipTrigger asChild>
<div className="pb-1 text-sm text-white">
{(review.severity == "alert" ||
review.severity == "detection") && (
<>
<Chip
className={`flex items-start justify-between space-x-1 ${playingBack ? "hidden" : ""} z-0 bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500`}
onClick={() => onClick(review, false, true)}
>
{review.data.metadata.potential_threat_level == 1 ? (
<MdOutlinePersonSearch className="size-3" />
) : (
<FaExclamationTriangle className="size-3" />
)}
</Chip>
</>
)}
</div>
</TooltipTrigger>
</div>
<TooltipContent className="smart-capitalize">
{review.data.metadata.potential_threat_level == 1 ? (
<>{t("suspiciousActivity", { ns: "views/events" })}</>
) : (
<>{t("threateningActivity", { ns: "views/events" })}</>
)}
</TooltipContent>
</Tooltip>
)}
</div>
{!playingBack && (
<div