From 31a42d34c7b3515e28203d6b62e1c4f593dc8f60 Mon Sep 17 00:00:00 2001 From: kodi Date: Wed, 11 Mar 2026 13:28:18 +0100 Subject: [PATCH] feat: menu layout --- project_docs/UI_FUNCTION_BAR_V2_DESIGN.md | 188 ++++++++++++++++++ .../test_ui_smoke_golden.cpython-313.pyc | Bin 4216 -> 4851 bytes .../tests/golden/test_ui_smoke_golden.py | 17 ++ webui/html/app.js | 1 - webui/html/index.html | 17 +- webui/html/style.css | 24 ++- 6 files changed, 237 insertions(+), 10 deletions(-) create mode 100644 project_docs/UI_FUNCTION_BAR_V2_DESIGN.md diff --git a/project_docs/UI_FUNCTION_BAR_V2_DESIGN.md b/project_docs/UI_FUNCTION_BAR_V2_DESIGN.md new file mode 100644 index 0000000..1f83c8d --- /dev/null +++ b/project_docs/UI_FUNCTION_BAR_V2_DESIGN.md @@ -0,0 +1,188 @@ +# UI_FUNCTION_BAR_V2_DESIGN.md + +## 1. Doel en scope + +Deze stap beschrijft de evolutie van de huidige onderbalk onder de twee panelen naar een compactere, duidelijkere functiebalk in Midnight Commander-stijl. + +Doel: +- de balk onder de panelen wordt visueel en functioneel herkenbaar als vaste actiebalk +- acties blijven direct gekoppeld aan het actieve paneel +- de balk wordt voorbereid op latere functietoets-labeling zonder nu al functietoetsen te implementeren + +In scope: +- compactere horizontale functiebalk onder de twee panelen +- vaste knopvolgorde +- duidelijkere relatie tussen actie, actief paneel en selectie +- ontwerpvoorbereiding voor latere F3-F8 koppeling + +Out of scope: +- geen implementatie van `View` +- geen implementatie van `Edit` +- geen functietoetsen +- geen backendwijzigingen +- geen nieuwe dependencies + +--- + +## 2. Positie en layout + +De functiebalk staat vast onder de twee panelen, op de plek van de huidige onderste actiebalk. + +Layoutdoelen: +- horizontaal gecentreerd in de beschikbare breedte +- compact in hoogte +- kleine, gelijkmatige spacing tussen knoppen +- visueel duidelijk gescheiden van de paneelzone, maar zonder grote verticale band +- uitbreidbaar naar extra labels of functietoetsbadges zonder redesign + +Voorstel: +- één compacte horizontale rij +- de rij krijgt een eigen container binnen de footerzone +- links en rechts geen brede utilityblokken +- status/fouttekst blijft buiten of onder de functiebalk, zodat de knoppenrij zelf compact blijft + +--- + +## 3. Vaste volgorde van de knoppen + +De functiebalk gebruikt exact deze volgorde: + +1. `View` +2. `Edit` +3. `Copy` +4. `Move` +5. `Rename` +6. `MKdir` +7. `Delete` + +Reden: +- sluit aan op klassieke file-manager verwachtingen +- groepeert navigatie-/inhoudsacties eerst, daarna muterende file-acties +- houdt de destructieve actie `Delete` aan het einde + +--- + +## 4. Relatie met toekomstig functietoetsgebruik + +De functiebalk moet later zonder structurele herbouw koppelbaar zijn aan: + +- `F3 = View` +- `F4 = Edit` +- `F5 = Copy` +- `F6 = Move` +- `F7 = MKdir` +- `F8 = Delete` + +Ontwerpimplicatie: +- elke knop moet later een compacte functietoetsbadge of prefix kunnen tonen +- `Rename` blijft voorlopig zonder vaste F-toets in deze mapping +- deze stap implementeert nog geen keyboardbindingen of badgegedrag + +--- + +## 5. Relatie met actief paneel en selectie + +Alle acties in de functiebalk werken altijd vanuit het actieve paneel. + +### Geen selectie +- `View`: disabled +- `Edit`: disabled +- `Copy`: disabled +- `Move`: disabled +- `Rename`: disabled +- `MKdir`: enabled +- `Delete`: disabled + +### Exact 1 selectie +- `View`: later afhankelijk van file-type; in deze stap nog niet functioneel +- `Edit`: later afhankelijk van file-type; in deze stap nog niet functioneel +- `Copy`: enabled als huidige backendactie geldig is +- `Move`: enabled als huidige backendactie geldig is +- `Rename`: enabled +- `MKdir`: enabled +- `Delete`: enabled + +### Meerdere selecties +- `View`: disabled +- `Edit`: disabled +- `Copy`: enabled als alle geselecteerde items compatibel zijn met bestaande backendscope +- `Move`: enabled als alle geselecteerde items compatibel zijn met bestaande backendscope +- `Rename`: disabled +- `MKdir`: enabled +- `Delete`: enabled + +### File- of directoryselectie +- `Copy` en `Move` blijven gebonden aan de huidige backendbeperking +- zolang backend `file-only` is voor copy/move: + - selectie met directories blokkeert `Copy` + - selectie met directories blokkeert `Move` +- `Delete` blijft werken volgens bestaande backendregels +- `Rename` volgt bestaande rename-semantiek + +Belangrijk: +- de functiebalk toont niet alleen acties, maar reflecteert ook duidelijk welke acties in de huidige context geldig zijn via enabled/disabled toestand + +--- + +## 6. Scopebeperking + +Nog niet in deze stap: +- geen `View`-implementatie +- geen `Edit`-implementatie +- geen functietoetsen +- geen backendwijzigingen +- geen extra UI-frameworks + +Deze ontwerpstap gaat dus alleen over de functiebalk zelf, niet over nieuwe actiecapaciteit. + +--- + +## 7. Impactanalyse + +Waarschijnlijk te wijzigen bestanden: +- `webui/html/index.html` +- `webui/html/style.css` +- `webui/html/app.js` +- `webui/backend/tests/golden/test_ui_smoke_golden.py` + +### Regressierisico + +Belangrijkste risico's: +- huidige actieknoppen verliezen hun correcte enabled/disabled logica +- de relatie tussen actief paneel en actiebalk wordt visueel minder duidelijk +- keyboard- en klikflows kunnen breken als knop-ids of handlers onzorgvuldig worden vervangen +- extra compactheid kan ten koste gaan van leesbaarheid op smallere schermen + +Mitigatie: +- bestaande action handlers hergebruiken waar mogelijk +- ids voor bestaande werkende acties stabiel houden of gecontroleerd migreren +- disabled-logica centraal laten in plaats van per knop ad hoc +- smoke tests uitbreiden met de nieuwe functiebalkstructuur + +--- + +## 8. Teststrategie + +### Smoke/regressietests + +Aan te passen: +- `test_ui_smoke_golden.py` + +Nieuwe of aangepaste checks: +- functiebalkcontainer aanwezig onder de panelen +- knopvolgorde in HTML komt overeen met het ontwerp +- bestaande actieknoppen voor werkende backendacties blijven aanwezig +- assets blijven correct gemount + +### Handmatige validatie + +Te valideren bij implementatie: +- functiebalk blijft compact op desktop +- functiebalk blijft bruikbaar op smallere breedte +- actief paneel blijft bepalend voor de actiecontext +- disabled/enable toestand klopt bij: + - geen selectie + - 1 selectie + - meerdere selecties + - gemixte file/directory-selectie +- bestaande keyboard- en klikselectieflow blijft intact diff --git a/webui/backend/tests/golden/__pycache__/test_ui_smoke_golden.cpython-313.pyc b/webui/backend/tests/golden/__pycache__/test_ui_smoke_golden.cpython-313.pyc index 8ba0d96fa32760353e9c896fea15c36838de6a4a..18fabcdeaa0b389fc96a4604dfc9ba0225ee81cc 100644 GIT binary patch delta 789 zcmZ9K%TE(Q9LHz2yW3?;Tj&E?9<>%h7D7NG0xBFZ5~7jtNHsysW?=_h+wRucE$Ydb z7((I+=O9N99(wVBTs(L;UPJlHV@_ z`kbF#H=fGtfzKYFNTmk=SeoTG0{nZ9ToEGVr&z<@Fhs_M78ouwQf8F=5?f#$V`qKZ z)5o!P03<;-n2t?ClTY(ua8aDnx3jBtG;lf&<88o6WoO;06tn}il&eT zQ*jpW5-&Ga;sB(@zq$WzSfm}3^q9f|P~xQ5yL`LW(1%hB1#{jpEVFA)!>R9nW-S@$ zM%SEU{*g#GoQe#vXfC50_&|8x%HKL5bJh~7$RNwc$kcKN4IO2XQ#Qy4@4YrJj?=%! z4Gc{T%?t?!HV!^Sp#(@?T1>ctVe06n>(gu-Vdw1if|hkf+rkdg6)$-wCE8t|g>{6H zt{S@Sia8Bu5O%BbmTj;ZZQD!RC6h_=L%It$$(^bfqEbA*BlVC8xs{xgJ4v&gAO(49 zd`Ift^Y?CVF%|vr_dcGV)fc-j!loQfw{$XtX%E zeWdTTbmH5d2Sm?6n=QxlV+~^pzp*KMxQ@eYpcF$3gpwZQ0P53>hYRa8}NM{|sMRdXC{%oQADt13Rp66zS}&H&8zw2UDA zutOBfV4vfK!Tstsq5sPSydQkoIz(-k&uNDFU%4xt&RKdPi-z$eDFrWu2H@bDv>Q{l PV#+?C;^PvTt!erV1R2yh delta 365 zcmeyY`a^;5GcPX}0}!x=Zp=*L*vR*lnVSX3WoBSt{H(ydnUCc*)8x7AB9s5J34mxp zp-^U1CXfaO1_g$622J6~c^qx(e3>b>O1ar7nMJxuC3#9!ydZvZenBM?H#fg*avtXd zM()WfTDJ^61R9ti*n)%5=%1T)AEaMaVHiRrxumC7M3RFXtEXwf|MytuH#?9s5@C* zU=O4IEoyi7*(u{hOeFSBMKD{`HjCls!y&S*J<3_#9@5Jm None: mount = self._ui_mount() static_root = Path(mount.app.directory) diff --git a/webui/html/app.js b/webui/html/app.js index f348ba5..a58daac 100644 --- a/webui/html/app.js +++ b/webui/html/app.js @@ -856,7 +856,6 @@ function setupEvents() { document.getElementById("copy-btn").onclick = startCopySelected; document.getElementById("move-btn").onclick = startMoveSelected; document.getElementById("mkdir-btn").onclick = createFolderForActivePane; - document.getElementById("add-bookmark-btn").onclick = addBookmark; const wildcard = wildcardPopupElements(); wildcard.cancelButton.onclick = closeWildcardPopup; diff --git a/webui/html/index.html b/webui/html/index.html index daf9bad..b4cdfc5 100644 --- a/webui/html/index.html +++ b/webui/html/index.html @@ -60,14 +60,15 @@ diff --git a/webui/html/style.css b/webui/html/style.css index 0e3263c..654550a 100644 --- a/webui/html/style.css +++ b/webui/html/style.css @@ -295,7 +295,29 @@ button:disabled { #footer-bar { border-top: 1px solid var(--border); background: var(--panel); - padding: 4px 10px 2px 10px; + padding: 4px 10px 3px 10px; + display: flex; + flex-direction: column; + align-items: center; + gap: 3px; +} + +#function-bar-meta { + margin-bottom: 0; + justify-content: center; +} + +#function-bar { + margin-bottom: 0; + justify-content: center; + gap: 5px; + width: 100%; + max-width: 760px; +} + +#function-bar button { + min-width: 72px; + padding: 3px 8px; } .popup-overlay {