Files
leistungsbilanz-ts/docs/circuit-list-editor-interactions.md
T
2026-07-25 20:26:45 +02:00

6.7 KiB

Circuit List Editor Interactions

Editing Model

Inline cells are static text by default. A cell enters edit mode by:

  • double-click
  • Enter
  • F2
  • typing a printable character (type-to-edit)

Enter confirms changes. Escape cancels current edit draft. Tab and Shift+Tab confirm and move to next/previous editable cell.

Committed cells on existing circuits and device rows are persisted as typed project commands with an optimistic project revision. Only the edited fields are included, so an older tree response cannot write unrelated fields back. The server records the inverse in the same transaction.

selectedCell vs editingCell

  • selectedCell tracks spreadsheet navigation focus.
  • editingCell tracks active input draft (draft, edit mode, focus token).

The editor can have a selected cell without an active editor input. editingCell is only set while editing.

Normalized Visible Grid

The UI works from a normalized visibleRows model built from filtered/sorted sections:

  • section header rows
  • circuit rows (circuitCompact, circuitSummary, reserveCircuit)
  • device rows (deviceRow)
  • section placeholder rows (placeholder)

Selection, keyboard movement, and editability checks run against this normalized grid, not directly against nested API JSON.

Keyboard Behavior

  • Enter: start edit (when not editing) or commit (when editing input)
  • F2: start edit on selected cell
  • Escape: cancel edit draft, or clear multi-row selection when not editing
  • Tab / Shift+Tab: move between editable cells (commits active edit)
  • arrow keys: move selected cell in grid when not editing
  • type-to-edit: printable keys open edit mode and replace current display value with typed character
  • Ctrl+Plus / Ctrl+Shift+Plus: insert below the selected circuit or device context
  • Delete: delete the selected circuit or device context after confirmation

For insertion, a circuit-level cell creates a reserve circuit directly after the selected circuit. A device-level cell creates a manual device row directly after the selected device. On the virtual -frei- row, or without a valid row selection, the shortcut creates a circuit at the end of the active section. Insertions use command history and never renumber existing equipment identifiers.

For deletion, a circuit-level cell targets the complete circuit and a device-level cell targets only the device row. Deleting the last device requires an explicit choice between keeping the empty circuit as reserve, deleting the complete circuit, or cancelling. Delete commands are undoable and never renumber remaining circuits.

Creating or deleting a device row updates the row and the circuit reserve state in one SQLite transaction.

Equipment Identifier Validation

Equipment identifiers are compared case-insensitively after trimming whitespace. A conflicting edit is highlighted before submission and cannot be committed. Existing conflicts are highlighted in the grid. Validation errors remain dismissible above the editor instead of replacing the complete workspace.

-frei- Placeholder Behavior

Each section has a trailing placeholder row showing -frei- in BMK column:

  • serves as drop target for creating new circuits from project devices or moved rows
  • editable placeholder cells can create a new circuit + first row through the same edit command flow
  • a new circuit and its initial row(s) are created in one SQLite transaction

Add Circuit Behavior

Add-circuit actions create reserve circuits in the active section using the section prefix and next numeric suffix (max + 1).
No automatic gap-filling or global renumbering is performed.

Drag-and-Drop Behavior

Intent is separated by drag source type:

  • project device drag:
    • drop to section/placeholder -> create new circuit with linked row
    • the new circuit and linked row are committed atomically
    • drop to existing circuit row -> append row to that circuit
    • lighting devices are accepted only by the lighting section
    • other devices are accepted only by the section matching their phase type
    • invalid targets show rejection feedback and do not create data
  • device row drag:
    • drop to existing circuit -> move row(s) into that circuit
    • drop to placeholder -> create new target circuit and move row(s)
    • crossing a section boundary requires explicit confirmation
    • phase type, category, linked project device and local row values remain unchanged
    • target creation, row assignments and reserve-state updates use one SQLite transaction
  • circuit drag (BMK handle):
    • reorder circuits inside same section only
    • cross-section reorder is rejected
    • the complete section order is validated and stored in one SQLite transaction
  • bulk device row move:
    • supported via multi-selection + drag
  • multi-circuit move:
    • supported for same-section selected circuit blocks

The sidebar insertion controls use the same project-device placement rules as drag-and-drop. Invalid section and circuit options are disabled after selecting a project device.

Cross-section device moves show confirmation-required feedback before drop. The confirmation names source and target sections and warns that the unchanged device classification may need manual review. Cancelling leaves every row and circuit unchanged. Moving never renumbers existing circuits.

Filtering and Sorting

  • Per-column filtering works on normalized displayed values.
  • Sorting is view-level first and treats circuits as blocks.
  • Multi-device circuits are not split during sort.
  • Sorting alone does not persist order.

Apply Sorted Order

Apply sorted order persists current sorted block order to backend by section.

  • disabled while filters are active
  • undoable via command history
  • each complete section order is stored atomically
  • until applied, sort remains view-only

Column Configuration

  • Column visibility and order are configurable.
  • BMK column (equipmentIdentifier) is locked as first column.
  • Layout is saved in local storage (circuitTreeEditor.columnLayout.v1).

Undo/Redo

Undo/redo wraps editor operations as command objects and reloads the tree after each command. Existing Circuit and device-row cell edits execute persistent project commands; their toolbar undo/redo calls the project-wide server history. Other covered operations still use their existing direct API writes and session-local inverse callbacks during the cutover.

Covered operations include:

  • insert/delete circuit
  • insert/delete row
  • edit cell values
  • moves (single/bulk rows, circuit reorder)
  • renumber and identifier update flows
  • apply sorted order

Current limitations:

  • the visible editor stack is still session-local and is empty after reload
  • structural and destructive editor actions are not all connected to the persistent command boundary yet