Add attributes to UI filters list (#23250)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

* preserve user-set min_score on attribute filters instead of bumping any 0.5 value

use model_fields_set to distinguish "user explicitly set min_score" from "Pydantic applied the generic FilterConfig default of 0.5"

* add config test for attributes

* fix attributes frontend type

* add expanded hidden field context

* extend schema modification

* special case for attributes

* i18n for attributes

* handle dedicated lpr mode

* strip unrendered FilterConfig fields from attribute filter form data to fix validation errors
This commit is contained in:
Josh Hawkins
2026-05-19 08:31:50 -06:00
committed by GitHub
parent 4fdc107987
commit b1de5e2290
16 changed files with 535 additions and 43 deletions
@@ -308,11 +308,30 @@ export function ConfigSection({
// Get section schema using cached hook
const sectionSchema = useSectionSchema(sectionPath, effectiveLevel);
// Apply special case handling for sections with problematic schema defaults
// Apply special case handling for sections with problematic schema defaults.
// The HiddenFieldContext is built from `config` (saved state) only — not the
// in-flight raw section value — because the schema is computed before
// rawFormData is derived. The objects-branch fallback in
// modifySchemaForSection reads `track` from fullCameraConfig / fullConfig.
const modifiedSchema = useMemo(
() =>
modifySchemaForSection(sectionPath, level, sectionSchema ?? undefined),
[sectionPath, level, sectionSchema],
modifySchemaForSection(
sectionPath,
level,
sectionSchema ?? undefined,
config
? {
fullConfig: config,
fullCameraConfig:
effectiveLevel === "camera" && cameraName
? config.cameras?.[cameraName]
: undefined,
level,
cameraName,
}
: undefined,
),
[sectionPath, level, sectionSchema, config, effectiveLevel, cameraName],
);
// Get override status (camera vs global)
@@ -384,7 +403,19 @@ export function ConfigSection({
// When editing a profile, hide fields that require a restart since they
// cannot take effect via profile switching alone.
const effectiveHiddenFields = useMemo(() => {
const base = resolveHiddenFieldEntries(sectionConfig.hiddenFields, config);
const ctx = config
? {
fullConfig: config,
fullCameraConfig:
effectiveLevel === "camera" && cameraName
? config.cameras?.[cameraName]
: undefined,
level,
cameraName,
formData: rawFormData,
}
: undefined;
const base = resolveHiddenFieldEntries(sectionConfig.hiddenFields, ctx);
if (!profileName || !sectionConfig.restartRequired?.length) {
return base;
}
@@ -394,6 +425,10 @@ export function ConfigSection({
sectionConfig.hiddenFields,
sectionConfig.restartRequired,
config,
effectiveLevel,
cameraName,
level,
rawFormData,
]);
const sanitizeSectionData = useCallback(