Files
webmanager-mvp/project_docs/UI_F6_RENAME_MOVE_DESIGN.md
2026-03-11 15:25:32 +01:00

7.7 KiB

UI_F6_RENAME_MOVE_DESIGN.md

1. Doel

Deze stap herontwerpt F6 naar een gecombineerde Rename/Move actie in Midnight Commander-stijl.

Doel:

  • F6 wordt de primaire actie voor zowel hernoemen als verplaatsen
  • de gebruiker werkt vanuit één compacte flow in plaats van aparte shortcuts
  • een losse Rename shortcut zoals Alt+R is daarna niet meer gewenst

Uitgangspunt:

  • de functiebalk kan Rename visueel nog blijven tonen als aparte knop, maar de keyboardflow voor F6 wordt leidend voor gecombineerde rename/move-semantiek
  • deze ontwerpstap verandert nog niets aan backendcontracten

2. Popupgedrag

Bij F6 opent de UI een compacte popup.

Popup-eisen:

  • één invoerveld
  • één contextregel met bronbestand/-map
  • één invoerveld met voorgesteld doelpad
  • compacte actieknoppen: OK en Cancel zijn optioneel, maar Enter en Escape zijn leidend

Keyboardgedrag:

  • Escape sluit popup zonder actie
  • Enter voert de actie uit

Semantiek:

  • popup is niet alleen een naamveld, maar een doelpadveld
  • gebruiker kan dus zowel alleen de naam aanpassen als een volledig ander doelpad kiezen

3. Defaultwaarde in het invoerveld

De standaardwaarde in het invoerveld wordt:

  • current path van het andere paneel
  • plus de huidige naam van het geselecteerde bestand of de geselecteerde map

Voorbeeld:

  • actief paneel: left
  • geselecteerd item: storage1/docs/report.txt
  • inactief paneel current path: storage2/archive
  • default invoerveld:
    • storage2/archive/report.txt

Motivatie:

  • dit past bij klassieke dual-pane file-managerverwachting: F6 suggereert standaard verplaatsen naar de andere kant
  • dezelfde popup blijft bruikbaar voor pure rename door het doelpad handmatig terug te brengen naar dezelfde parent met een andere naam

Belangrijk:

  • de default is altijd een volledig doelpad
  • geen impliciete "move into current dir" semantiek buiten wat in het tekstveld staat

4. Beslislogica

De UI bepaalt op basis van bronpad en ingevoerd doelpad of de actie neerkomt op rename of move.

Regel 1: zelfde parent, andere naam = rename

Als:

  • bron en doel in dezelfde parent-directory liggen
  • en alleen de naam verschilt

dan gebruikt de UI het bestaande rename endpoint.

Voorbeeld:

  • bron: storage1/docs/report.txt
  • doel: storage1/docs/report-final.txt
  • resultaat: rename

Regel 2: ander pad of andere parent = move

Als:

  • de doel-parent verschilt van de bron-parent
  • of de doel-root/paneelcontext anders is

dan gebruikt de UI het bestaande move endpoint.

Voorbeeld:

  • bron: storage1/docs/report.txt
  • doel: storage2/archive/report.txt
  • resultaat: move

Regel 3: ongewijzigde waarde = move naar andere paneel-locatie

Omdat de defaultwaarde standaard naar het andere paneel wijst, betekent ongewijzigd bevestigen normaal gesproken:

  • move naar het current path van het andere paneel met dezelfde naam

Voorbeeld:

  • bron: storage1/docs/report.txt
  • default doel: storage2/archive/report.txt
  • gebruiker drukt direct Enter
  • resultaat: move

Regel 4: exact gelijk aan bronpad = no-op

Als de gebruiker het invoerveld wijzigt naar exact hetzelfde pad als de bron:

  • er wordt geen rename of move gestart
  • de popup sluit niet automatisch met een schijnactie
  • voorkeur v1: compacte validatiemelding zoals Destination must differ from source

Dit voorkomt zinloze requests.


5. Relatie met huidige backend

Rename endpoint

Te gebruiken als de UI beslist op rename:

  • POST /api/files/rename

Mapping:

  • request gebruikt bestaand model:
    • path = source
    • new_name = basename(destination)

Belangrijke beperking:

  • bestaand rename-contract werkt alleen binnen dezelfde parent-directory
  • de UI moet dat contract respecteren en alleen in die situatie rename gebruiken

Move endpoint

