diff --git a/docs/chantiers/acte-certification/CHANTIER.md b/docs/chantiers/acte-certification/CHANTIER.md index 3621648..7f9d863 100644 --- a/docs/chantiers/acte-certification/CHANTIER.md +++ b/docs/chantiers/acte-certification/CHANTIER.md @@ -35,7 +35,11 @@ les applications clientes (Cesium, Ğecko…) peuvent suivre. ouvrent un panneau latéral (une feuille sur mobile) dont l'état vit dans l'URL. 5. **En dessous**, les propositions en cours — les 30 autres articles du texte source, à zéro vote, inertie standard — rangées par section (introduction, fondamental, technique, - conclusion, annexes, formule, inertie, ordonnancement), les variantes signalées. + conclusion, annexes, formule, inertie, ordonnancement), **une ligne par article** : un + article qui a plusieurs versions (variantes du seed, propositions rivales) montre leur + nombre et la meilleure en tête (niveau d'eau, pour / contre) ; la ligne se déplie sur ses + versions, chacune avec son étiquette, son niveau et ses marques, et chacune ouvre son vote. + Les filtres gardent un article dès qu'une de ses versions passe. 6. **Deux aperçus** : « si les bien cotées passent » et « si tout passe ». 7. **Trois langues** : fr · en · es, pour l'interface comme pour le texte. Le français fait foi ; une traduction devenue ancienne (le français a changé depuis) est signalée. diff --git a/docs/chantiers/acte-certification/CONTROLES.md b/docs/chantiers/acte-certification/CONTROLES.md index f5eca6a..1690f5b 100644 --- a/docs/chantiers/acte-certification/CONTROLES.md +++ b/docs/chantiers/acte-certification/CONTROLES.md @@ -11,7 +11,7 @@ Où tester : les contrôles qui écrivent (C5, C6, C7) se font dans le **groupe |---|---|---|---| | C1 | L'accueil | ouvrir `/` sans être connectée | « Rendre possible la décision collective », la phrase d'outils, les quatre sections ; le menu à gauche avec les quatre outils, trois grisés ; « Se connecter avec sa clé Ğ1 » | | C2 | Les groupes | se connecter, ouvrir « Groupes » | Monnaie libre, Axiom, Librodrome, Groupe local Vallée Drôme Crestois ; **pas** l'Atelier du canal | -| C3 | Le texte en vigueur | Monnaie libre → Docs de référence → Acte d'engagement Certification | trois articles seulement (Raison d'être, Unicité du compte, Réciprocité), chacun « seed a minima · 0 vote » ; en dessous, « Propositions en cours » (32 lignes) | +| C3 | Le texte en vigueur | Monnaie libre → Docs de référence → Acte d'engagement Certification | trois articles seulement (Raison d'être, Unicité du compte, Réciprocité), chacun « seed a minima · 0 vote » ; en dessous, « Propositions en cours » (30 lignes, une par article) | | C4 | Gestes contextuels | survoler la Raison d'être → « Le vote » | un panneau : seuil 50 voix pour, il en manque 50 ; « La formule du seuil » se déplie ; l'URL garde le panneau ; Échap le ferme | | C5 | Entrée en vigueur | groupe d'essai : à deux, voter « Pour » sur « Les deux garanties réciproques » | au second vote, « … est entré en vigueur » ; le texte en vigueur compte quatre articles | | C6 | Coquille sans vote | groupe d'essai : Unicité du compte → « Le vote » → « Corriger une coquille », remplacer les apostrophes droites par des apostrophes typographiques (« Je m’engage sur l’honneur ») | « Coquille corrigée, sans toucher aux votes. » ; un changement de sens est refusé : « Ce changement touche au sens : propose-le comme modification. » | @@ -22,6 +22,7 @@ Où tester : les contrôles qui écrivent (C5, C6, C7) se font dans le **groupe | C11 | Une personne, une voix | avec un lien d'invitation, ouvrir le vote d'un article de Monnaie libre | « Ici, seuls les membres de la toile de confiance Ğ1 votent… » à la place des boutons ; dans le groupe d'essai, les boutons sont là | | C12 | Lien d'équipe | administrateur : `/acces` → « Liens d'équipe », cocher le groupe d'essai, créer ; l'ouvrir dans deux navigateurs, sous deux noms | chacun arrive sur ses groupes sous son nom ; dans `/acces`, « 2 / 30 personnes » et deux identités « venue par » le lien ; un nom déjà pris est refusé, même autrement écrit (« luna » pour « Luna ») ; sur un navigateur où quelqu'un est connecté, « Ce n'est pas moi » le déconnecte ; « Révoquer » ferme le lien | | C13 | La Raison d'être | Monnaie libre → Acte d'engagement Certification, puis EN, puis ES | en tête du texte en vigueur, « Raison d'être » : la première phrase en italique, puis deux paragraphes ; « Purpose », « Razón de ser » | +| C14 | Les versions d'un article | Monnaie libre → « Propositions en cours » → « Connaissance suffisante » (au clavier : Tab jusqu'à la ligne, Entrée) | une seule ligne, « 2 versions » ; dépliée : « variante 1.0.0 » et « variante 0.4.0-draft », chacune avec son niveau et ce qui la distingue ; un clic sur une version ouvre son vote ; un nouveau clic sur la ligne la replie | | M1 | Mobile | téléphone (ou fenêtre étroite) | menu en tiroir, les trois gestes visibles sans survol, le panneau s'ouvre en feuille | ## Au-delà de la liste diff --git a/web/e2e/reader.spec.ts b/web/e2e/reader.spec.ts index 37b072a..b01ae6e 100644 --- a/web/e2e/reader.spec.ts +++ b/web/e2e/reader.spec.ts @@ -33,7 +33,8 @@ test('C3 — le texte en vigueur : raison d’être et deux engagements, seed a await expect(units.nth(2).locator('h2')).toHaveText('Réciprocité'); await expect(page.getByText('seed a minima · 0 vote')).toHaveCount(3); await expect(page.getByRole('heading', { name: 'Propositions en cours' })).toBeVisible(); - await expect(page.locator('ul.deep button.row')).toHaveCount(32); + // One line per article: E3 and E7 hold their two variants inside. + await expect(page.locator('ul.deep button.row')).toHaveCount(30); }); test('C4 — les actions sont contextuelles, le vote s’ouvre en panneau', async ({ page }) => { @@ -147,13 +148,13 @@ test('C11 — une personne, une voix : dans Monnaie libre, seuls les membres de await invited.goto(`/invitation#${link.split('#')[1]}`); await expect(invited).toHaveURL(/\/groupes$/); await invited.goto(DOC); - await invited.locator('ul.deep button.row', { hasText: 'Connaissance suffisante' }).first().click(); + await invited.locator('ul.deep button.row', { hasText: 'Vérification personnelle de la clé' }).click(); const panel = invited.locator('aside.panel'); await expect(panel.getByText('Ici, seuls les membres de la toile de confiance Ğ1 votent', { exact: false })).toBeVisible(); await expect(panel.getByRole('button', { name: 'Pour', exact: true })).toHaveCount(0); // In the test group, the same person votes. await invited.goto(TEST_DOC); - await invited.locator('ul.deep button.row', { hasText: 'Connaissance suffisante' }).first().click(); + await invited.locator('ul.deep button.row', { hasText: 'Vérification personnelle de la clé' }).click(); await expect(invited.locator('aside.panel').getByRole('button', { name: 'Pour', exact: true })).toBeVisible(); }); @@ -205,3 +206,27 @@ test('C13 — la Raison d’être ouvre le texte en vigueur, en trois langues', await page.getByRole('radiogroup', { name: 'Text language' }).getByRole('radio', { name: 'ES' }).click(); await expect(first.locator('h2')).toHaveText('Razón de ser'); }); + +test('C14 — un article, une ligne : ses versions se déplient', async ({ page }) => { + await signIn(page, 'Chiara'); + await page.goto(DOC); + const e3 = page.locator('ul.deep button.row', { hasText: 'Connaissance suffisante' }); + await expect(e3).toHaveCount(1); + await expect(e3).toContainText('2 versions'); + await expect(e3).toHaveAttribute('aria-expanded', 'false'); + // Unfolded with the keyboard: its two versions, each with its label. + await e3.focus(); + await page.keyboard.press('Enter'); + await expect(e3).toHaveAttribute('aria-expanded', 'true'); + const versions = page.locator(`#${await e3.getAttribute('aria-controls')}`).getByRole('button'); + await expect(versions).toHaveCount(2); + await expect(versions.nth(0)).toContainText('variante 1.0.0'); + await expect(versions.nth(1)).toContainText('variante 0.4.0-draft'); + // A version opens its vote, as any proposal. + await versions.nth(1).click(); + await expect(page.locator('aside.panel').getByText('Seuil : 50 voix pour')).toBeVisible(); + await expect(page).toHaveURL(/version=/); + await e3.click(); + await expect(e3).toHaveAttribute('aria-expanded', 'false'); + await expect(versions).toHaveCount(0); +}); diff --git a/web/src/lib/components/DeepList.svelte b/web/src/lib/components/DeepList.svelte index c16b3d3..e09907a 100644 --- a/web/src/lib/components/DeepList.svelte +++ b/web/src/lib/components/DeepList.svelte @@ -1,45 +1,126 @@ +{#snippet marks(p: Proposal)} + {#if p.evaluation?.wellRated}{t('deep.wellrated')}{/if} + {#if p.blocked}{t('deep.blocked')}{/if} + {#if p.myVoteStale}{t('deep.stale')}{/if} + {#if p.mine}{t('deep.mine')}{/if} +{/snippet} +