fix fast refresh

This commit is contained in:
Josh Hawkins 2026-02-01 12:44:54 -06:00
parent 3e708255a7
commit 718757fc60
4 changed files with 66 additions and 67 deletions

View File

@ -1,5 +1,5 @@
import { useMemo } from "react";
import { createConfigSection } from "./BaseSection";
import { ConfigSection } from "./BaseSection";
import type { BaseSectionProps, SectionConfig } from "./BaseSection";
import { getSectionConfig } from "@/utils/sectionConfigsUtils";
@ -19,17 +19,10 @@ export function ConfigSectionTemplate({
[sectionKey, level],
);
const SectionComponent = useMemo(
() =>
createConfigSection({
sectionPath: sectionKey,
defaultConfig,
}),
[sectionKey, defaultConfig],
);
return (
<SectionComponent
<ConfigSection
sectionPath={sectionKey}
defaultConfig={defaultConfig}
level={level}
sectionConfig={sectionConfig ?? defaultConfig}
{...rest}

View File

@ -2,10 +2,11 @@
// Reusable components for both global and camera-level settings
export {
createConfigSection,
ConfigSection,
type BaseSectionProps,
type SectionConfig,
type CreateSectionOptions,
type ConfigSectionProps,
} from "./BaseSection";
export {
ConfigSectionTemplate,

View File

@ -39,7 +39,10 @@ import FrigatePlusSettingsView from "@/views/settings/FrigatePlusSettingsView";
import MaintenanceSettingsView from "@/views/settings/MaintenanceSettingsView";
import GlobalConfigView from "@/views/settings/GlobalConfigView";
import CameraConfigView from "@/views/settings/CameraConfigView";
import { createSingleSectionPage } from "@/views/settings/SingleSectionPage";
import {
SingleSectionPage,
type SettingsPageProps,
} from "@/views/settings/SingleSectionPage";
import { useSearchEffect } from "@/hooks/use-overlay-state";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useInitialCameraState } from "@/api/ws";
@ -93,16 +96,18 @@ const allSettingsViews = [
] as const;
type SettingsType = (typeof allSettingsViews)[number];
const MqttSettingsPage = createSingleSectionPage({
sectionKey: "mqtt",
level: "global",
});
const MqttSettingsPage = (props: SettingsPageProps) => (
<SingleSectionPage sectionKey="mqtt" level="global" {...props} />
);
const CameraMqttSettingsPage = createSingleSectionPage({
sectionKey: "mqtt",
level: "camera",
showOverrideIndicator: false,
});
const CameraMqttSettingsPage = (props: SettingsPageProps) => (
<SingleSectionPage
sectionKey="mqtt"
level="camera"
showOverrideIndicator={false}
{...props}
/>
);
const settingsGroups = [
{

View File

@ -18,58 +18,58 @@ export type SingleSectionPageOptions = {
showOverrideIndicator?: boolean;
};
export function createSingleSectionPage({
export type SingleSectionPageProps = SettingsPageProps &
SingleSectionPageOptions;
export function SingleSectionPage({
sectionKey,
level,
sectionConfig,
requiresRestart,
showOverrideIndicator = true,
}: SingleSectionPageOptions) {
return function SingleSectionPage({
selectedCamera,
setUnsavedChanges,
}: SettingsPageProps) {
const sectionNamespace =
level === "camera" ? "config/cameras" : "config/global";
const { t, i18n } = useTranslation([
sectionNamespace,
"views/settings",
"common",
]);
if (level === "camera" && !selectedCamera) {
return (
<div className="flex h-full items-center justify-center text-muted-foreground">
{t("configForm.camera.noCameras", { ns: "views/settings" })}
</div>
);
}
selectedCamera,
setUnsavedChanges,
}: SingleSectionPageProps) {
const sectionNamespace =
level === "camera" ? "config/cameras" : "config/global";
const { t, i18n } = useTranslation([
sectionNamespace,
"views/settings",
"common",
]);
if (level === "camera" && !selectedCamera) {
return (
<div className="flex size-full flex-col pr-2">
<div className="mb-4">
<Heading as="h3">
{t(`${sectionKey}.label`, { ns: sectionNamespace })}
</Heading>
{i18n.exists(`${sectionKey}.description`, {
ns: sectionNamespace,
}) && (
<p className="text-sm text-muted-foreground">
{t(`${sectionKey}.description`, { ns: sectionNamespace })}
</p>
)}
</div>
<ConfigSectionTemplate
sectionKey={sectionKey}
level={level}
cameraName={level === "camera" ? selectedCamera : undefined}
showOverrideIndicator={showOverrideIndicator}
onSave={() => setUnsavedChanges?.(false)}
showTitle={false}
sectionConfig={sectionConfig}
requiresRestart={requiresRestart}
/>
<div className="flex h-full items-center justify-center text-muted-foreground">
{t("configForm.camera.noCameras", { ns: "views/settings" })}
</div>
);
};
}
return (
<div className="flex size-full flex-col pr-2">
<div className="mb-4">
<Heading as="h3">
{t(`${sectionKey}.label`, { ns: sectionNamespace })}
</Heading>
{i18n.exists(`${sectionKey}.description`, {
ns: sectionNamespace,
}) && (
<p className="text-sm text-muted-foreground">
{t(`${sectionKey}.description`, { ns: sectionNamespace })}
</p>
)}
</div>
<ConfigSectionTemplate
sectionKey={sectionKey}
level={level}
cameraName={level === "camera" ? selectedCamera : undefined}
showOverrideIndicator={showOverrideIndicator}
onSave={() => setUnsavedChanges?.(false)}
showTitle={false}
sectionConfig={sectionConfig}
requiresRestart={requiresRestart}
/>
</div>
);
}