This commit is contained in:
kodi
2026-03-11 15:25:32 +01:00
parent 6a1a575383
commit d1f018a130
22 changed files with 909 additions and 49 deletions
+259
View File
@@ -0,0 +1,259 @@
# 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