260 lines
7.7 KiB
Markdown
260 lines
7.7 KiB
Markdown
# 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
|