fix(cms): reindex nested array paths correctly in Content Editor
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions

reindexItems replaced the FIRST [n] index in a data-path, which for nested
arrays (e.g. services[1].specs.items) rewrote the OUTER array index instead
of the item's own index. Deleting or adding an item scattered paths across
services[0..n], produced sparse arrays (null items) and schema errors like
'$.details.services[1].specs.items[0]: string érték szükséges'.

Rewrite only the index directly following the reindexed array's path prefix;
drop the now-redundant str-item special case.

Closes MITHOME-30
This commit is contained in:
Do Siki
2026-08-18 12:53:18 +02:00
parent afcbdc26bf
commit 713d89b09c
2 changed files with 58 additions and 9 deletions
+10 -8
View File
@@ -298,21 +298,23 @@ function makeObjCard(obj, idx, path) {
function reindexItems(itemsEl) {
if (!itemsEl) return;
const path = itemsEl.dataset.arrayItems;
// WHY: rewrite only the index that directly follows THIS array's own path prefix.
// A generic "replace first [n]" rule corrupts nested arrays (e.g. deleting from
// services[1].specs.items rewrites the OUTER services index and scatters paths
// across services[0..n], producing sparse arrays and schema errors).
const prefix = path + '[';
Array.from(itemsEl.children).forEach((child, i) => {
// Update all data-path in this child
child.querySelectorAll('[data-path]').forEach(el => {
const old = el.dataset.path;
// Replace the array index part: path[old_i] → path[new_i]
el.dataset.path = old.replace(/^(.+?)\[(\d+)\]/, (_,p) => p + '[' + i + ']');
if (typeof old !== 'string' || !old.startsWith(prefix)) return;
const rest = old.slice(prefix.length);
const bracketEnd = rest.indexOf(']');
const suffix = bracketEnd === -1 ? '' : rest.slice(bracketEnd);
el.dataset.path = prefix + i + suffix;
});
// Update card header
const hdr = child.querySelector('.card-header');
if (hdr) hdr.textContent = path + '[' + i + ']';
// Update str-item textarea
const ta = child.querySelector('textarea[data-path]');
if (ta && !ta.closest('.obj-card')) {
ta.dataset.path = path + '[' + i + ']';
}
});
}