Files
webmanager-mvp/project_docs/UI_DUAL_PANE_DESIGN.md
2026-03-11 09:39:41 +01:00

234 lines
6.7 KiB
Markdown

# UI_DUAL_PANE_DESIGN.md
## Doel van deze notitie
Deze notitie beschrijft de ontwerpstap voor **Dual-pane UI v2** op basis van de huidige v1.1 UI en `UI_VISION_MC.md`.
Randvoorwaarden voor deze stap:
- geen backendwijzigingen
- geen nieuwe dependencies
- geen multi-select
- geen viewer/editor
- geen keyboard-uitbreiding (behalve als latere notitie)
---
## 1) Ombouw van single-page UI naar twee panelen
### Huidige situatie (v1.1)
- één browsepaneel met één `currentPath`
- globale selectie voor dat paneel
- acties (mkdir/rename/delete/copy/move) vanuit die ene context
### Doelsituatie (v2)
- twee browsepanelen naast elkaar: `left` en `right`
- elk paneel heeft:
- eigen path input + go
- eigen breadcrumbs
- eigen directory/file lijst
- eigen geselecteerd item
- één paneel is altijd **actief**
- acties worden contextueel uitgevoerd vanuit actief paneel
- tasks- en bookmarks-sectie blijven gedeeld (onder of naast de panelen)
### UI-structuur op hoog niveau
- Header: algemene status
- Main layout:
- Paneel links (`left-pane`)
- Paneel rechts (`right-pane`)
- Utility-kolom (tasks + bookmarks)
- Actieknoppen:
- per paneel (mkdir)
- actieve-paneelacties (rename/delete/copy/move)
### Bookmark-open gedrag (expliciete keuze)
- Een klik op een bookmark opent altijd in het **actieve paneel**.
- Motivatie (kort): dit is het meest voorspelbaar, sluit aan op het active/inactive-pane model, en voorkomt verborgen side-effects in het niet-actieve paneel.
---
## 2) Benodigde state per paneel
## State-model
```js
state = {
panes: {
left: {
currentPath: "storage1",
showHidden: false,
selectedItem: null, // { path, name, kind: "file"|"directory" }
entries: { directories: [], files: [] }
},
right: {
currentPath: "storage1",
showHidden: false,
selectedItem: null,
entries: { directories: [], files: [] }
}
},
activePane: "left", // "left" | "right"
selectedTaskId: null,
pollHandle: null
}
```
### Verplichte kernstate
- `current path` per paneel
- `selected item` per paneel
- `active pane` globaal
### Afgeleide helperstate
- `inactivePane = activePane === "left" ? "right" : "left"`
- `canRename/canDelete` op basis van selectie actief paneel
- `canCopy/canMove` alleen als selectie actief paneel een file is
---
## 3) Copy/move van actief paneel naar ander paneel
## Semantiek v2
- Bron komt altijd uit `selectedItem` van `activePane`.
- Doelcontext is standaard het **andere paneel**.
- `destination` blijft volledig doelpad (geen impliciete shell-achtige "copy into" semantics).
### Destination-bepaling
- `targetBasePath = panes[inactivePane].currentPath`
- `destination = targetBasePath + "/" + sourceItem.name`
- UI toont dit voorstel in prompt/confirm en laat aanpassen toe.
### Copy flow
1. User selecteert file in actief paneel.
2. User kiest `Copy`.
3. UI bouwt default destination op basis van inactieve paneel-path + bestandsnaam.
4. UI roept `POST /api/files/copy` met `{source, destination}`.
5. Bij `202`: tasks refresh + taskdetail naar nieuw task_id.
6. Na start: beide panelen refresh (best effort), zodat user contextueel resultaat ziet.
### Move flow
1. Zelfde als copy, maar endpoint `POST /api/files/move`.
2. Bij `202`: tasks refresh + taskdetail selecteren.
3. Beide panelen refreshen (source kan verdwijnen, destination verschijnen).
### Refresh-semantiek per actie (expliciet)
- `mkdir`: refresh alleen het actieve paneel.
- `rename`: refresh alleen het actieve paneel.
- `delete`: refresh alleen het actieve paneel.
- `copy`: refresh beide panelen.
- `move`: refresh beide panelen.
Rationale (kort):
- Lokale mutaties (`mkdir/rename/delete`) zijn paneelgebonden en blijven daardoor snel en voorspelbaar.
- Transfer-acties (`copy/move`) raken bron- en doelcontext, dus beide panelen verversen voorkomt stale state.
### Foutafhandeling
- Validatiefouten vóór task-creatie direct tonen op actiegebied actief paneel.
- Runtime-fouten via task-status (`failed`) zichtbaar in tasklijst/detail.
---
## 4) Bestaande backend-endpoints die hergebruikt worden
Geen contractwijzigingen; hergebruik van bestaande endpoints:
Browse/file ops:
- `GET /api/browse`
- `POST /api/files/mkdir`
- `POST /api/files/rename`
- `POST /api/files/delete`
- `POST /api/files/copy`
- `POST /api/files/move`
Tasks:
- `GET /api/tasks`
- `GET /api/tasks/{task_id}`
Bookmarks:
- `GET /api/bookmarks`
- `POST /api/bookmarks`
- `DELETE /api/bookmarks/{bookmark_id}`
---
## 5) Waarschijnlijk te wijzigen bestanden
Primair frontend:
- `webui/html/index.html`
- layout naar dual-pane
- pane-specifieke controls/containers
- `webui/html/app.js`
- state refactor naar `panes.left/right`
- browse/render/actions per pane
- active-pane switching
- copy/move destination vanuit ander pane
- `webui/html/style.css`
- twee panelen visueel gelijkwaardig
- actieve-paneel-highlight
- responsieve fallback (mobiel: gestapeld)
Tests:
- `webui/backend/tests/golden/test_ui_smoke_golden.py`
- assertions bijwerken naar dual-pane markup/ids
Niet gepland in deze stap:
- backend python-bestanden
- API schemas/routes/services
---
## 6) Regressierisico
## Hoog risico
- Stateverwarring tussen links/rechts paneel (actie op verkeerde paneelcontext).
- Onjuiste destination-opbouw bij copy/move (per ongeluk vanuit actief i.p.v. inactief pad).
## Middel risico
- Disable/enable logica van knoppen niet synchroon met actieve paneelselectie.
- Refresh-volgorde na acties waardoor UI tijdelijk stale data toont.
- Bookmarks die per ongeluk in het verkeerde paneel openen als `activePane` niet consequent wordt gebruikt.
## Laag risico
- CSS regressies in mobile layout.
- Kleine tekst/label inconsistenties in error/statusweergave.
## Mitigatie
- Duidelijke pane-identifiers in DOM en handlers (`left`/`right`).
- Eén centrale helper voor `getActivePane()` en `getInactivePane()`.
- Eén centrale helper voor copy/move destination-opbouw.
- Smoke tests expliciet op dual-pane hoofdstructuur.
---
## 7) Aan te passen/toe te voegen UI smoke tests
## Aanpassen bestaande smoke test
`test_ui_smoke_golden.py`:
- huidige checks op enkel browsepaneel vervangen door dual-pane checks.
Nieuwe/gewijzigde assertions:
- UI mount bestaat op `/ui`.
- HTML bevat beide hoofdpanelen:
- `id="left-pane"`
- `id="right-pane"`
- HTML bevat actieve-paneel-indicator/container (bijv. class of data-attribute).
- Assets blijven gemapt:
- `/ui/app.js`
- `/ui/style.css`
## Kleine extra smoke checks (zonder backenduitbreiding)
- basisactieknoppen aanwezig voor actieve-paneelacties.
- tasks- en bookmarks-panelen blijven aanwezig in HTML.
Geen end-to-end browserautomatisering in deze stap.
---
## Niet in scope voor deze implementatieslice
- multi-select
- viewer/editor
- cancel/retry
- history UI
- nieuwe backend endpoints
- keyboard mapping uitbreiding (eventueel later)