Skip to content

Allow adding and deleting apps.yaml list entries and settings from the apps editor - #4741

Merged
springfall2008 merged 2 commits into
mainfrom
feat/apps-editor-add-delete-4714
Aug 27, 2026
Merged

Allow adding and deleting apps.yaml list entries and settings from the apps editor#4741
springfall2008 merged 2 commits into
mainfrom
feat/apps-editor-add-delete-4714

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

This is an automated draft PR generated from issue #4714 — a maintainer should review it before merging.

Fixes #4714

Summary

The structured /apps editor could only change the value of settings that already existed, so a compare profile could be edited but never removed, added, or given a new setting — _update_nested_yaml_value raised KeyError for an unknown final key and html_apps_post had no wire representation for a delete or a create.

This adds both halves:

  • Rendering (render_type): every nested list entry and every setting now gets a Delete button, and each list/dictionary gets an Add item / Add setting row at the end. List entries that are themselves dictionaries (a compare profile) previously rendered with no row id and no actions at all, so they now get both.
  • Client (get_apps_js): deletions and additions are queued like any other edit and only applied on save, so they can be undone (Undo / Remove) or dropped with Discard Changes. Add item against compare_list opens with a name:/id: template, so adding a tariff to compare no longer means hand-editing YAML.
  • Server (html_apps_post): new add and delete change types, with _add_nested_yaml_value / _delete_nested_yaml_value alongside the existing update helper (whose path parsing and navigation are now shared). Added values are parsed as a YAML fragment, so a whole new list entry with its own settings can be created in one go and keeps its types.

Two ordering details worth reviewing:

  • Deletions are applied after all edits and additions, sorted deepest path and highest list index first, because paths were rendered against the pre-delete indices — deleting compare_list[0] and compare_list[2] in one save otherwise removes the wrong second entry.
  • Adds are keyed uniquely by the browser (path#n) so several can target the same list, and a deletion is keyed path#delete so undoing it does not silently discard a pending edit of the same row. The server therefore takes the path from the change itself rather than from the key.

Both add and delete are refused for top-level arguments, so this cannot restructure apps.yaml above the list/dictionary level. The raw /apps_editor remains the way to do that.

Testing

  • New apps/predbat/tests/test_web_apps_edit.py (registered as web_apps_edit in TEST_REGISTRY) — 16 checks covering single and multiple deletions, the index-shift regression, adding two profiles at once, adding a typed setting, an edit plus a delete in one save, the refusal cases (duplicate key, out-of-range index, appending to a dictionary, top-level add/delete, empty value), comment preservation through the ruamel round trip, and the rendered buttons. The client half is asserted structurally, as test_debug_history_client_js.py does, since there is no JS engine in the suite. tools/triage_test.sh web_apps_edit passes.
  • coverage/run_pre_commit passes: all 12 hooks Passed, and run_all --quick reports all tests passed (4 slow tests skipped). That includes web_if, which exercises GET/POST /apps end to end.

Notes

Documentation for the new buttons added to the Apps View section of docs/web-interface.md.

…e apps editor

Compare profiles (and any other apps.yaml list) could only have their existing
values edited - there was no way to remove one, add a new one, or add a new
setting to one, so it had to be done by hand in the raw YAML editor.

Adds a Delete button to every nested list item and setting, and Add item /
Add setting buttons at the end of each group, backed by new "add" and "delete"
change types in html_apps_post. Deletions are applied after all edits, deepest
path and highest list index first, so several in one save do not shift the
indices the others refer to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@springfall2008 springfall2008 self-assigned this Aug 25, 2026
@springfall2008
springfall2008 requested a balanced review from Copilot August 25, 2026 17:22
@springfall2008
springfall2008 marked this pull request as ready for review August 25, 2026 17:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Path validation, profile validation, and non-atomic live configuration mutations can cause incorrect or inconsistent configuration.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds structured creation and deletion of nested apps.yaml entries.

Changes:

  • Adds nested Add/Delete controls and pending-change handling.
  • Adds server-side YAML mutation helpers.
  • Adds documentation and regression tests.
File summaries
File Description
apps/predbat/web.py Renders controls and processes YAML changes.
apps/predbat/web_helper.py Adds client-side dialogs and change tracking.
apps/predbat/tests/test_web_apps_edit.py Tests add/delete behavior.
apps/predbat/unit_test.py Registers the new tests.
docs/web-interface.md Documents the controls.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 5
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/predbat/web.py Outdated
Comment thread apps/predbat/web.py
Comment thread apps/predbat/web.py Outdated
Comment thread apps/predbat/web.py Outdated
Comment thread apps/predbat/web.py Outdated
- Determine nesting from the parsed path, not the client-supplied isNested
  flag, so a delete/add posted with isNested spoofed true cannot reach a
  top-level argument
- Validate that every compare_list profile keeps a unique, non-empty id
  and name after a batch, since compare.py indexes results by id and would
  otherwise raise KeyError
- Tokenize every bracket pair in a path component instead of just one, so
  a directly nested list (list of lists) can be edited, added to or
  deleted from
- Stage every add/update/delete on a copy of self.args and only publish it
  in place once the whole batch has validated and the file write has
  succeeded, so a batch that fails partway (or a failed write) never
  leaves self.args half-applied and unrecoverable on retry

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@springfall2008
springfall2008 merged commit b0b7e55 into main Aug 27, 2026
2 checks passed
@springfall2008
springfall2008 deleted the feat/apps-editor-add-delete-4714 branch August 27, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow deleting 'compare' profiles from the apps editor

2 participants