From 58588b9dbd2fd3b7d2a63bf91f299f58dd842c6a Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 14 Oct 2026 07:39:02 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20une=20zone=20de=20d=C3=A9p=C3=B4t?= =?UTF-8?q?=20par=20cible,=20pause=20globale=20(#10,=20#11,=20#13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - une zone de dépôt par cible à la place du menu déroulant, avec pastille de catégorie sur chaque fichier quand il y a plusieurs cibles (#11) - un seul sélecteur : le doublon « Parcourir un dossier » disparaît, les dossiers passent par glisser-déposer (#10) - bouton « Tout mettre en pause / Tout reprendre » à côté de « Tout annuler » (#13) Co-Authored-By: Claude Sonnet 5.5 --- public/upload.html | 252 ++++++++++++++++++++++++-------------------- tests/pages.test.ts | 19 +++- 2 files changed, 153 insertions(+), 118 deletions(-) diff --git a/public/upload.html b/public/upload.html index ca1afe6..a0acdb0 100644 --- a/public/upload.html +++ b/public/upload.html @@ -110,7 +110,7 @@ color: var(--text); font: inherit; } - #dropzone { + .dropzone { border: 2px dashed var(--border); border-radius: 10px; padding: 2.5rem 1rem; @@ -122,15 +122,32 @@ background 0.15s, opacity 0.15s; } - #dropzone.hover { + .dropzone.hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); color: var(--text); } - #dropArea { + .dropzone strong { + color: var(--text); + } + #zones { display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.25rem; } + .queue-actions { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + } + .badge { + flex: none; + font-size: 0.75rem; + padding: 0.05rem 0.5rem; + border-radius: 999px; + border: 1px solid var(--accent); + color: var(--accent); + } #list { display: grid; grid-template-columns: minmax(0, 1fr); @@ -250,28 +267,14 @@ - - -
-
- Déposez fichiers ou dossiers ici
- ou cliquez pour parcourir - -
- - -
+
@@ -279,16 +282,11 @@ diff --git a/tests/pages.test.ts b/tests/pages.test.ts index b13df50..0ea0f81 100644 --- a/tests/pages.test.ts +++ b/tests/pages.test.ts @@ -54,7 +54,7 @@ describe('GET /', () => { expect(res.statusCode).toBe(200); expect(res.headers['content-type']).toContain('text/html'); expect(res.body).toContain('href="/auth/login"'); - expect(res.body).not.toContain('id="dropzone"'); + expect(res.body).not.toContain('id="zones"'); expect(res.body).not.toContain('Se déconnecter'); }); @@ -68,7 +68,7 @@ describe('GET /', () => { expect(res.statusCode).toBe(200); expect(res.body).toContain('Connecté : Alice'); expect(res.body).toContain('Se déconnecter'); - expect(res.body).toContain('id="dropzone"'); + expect(res.body).toContain('id="zones"'); expect(res.body).not.toContain('{{USER_NAME}}'); expect(res.body).not.toContain('href="/auth/login"'); }); @@ -86,6 +86,19 @@ describe('GET /', () => { expect(res.body).not.toContain('max-width: 640px'); }); + it('page de dépôt : une zone par cible, plus de menu déroulant ni de second sélecteur', async () => { + const cookie = await login(app, idp); + const res = await app.inject({ + method: 'GET', + url: '/', + cookies: { [SESSION_COOKIE]: cookie }, + }); + expect(res.body).toContain('id="zones"'); + expect(res.body).toContain('id="queuePause"'); + expect(res.body).not.toContain('targetSelect'); + expect(res.body).not.toContain('dirPicker'); + }); + it('échappe le nom d’utilisateur avant de l’insérer dans le HTML', async () => { const cookie = await login(app, idp, { name: '' }); const res = await app.inject({ @@ -105,6 +118,6 @@ describe('GET /', () => { }); expect(res.statusCode).toBe(200); expect(res.body).toContain('href="/auth/login"'); - expect(res.body).not.toContain('id="dropzone"'); + expect(res.body).not.toContain('id="zones"'); }); });