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

6.7 KiB

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

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)