Files
leistungsbilanz-ts/docs/circuit-list-editor-interactions.md
T
2026-07-23 17:22:56 +02:00

129 lines
5.7 KiB
Markdown

# 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.
## `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.
## 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
## 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
- 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
- circuit drag (BMK handle):
- reorder circuits inside same section only
- cross-section reorder is rejected
- bulk device row move:
- supported via multi-selection + drag
- row assignments, optional target creation and reserve-state updates are committed in one SQLite transaction
- 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
- 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 with async `redo`/`undo` and reloads tree after each command.
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:
- session-local only
- no persisted history across browser reload