mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-06-26 14:08:36 +00:00
fix(web): repair news ticker custom-feeds save for JSON path
The JS dotToNested() helper converts indexed form fields like
feeds.custom_feeds.0.name into a dict {'0': {name:...}} rather than a
proper array. The form-data path already had fix_array_structures() to
convert those dicts back to arrays before schema validation, but the
JSON path (used by all web-UI saves) never ran that fix, so saving any
custom feed produced a schema validation error: "Expected type array,
got object".
Add _fix_json_arrays() immediately after schema loading on the JSON
path, mirroring the existing fix_array_structures() logic.
Also fix custom-feeds.js getValue() to omit the logo key entirely when
no logo is present instead of returning logo:null, which would fail
schema validation (logo expects type object).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4463,6 +4463,42 @@ def save_plugin_config():
|
|||||||
if 'application/json' in content_type:
|
if 'application/json' in content_type:
|
||||||
schema = schema_mgr.load_schema(plugin_id, use_cache=False)
|
schema = schema_mgr.load_schema(plugin_id, use_cache=False)
|
||||||
|
|
||||||
|
# JSON path: fix numeric-keyed dicts that should be arrays.
|
||||||
|
# JS dotToNested() converts feeds.custom_feeds.0.name → {'0': {name:...}}
|
||||||
|
# instead of [{name:...}]. The form-data path has fix_array_structures for this;
|
||||||
|
# mirror that logic here for JSON submissions.
|
||||||
|
if 'application/json' in content_type and schema and 'properties' in schema:
|
||||||
|
def _fix_json_arrays(cfg, props):
|
||||||
|
for k, ps in props.items():
|
||||||
|
if not isinstance(cfg, dict) or k not in cfg:
|
||||||
|
continue
|
||||||
|
pt = ps.get('type')
|
||||||
|
val = cfg[k]
|
||||||
|
if pt == 'array' and isinstance(val, dict):
|
||||||
|
keys = list(val.keys())
|
||||||
|
if keys and all(str(x).isdigit() for x in keys):
|
||||||
|
sorted_keys = sorted(keys, key=lambda x: int(str(x)))
|
||||||
|
items_schema = ps.get('items', {})
|
||||||
|
item_type = items_schema.get('type')
|
||||||
|
arr = [val[sk] for sk in sorted_keys]
|
||||||
|
if item_type in ('integer', 'number'):
|
||||||
|
converted = []
|
||||||
|
for v in arr:
|
||||||
|
if isinstance(v, str):
|
||||||
|
try:
|
||||||
|
converted.append(int(v) if item_type == 'integer' else float(v))
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
converted.append(v)
|
||||||
|
else:
|
||||||
|
converted.append(v)
|
||||||
|
arr = converted
|
||||||
|
cfg[k] = arr
|
||||||
|
elif not keys:
|
||||||
|
cfg[k] = []
|
||||||
|
elif pt == 'object' and 'properties' in ps and isinstance(val, dict):
|
||||||
|
_fix_json_arrays(val, ps['properties'])
|
||||||
|
_fix_json_arrays(plugin_config, schema['properties'])
|
||||||
|
|
||||||
# PRE-PROCESSING: Preserve 'enabled' state if not in request
|
# PRE-PROCESSING: Preserve 'enabled' state if not in request
|
||||||
# This prevents overwriting the enabled state when saving config from a form that doesn't include the toggle
|
# This prevents overwriting the enabled state when saving config from a form that doesn't include the toggle
|
||||||
if 'enabled' not in plugin_config:
|
if 'enabled' not in plugin_config:
|
||||||
|
|||||||
@@ -54,15 +54,18 @@
|
|||||||
const logoIdInput = row.querySelector('input[name*=".logo.id"]');
|
const logoIdInput = row.querySelector('input[name*=".logo.id"]');
|
||||||
|
|
||||||
if (nameInput && urlInput) {
|
if (nameInput && urlInput) {
|
||||||
feeds.push({
|
const feedObj = {
|
||||||
name: nameInput.value,
|
name: nameInput.value,
|
||||||
url: urlInput.value,
|
url: urlInput.value,
|
||||||
enabled: enabledInput ? enabledInput.checked : true,
|
enabled: enabledInput ? enabledInput.checked : true
|
||||||
logo: logoPathInput || logoIdInput ? {
|
};
|
||||||
|
if (logoPathInput || logoIdInput) {
|
||||||
|
feedObj.logo = {
|
||||||
path: logoPathInput ? logoPathInput.value : '',
|
path: logoPathInput ? logoPathInput.value : '',
|
||||||
id: logoIdInput ? logoIdInput.value : ''
|
id: logoIdInput ? logoIdInput.value : ''
|
||||||
} : null
|
};
|
||||||
});
|
}
|
||||||
|
feeds.push(feedObj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user