upload volledige repo
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user