fix(m9/T30): empty-state guard keys off resolved fields (top-level \$ref); shift list raw-text on item removal
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
values.
|
||||
*@
|
||||
|
||||
@if (_shapes.Count == 0)
|
||||
@if (_topLevelFields.Count == 0)
|
||||
{
|
||||
<div class="text-muted small fst-italic">No parameters declared.</div>
|
||||
}
|
||||
@@ -399,18 +399,47 @@ else
|
||||
await Emit();
|
||||
}
|
||||
|
||||
// After a removal, item paths above the removed index shift down by one; clear
|
||||
// their stale raw-text/error entries so the re-rendered rows read fresh.
|
||||
// After a removal at removedIndex, paths for items above that index shift down
|
||||
// by one. Mirror the value-list RemoveAt by: (1) for each index > removedIndex
|
||||
// found in a dict, re-key it as index-1; (2) clear the now-vacated top slot
|
||||
// (the original highest index). Items below the removed index are unaffected.
|
||||
private void ShiftListState(string path, int removedIndex)
|
||||
{
|
||||
ShiftDict(_rawText, path, removedIndex);
|
||||
ShiftDict(_parseErrors, path, removedIndex);
|
||||
}
|
||||
|
||||
private static void ShiftDict(Dictionary<string, string> dict, string path, int removedIndex)
|
||||
{
|
||||
var prefix = $"{path}[";
|
||||
foreach (var key in _rawText.Keys.Where(k => k.StartsWith(prefix, StringComparison.Ordinal)).ToList())
|
||||
// Collect keys under this list prefix, parse the item index, and build the
|
||||
// shift map in one pass so in-place mutation does not interfere with iteration.
|
||||
var toShift = new List<(string Key, int ItemIndex, string Suffix)>();
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
_rawText.Remove(key);
|
||||
if (!key.StartsWith(prefix, StringComparison.Ordinal)) continue;
|
||||
// Extract the integer after the '['.
|
||||
var rest = key.AsSpan(prefix.Length); // e.g. "2]" or "2].field"
|
||||
var closePos = rest.IndexOf(']');
|
||||
if (closePos < 0) continue;
|
||||
if (!int.TryParse(rest[..closePos], System.Globalization.NumberStyles.Integer,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out var idx)) continue;
|
||||
// Only touch items ABOVE the removed index; items at lower indices are stable.
|
||||
if (idx <= removedIndex) continue;
|
||||
var suffix = rest[(closePos + 1)..].ToString(); // everything after ']'
|
||||
toShift.Add((key, idx, suffix));
|
||||
}
|
||||
foreach (var key in _parseErrors.Keys.Where(k => k.StartsWith(prefix, StringComparison.Ordinal)).ToList())
|
||||
|
||||
// Apply: remove old key, write shifted key. Higher indices first so we never
|
||||
// overwrite a key that is itself still pending a shift (would happen if we
|
||||
// iterated lowest-to-highest and the same path base appeared at consecutive
|
||||
// indices). Processing highest → lowest avoids the collision.
|
||||
foreach (var (key, idx, suffix) in toShift.OrderByDescending(t => t.ItemIndex))
|
||||
{
|
||||
_parseErrors.Remove(key);
|
||||
var value = dict[key];
|
||||
dict.Remove(key);
|
||||
var shiftedKey = $"{path}[{idx - 1}]{suffix}";
|
||||
dict[shiftedKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user