Te gebruiken als de UI beslist op move:

  • POST /api/files/move

Mapping:

  • request gebruikt bestaand model:
    • source
    • destination als volledig doelpad

File versus directory

Huidige backend-scope blijft leidend:

  • rename ondersteunt bestaande rename-semantiek op file/directory zoals nu aanwezig
  • move is momenteel file-only

Gevolg voor gecombineerde F6-flow:

  • file + ander pad -> move toegestaan
  • file + zelfde parent andere naam -> rename toegestaan
  • directory + zelfde parent andere naam -> rename toegestaan
  • directory + ander pad -> niet toegestaan zolang backend directory-move niet ondersteunt

Voor directory-case buiten scope:

  • de popup mag wel openen
  • maar bevestigen moet blokkeren met duidelijke melding, bijvoorbeeld:
    • Directory move is not supported in v1

Huidige scopebeperkingen blijven gelden

Dus expliciet:

  • geen directory move
  • geen batch rename/move via deze popup in v1
  • geen backend-uitbreiding om F6 slimmer te maken
  • alle padvalidatie en foutafhandeling blijven backendgedreven

6. Focus en UX

Popup-eisen:

  • compact en centraal
  • niet schermvullend
  • focus direct in het invoerveld
  • volledige doelpadtekst selecteerbaar en bewerkbaar

Keyboardgedrag:

  • Enter = bevestigen
  • Escape = annuleren

Interactie-eis:

  • terwijl de popup open is, mag paneelkeyboardnavigatie niet interfereren
  • bestaande shortcuts voor paneelnavigatie en functiebalkacties moeten tijdelijk uitgeschakeld zijn, behalve popup-eigen Enter/Escape

Feedback:

  • validatiefouten compact in de popup tonen
  • backendfouten terugkoppelen zonder de popup-context te verliezen als de actie faalt

7. Scopebeperking

Niet in deze stap:

  • geen implementatie
  • geen backendwijzigingen
  • geen nieuwe dependencies
  • geen directory move ondersteuning
  • geen multi-select rename/move popup
  • geen extra path picker of browse-in-dialog

Deze ontwerpstap beperkt zich dus tot de UI-semantiek van één gecombineerde F6 flow.


8. Impactanalyse

Waarschijnlijk te wijzigen frontendbestanden bij implementatie:

  • webui/html/app.js
  • webui/html/index.html
  • webui/html/style.css
  • webui/backend/tests/golden/test_ui_smoke_golden.py

Verwachte aanpassingen

app.js:

  • nieuwe popup-state voor F6 rename/move
  • beslislogica rename versus move
  • verwijdering of aanpassing van losse Alt+R keyboardbinding
  • hergebruik van bestaande rename- en move-action handlers waar mogelijk

index.html:

  • compacte popup-markup met invoerveld en foutregel

style.css:

  • compacte popup-styling, aansluitend op bestaande wildcard/view/edit modals

Regressierisico

Belangrijkste risico's:

  • verwarring tussen bestaande losse Rename knop en nieuwe F6-semantiek
  • directorycases die per ongeluk op move uitkomen terwijl backend dat niet ondersteunt
  • dubbele logica tussen functiebalk-Rename, functiebalk-Move en F6-popup
  • keyboardconflict met bestaande F6 = Move shortcut uit action-shortcuts v1

Mitigatie:

  • één centrale beslisfunctie voor rename versus move
  • Alt+R verwijderen zodra F6-flow geïmplementeerd wordt
  • bestaande knophandlers alleen hergebruiken waar de semantiek echt gelijk is; anders kleine centrale wrapperfunctie introduceren

9. Teststrategie

Smoke/regressietests

Bij implementatie aan te passen:

  • UI smoke test controleert aanwezigheid van F6 popup-container
  • controle op relevant inputveld en basiscontrols
  • bestaande functiebalk- en modalchecks blijven bestaan

Handmatige validatie

Essentieel:

  • F6 opent popup met defaultwaarde gebaseerd op ander paneel + huidige naam
  • Enter met default leidt tot move
  • wijziging naar zelfde parent + andere naam leidt tot rename
  • directory + cross-path wordt netjes geblokkeerd
  • Escape sluit popup zonder bijeffecten
  • paneelkeyboardnavigatie werkt niet door popup heen
  • bestaande Move knop blijft werken
  • bestaande Rename knop blijft werken totdat eventuele latere UI-consolidatie expliciet wordt doorgevoerd