Miscellaneous fixes (#23009)
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled

* Reduce max frames per second to 1

* Use pydantic but don't fail if some constraints are not met.

* Adjust limits

* Adjust limits

* Cleanup

* add unsaved changes icon/popover to individual settings section

* allow changing camera friendly_name from camera management pane

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
Nicolas Mowen
2026-04-26 17:09:35 -05:00
committed by GitHub
co-authored by Josh Hawkins
parent 0ea8924727
commit 4171efcd79
9 changed files with 267 additions and 87 deletions
@@ -1,3 +1,4 @@
import ActivityIndicator from "@/components/indicators/activity-indicator";
import TextEntry from "@/components/input/TextEntry";
import { Button } from "@/components/ui/button";
import {
@@ -19,7 +20,9 @@ type TextEntryDialogProps = {
setOpen: (open: boolean) => void;
onSave: (text: string) => void;
defaultValue?: string;
placeholder?: string;
allowEmpty?: boolean;
isSaving?: boolean;
regexPattern?: RegExp;
regexErrorMessage?: string;
forbiddenPattern?: RegExp;
@@ -33,7 +36,9 @@ export default function TextEntryDialog({
setOpen,
onSave,
defaultValue = "",
placeholder,
allowEmpty = false,
isSaving = false,
regexPattern,
regexErrorMessage,
forbiddenPattern,
@@ -50,6 +55,7 @@ export default function TextEntryDialog({
</DialogHeader>
<TextEntry
defaultValue={defaultValue}
placeholder={placeholder}
allowEmpty={allowEmpty}
onSave={onSave}
regexPattern={regexPattern}
@@ -58,11 +64,22 @@ export default function TextEntryDialog({
forbiddenErrorMessage={forbiddenErrorMessage}
>
<DialogFooter className={cn("pt-4", isMobile && "gap-2")}>
<Button type="button" onClick={() => setOpen(false)}>
<Button
type="button"
disabled={isSaving}
onClick={() => setOpen(false)}
>
{t("button.cancel")}
</Button>
<Button variant="select" type="submit">
{t("button.save")}
<Button variant="select" type="submit" disabled={isSaving}>
{isSaving ? (
<div className="flex flex-row items-center gap-2">
<ActivityIndicator className="size-4" />
<span>{t("button.saving")}</span>
</div>
) : (
t("button.save")
)}
</Button>
</DialogFooter>
</TextEntry>