Multi-export UI fixes (#23959)
CI / AMD64 Build (push) Canceled after 0s
CI / ARM Build (push) Canceled after 0s
CI / Jetson Jetpack 6 (push) Canceled after 0s
CI / AMD64 Extra Build (push) Canceled after 0s
CI / ARM Extra Build (push) Canceled after 0s
CI / Synaptics Build (push) Canceled after 0s
CI / Assemble and push default build (push) Canceled after 0s

* multi export fixes

* i18n

* new tests
This commit is contained in:
Josh Hawkins
2026-08-11 10:11:47 -06:00
committed by GitHub
parent 0735a8ac75
commit c75611b4df
9 changed files with 320 additions and 93 deletions
@@ -3,7 +3,6 @@ import { isDesktop } from "react-device-detect";
import axios from "axios";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import useSWR from "swr";
import {
@@ -43,6 +42,7 @@ import {
ExportCase,
} from "@/types/export";
import { FrigateConfig } from "@/types/frigateConfig";
import { baseUrl } from "@/api/baseUrl";
import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
import { resolveCameraName } from "@/hooks/use-camera-friendly-name";
import { useDateLocale } from "@/hooks/use-date-locale";
@@ -65,7 +65,6 @@ export default function MultiExportDialog({
}: MultiExportDialogProps) {
const { t } = useTranslation(["components/dialog", "common"]);
const locale = useDateLocale();
const navigate = useNavigate();
const isAdmin = useIsAdmin();
const { data: config } = useSWR<FrigateConfig>("config");
@@ -203,19 +202,24 @@ export default function MultiExportDialog({
const results = response.data.results ?? [];
const successful = results.filter((r) => r.success);
const failed = results.filter((r) => !r.success);
const exportCaseId = response.data.export_case_id;
const viewCaseAction = exportCaseId ? (
<a
href={`${baseUrl}export?caseId=${exportCaseId}`}
target="_blank"
rel="noopener noreferrer"
>
<Button>{t("export.toast.view", { ns: "components/dialog" })}</Button>
</a>
) : undefined;
if (successful.length > 0 && failed.length === 0) {
toast.success(
t(
isAdmin
? "export.multi.toast.started"
: "export.multi.toast.startedNoCase",
{
ns: "components/dialog",
count: successful.length,
},
),
{ position: "top-center" },
t("export.multi.toast.started", {
ns: "components/dialog",
count: successful.length,
}),
{ position: "top-center", action: viewCaseAction },
);
} else if (successful.length > 0 && failed.length > 0) {
// Resolve each failure to its review via item_index so same-camera
@@ -229,7 +233,7 @@ export default function MultiExportDialog({
total: results.length,
failedItems: failedLabels,
}),
{ position: "top-center" },
{ position: "top-center", action: viewCaseAction },
);
} else {
const failedLabels = failed.map(formatFailureLabel).join(", ");
@@ -247,9 +251,6 @@ export default function MultiExportDialog({
onStarted();
setOpen(false);
resetState();
if (response.data.export_case_id) {
navigate(`/export?caseId=${response.data.export_case_id}`);
}
}
} catch (error) {
const apiError = error as {
@@ -275,7 +276,6 @@ export default function MultiExportDialog({
formatFailureLabel,
isAdmin,
isNewCase,
navigate,
newCaseDescription,
newCaseName,
onStarted,