add timezone widget

This commit is contained in:
Josh Hawkins 2026-02-11 10:09:49 -06:00
parent 2ae972c068
commit c5fcf6aa1f
4 changed files with 72 additions and 0 deletions

View File

@ -1215,6 +1215,9 @@
"keyPlaceholder": "New key",
"remove": "Remove"
},
"timezone": {
"defaultOption": "Use browser timezone"
},
"ffmpegArgs": {
"preset": "Preset",
"manual": "Manual arguments",

View File

@ -18,6 +18,11 @@ const ui: SectionConfigOverrides = {
"unit_system",
],
advancedFields: [],
uiSchema: {
timezone: {
"ui:widget": "timezoneSelect",
},
},
},
};

View File

@ -23,6 +23,7 @@ import { AudioLabelSwitchesWidget } from "./widgets/AudioLabelSwitchesWidget";
import { ZoneSwitchesWidget } from "./widgets/ZoneSwitchesWidget";
import { ArrayAsTextWidget } from "./widgets/ArrayAsTextWidget";
import { FfmpegArgsWidget } from "./widgets/FfmpegArgsWidget";
import { TimezoneSelectWidget } from "./widgets/TimezoneSelectWidget";
import { FieldTemplate } from "./templates/FieldTemplate";
import { ObjectFieldTemplate } from "./templates/ObjectFieldTemplate";
@ -65,6 +66,7 @@ export const frigateTheme: FrigateTheme = {
objectLabels: ObjectLabelSwitchesWidget,
audioLabels: AudioLabelSwitchesWidget,
zoneNames: ZoneSwitchesWidget,
timezoneSelect: TimezoneSelectWidget,
},
templates: {
FieldTemplate: FieldTemplate as React.ComponentType<FieldTemplateProps>,

View File

@ -0,0 +1,62 @@
import { useMemo } from "react";
import type { WidgetProps } from "@rjsf/utils";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useTranslation } from "react-i18next";
const DEFAULT_TIMEZONE_VALUE = "__browser__";
function getTimezoneList(): string[] {
if (typeof Intl !== "undefined") {
const intl = Intl as typeof Intl & {
supportedValuesOf?: (key: string) => string[];
};
const supported = intl.supportedValuesOf?.("timeZone");
if (supported && supported.length > 0) {
return [...supported].sort();
}
}
const fallback = Intl.DateTimeFormat().resolvedOptions().timeZone;
return fallback ? [fallback] : ["UTC"];
}
export function TimezoneSelectWidget(props: WidgetProps) {
const { id, value, disabled, readonly, onChange, schema } = props;
const { t } = useTranslation(["views/settings", "common"]);
const timezones = useMemo(() => getTimezoneList(), []);
const selectedValue = value ? String(value) : DEFAULT_TIMEZONE_VALUE;
const defaultLabel = t("configForm.timezone.defaultOption", {
ns: "views/settings",
});
return (
<Select
value={selectedValue}
onValueChange={(next) =>
onChange(next === DEFAULT_TIMEZONE_VALUE ? null : next)
}
disabled={disabled || readonly}
>
<SelectTrigger id={id} className="w-full">
<SelectValue placeholder={schema.title || defaultLabel} />
</SelectTrigger>
<SelectContent>
<SelectItem value={DEFAULT_TIMEZONE_VALUE}>{defaultLabel}</SelectItem>
{timezones.map((timezone) => (
<SelectItem key={timezone} value={timezone}>
{timezone}
</SelectItem>
))}
</SelectContent>
</Select>
);
}
export default TimezoneSelectWidget;