mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-14 16:01:13 +03:00
respect section hiddenFields when detecting config overrides
This commit is contained in:
parent
d0f44de6bc
commit
9c44a2f662
@ -1,6 +1,7 @@
|
|||||||
// Hook to detect when camera config overrides global defaults
|
// Hook to detect when camera config overrides global defaults
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import set from "lodash/set";
|
import set from "lodash/set";
|
||||||
@ -8,7 +9,11 @@ import type { RJSFSchema } from "@rjsf/utils";
|
|||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { JsonObject, JsonValue } from "@/types/configForm";
|
import { JsonObject, JsonValue } from "@/types/configForm";
|
||||||
import { isJsonObject } from "@/lib/utils";
|
import { isJsonObject } from "@/lib/utils";
|
||||||
import { getBaseCameraSectionValue } from "@/utils/configUtil";
|
import {
|
||||||
|
getBaseCameraSectionValue,
|
||||||
|
getEffectiveHiddenFields,
|
||||||
|
unsetWithWildcard,
|
||||||
|
} from "@/utils/configUtil";
|
||||||
import { extractSectionSchema } from "@/hooks/use-config-schema";
|
import { extractSectionSchema } from "@/hooks/use-config-schema";
|
||||||
import { applySchemaDefaults } from "@/lib/config-schema";
|
import { applySchemaDefaults } from "@/lib/config-schema";
|
||||||
|
|
||||||
@ -38,6 +43,21 @@ export function normalizeConfigValue(value: unknown): JsonValue {
|
|||||||
return stripInternalFields(value as JsonValue);
|
return stripInternalFields(value as JsonValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove hidden-field paths from a value before comparison so fields the
|
||||||
|
* user can't change in the UI (e.g. motion masks, attribute filters) don't
|
||||||
|
* trigger override badges. Operates on a clone so the input is unchanged.
|
||||||
|
*/
|
||||||
|
function stripHiddenPaths(value: JsonValue, hiddenFields: string[]): JsonValue {
|
||||||
|
if (hiddenFields.length === 0 || !isJsonObject(value)) return value;
|
||||||
|
const cloned = cloneDeep(value) as JsonObject;
|
||||||
|
for (const path of hiddenFields) {
|
||||||
|
if (!path) continue;
|
||||||
|
unsetWithWildcard(cloned as Record<string, unknown>, path);
|
||||||
|
}
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collapse null and empty-object values for override comparisons so
|
* Collapse null and empty-object values for override comparisons so
|
||||||
* semantically equivalent shapes match. The schema may default `mask: None`
|
* semantically equivalent shapes match. The schema may default `mask: None`
|
||||||
@ -45,7 +65,7 @@ export function normalizeConfigValue(value: unknown): JsonValue {
|
|||||||
* masks", so collapsing them here keeps the equality check honest. We
|
* masks", so collapsing them here keeps the equality check honest. We
|
||||||
* keep this off the public `normalizeConfigValue` so save-flow code paths
|
* keep this off the public `normalizeConfigValue` so save-flow code paths
|
||||||
* (which serialize form data) aren't affected.
|
* (which serialize form data) aren't affected.
|
||||||
*/
|
**/
|
||||||
function collapseEmpty(value: JsonValue): JsonValue {
|
function collapseEmpty(value: JsonValue): JsonValue {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value.map(collapseEmpty);
|
return value.map(collapseEmpty);
|
||||||
@ -202,8 +222,21 @@ export function useConfigOverride({
|
|||||||
|
|
||||||
// Collapse empty/null values for comparison so semantically equivalent
|
// Collapse empty/null values for comparison so semantically equivalent
|
||||||
// shapes (e.g. schema default `mask: null` vs runtime `mask: {}`) match.
|
// shapes (e.g. schema default `mask: null` vs runtime `mask: {}`) match.
|
||||||
const collapsedGlobal = collapseEmpty(normalizedGlobalValue);
|
// Also strip hidden-field paths (motion masks, attribute filters, etc.)
|
||||||
const collapsedCamera = collapseEmpty(normalizedCameraValue);
|
// so fields the user can't edit in the UI don't trigger override badges.
|
||||||
|
const hiddenFields = getEffectiveHiddenFields(
|
||||||
|
sectionPath,
|
||||||
|
"camera",
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
const collapsedGlobal = stripHiddenPaths(
|
||||||
|
collapseEmpty(normalizedGlobalValue),
|
||||||
|
hiddenFields,
|
||||||
|
);
|
||||||
|
const collapsedCamera = stripHiddenPaths(
|
||||||
|
collapseEmpty(normalizedCameraValue),
|
||||||
|
hiddenFields,
|
||||||
|
);
|
||||||
|
|
||||||
const comparisonGlobal = compareFields
|
const comparisonGlobal = compareFields
|
||||||
? pickFields(collapsedGlobal, compareFields)
|
? pickFields(collapsedGlobal, compareFields)
|
||||||
@ -328,8 +361,15 @@ export function useAllCameraOverrides(
|
|||||||
getBaseCameraSectionValue(config, cameraName, key),
|
getBaseCameraSectionValue(config, cameraName, key),
|
||||||
);
|
);
|
||||||
|
|
||||||
const collapsedGlobal = collapseEmpty(globalValue);
|
const hiddenFields = getEffectiveHiddenFields(key, "camera", config);
|
||||||
const collapsedCamera = collapseEmpty(cameraValue);
|
const collapsedGlobal = stripHiddenPaths(
|
||||||
|
collapseEmpty(globalValue),
|
||||||
|
hiddenFields,
|
||||||
|
);
|
||||||
|
const collapsedCamera = stripHiddenPaths(
|
||||||
|
collapseEmpty(cameraValue),
|
||||||
|
hiddenFields,
|
||||||
|
);
|
||||||
const comparisonGlobal = compareFields
|
const comparisonGlobal = compareFields
|
||||||
? pickFields(collapsedGlobal, compareFields)
|
? pickFields(collapsedGlobal, compareFields)
|
||||||
: collapsedGlobal;
|
: collapsedGlobal;
|
||||||
|
|||||||
@ -254,7 +254,10 @@ export function flattenOverrides(
|
|||||||
|
|
||||||
// lodash `unset` treats `*` as a literal key. This helper expands wildcard
|
// lodash `unset` treats `*` as a literal key. This helper expands wildcard
|
||||||
// segments so that e.g. `"filters.*.mask"` unsets `filters.<each key>.mask`.
|
// segments so that e.g. `"filters.*.mask"` unsets `filters.<each key>.mask`.
|
||||||
function unsetWithWildcard(obj: Record<string, unknown>, path: string): void {
|
export function unsetWithWildcard(
|
||||||
|
obj: Record<string, unknown>,
|
||||||
|
path: string,
|
||||||
|
): void {
|
||||||
if (!path.includes("*")) {
|
if (!path.includes("*")) {
|
||||||
unset(obj, path);
|
unset(obj, path);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user