auto-prefix keys

This commit is contained in:
shamoon
2025-10-13 12:32:24 -07:00
parent 1d110d7ff9
commit 8ab3da9aef
3 changed files with 25 additions and 14 deletions

View File

@@ -120,7 +120,7 @@ Each widget can optionally provide a list of which fields should be visible via
### Block Highlighting
Widgets can tint their metric blocks automatically based on rules defined alongside the service. Attach a `highlight` section to the widget configuration and map each block (use the translation key from the widget, or the explicit `field` prop if it is present) to one or more numeric or string rules. The first matching rule wins and its level controls the colours.
Widgets can tint their metric blocks automatically based on rules defined alongside the service. Attach a `highlight` section to the widget configuration and map each block to one or more numeric or string rules using the field key (for example, `queued`, `lan_users`).
```yaml
- Sonarr:
@@ -131,7 +131,7 @@ Widgets can tint their metric blocks automatically based on rules defined alongs
url: http://sonarr.host.or.ip
key: ${SONARR_API_KEY}
highlight:
sonarr.queued:
queued:
numeric:
- level: danger
when: gte
@@ -142,7 +142,7 @@ Widgets can tint their metric blocks automatically based on rules defined alongs
- level: good
when: eq
value: 0
sonarr.status:
status:
string:
- level: danger
when: regex

View File

@@ -14,8 +14,8 @@ export default function Container({ error = false, children, service }) {
const { settings } = useContext(SettingsContext);
const highlightConfig = useMemo(
() => buildHighlightConfig(settings?.blockHighlights, service?.widget?.highlight),
[settings?.blockHighlights, service?.widget?.highlight],
() => buildHighlightConfig(settings?.blockHighlights, service?.widget?.highlight, service?.widget?.type),
[settings?.blockHighlights, service?.widget?.highlight, service?.widget?.type],
);
if (error) {

View File

@@ -4,7 +4,23 @@ const DEFAULT_LEVEL_CLASSES = {
danger: "bg-rose-700/45 text-rose-200 dark:bg-rose-950/70 dark:text-rose-400",
};
export const buildHighlightConfig = (globalConfig, widgetConfig) => {
const normalizeFieldKeys = (fields, widgetType) => {
if (!fields || typeof fields !== "object") return {};
return Object.entries(fields).reduce((acc, [key, value]) => {
if (value === null || value === undefined) return acc;
if (typeof key !== "string") return acc;
const trimmedKey = key.trim();
if (trimmedKey === "") return acc;
const targetKey = widgetType ? `${widgetType}.${trimmedKey}` : trimmedKey;
acc[targetKey] = value;
return acc;
}, {});
};
export const buildHighlightConfig = (globalConfig, widgetConfig, widgetType) => {
const levels = {
...DEFAULT_LEVEL_CLASSES,
...(globalConfig?.levels || {}),
@@ -12,19 +28,14 @@ export const buildHighlightConfig = (globalConfig, widgetConfig) => {
};
const { levels: _levels, ...fields } = widgetConfig || {};
Object.keys(fields).forEach((key) => {
if (fields[key] === null || fields[key] === undefined) {
delete fields[key];
}
});
const normalizedFields = normalizeFieldKeys(fields, widgetType);
const hasLevels = Object.values(levels).some(Boolean);
const hasFields = Object.keys(fields).length > 0;
const hasFields = Object.keys(normalizedFields).length > 0;
if (!hasLevels && !hasFields) return null;
return { levels, fields };
return { levels, fields: normalizedFields };
};
const NUMERIC_OPERATORS = {