import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import type { SectionConfig } from "@/components/config-form/sections"; import { ConfigSectionTemplate } from "@/components/config-form/sections"; import type { PolygonType } from "@/types/canvas"; import { Badge } from "@/components/ui/badge"; import type { ConfigSectionData } from "@/types/configForm"; import { getSectionConfig } from "@/utils/sectionConfigsUtils"; import { useDocDomain } from "@/hooks/use-doc-domain"; import { Link } from "react-router-dom"; import { LuExternalLink } from "react-icons/lu"; export type SettingsPageProps = { selectedCamera?: string; setUnsavedChanges?: React.Dispatch>; selectedZoneMask?: PolygonType[]; onSectionStatusChange?: ( sectionKey: string, level: "global" | "camera", status: SectionStatus, ) => void; pendingDataBySection?: Record; onPendingDataChange?: ( sectionKey: string, cameraName: string | undefined, data: ConfigSectionData | null, ) => void; }; export type SectionStatus = { hasChanges: boolean; isOverridden: boolean; }; export type SingleSectionPageOptions = { sectionKey: string; level: "global" | "camera"; sectionConfig?: SectionConfig; requiresRestart?: boolean; showOverrideIndicator?: boolean; }; export type SingleSectionPageProps = SettingsPageProps & SingleSectionPageOptions; export function SingleSectionPage({ sectionKey, level, sectionConfig, requiresRestart, showOverrideIndicator = true, selectedCamera, setUnsavedChanges, onSectionStatusChange, pendingDataBySection, onPendingDataChange, }: SingleSectionPageProps) { const sectionNamespace = level === "camera" ? "config/cameras" : "config/global"; const { t, i18n } = useTranslation([ sectionNamespace, "views/settings", "common", ]); const { getLocaleDocUrl } = useDocDomain(); const [sectionStatus, setSectionStatus] = useState({ hasChanges: false, isOverridden: false, }); const resolvedSectionConfig = useMemo( () => sectionConfig ?? getSectionConfig(sectionKey, level), [level, sectionConfig, sectionKey], ); const sectionDocsUrl = resolvedSectionConfig.sectionDocs ? getLocaleDocUrl(resolvedSectionConfig.sectionDocs) : undefined; const handleSectionStatusChange = useCallback( (status: SectionStatus) => { setSectionStatus(status); onSectionStatusChange?.(sectionKey, level, status); }, [level, onSectionStatusChange, sectionKey], ); if (level === "camera" && !selectedCamera) { return (
{t("configForm.camera.noCameras", { ns: "views/settings" })}
); } return (
{t(`${sectionKey}.label`, { ns: sectionNamespace })}
{i18n.exists(`${sectionKey}.description`, { ns: sectionNamespace, }) && (
{t(`${sectionKey}.description`, { ns: sectionNamespace })}
)} {sectionDocsUrl && (
{t("readTheDocumentation", { ns: "common" })}
)}
{level === "camera" && showOverrideIndicator && sectionStatus.isOverridden && ( {t("button.overridden", { ns: "common", defaultValue: "Overridden", })} )} {sectionStatus.hasChanges && ( {t("modified", { ns: "common", defaultValue: "Modified" })} )}
setUnsavedChanges?.(false)} showTitle={false} sectionConfig={resolvedSectionConfig} pendingDataBySection={pendingDataBySection} onPendingDataChange={onPendingDataChange} requiresRestart={requiresRestart} onStatusChange={handleSectionStatusChange} />
); }