v3 : modules d'ordre et de titre — l'interface, restes mineurs (L11, C25–C27)

Chaque section du lecteur finit par l'ordre de ses articles (inertie 2) : ses
articles numérotés, son vote déplié, « Proposer un autre ordre » — une liste où
l'on clique un article puis sa place, ses flèches, ou le clavier. Le titre du
document (inertie 4) se vote et se propose sous le titre, « traduction à
revoir » quand il a changé. Les deux sont dans la liste des propositions, le
panier et la chaîne Ğ1 ; un nouvel article se propose dans une section, à sa fin.
La liste du groupe compte les propositions ouvertes des modules.

Restes mineurs : la participation ramenée se dit en deux temps (la mesure, puis
ce que le groupe demande), les lignes « habituelle » des réglages resserrées, le
sélecteur d'inertie se parcourt aux flèches (le cran actuel atteignable, jamais
choisi), la marque « seed a minima » porte le vrai nombre de votes.

Contrôles : C25 (ordre, dont la chaîne et le téléphone), C26 (titre), C27
(participation ramenée) ; C3, C17 (41 modules), C20 mis à jour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-31 05:35:02 +01:00
co-authored by Claude Opus 5.5
parent 3831ddb1bf
commit 785580c78f
31 changed files with 1480 additions and 136 deletions
+25 -1
View File
@@ -9,7 +9,8 @@
import { api } from '$lib/api';
import type { DocState } from '$lib/doc.svelte';
import { i18n, t } from '$lib/i18n/index.svelte';
import { inertiaBadge, titleOf } from '$lib/labels';
import { inertiaBadge, orderNote, titleOf } from '$lib/labels';
import { moved } from '$lib/order';
import { toasts } from '$lib/toast.svelte';
import type { LevelInfo, Proposal, Unit } from '$lib/types';
import { errorText, g1Amount, voteDirect, type Line } from '$lib/vote';
@@ -55,6 +56,11 @@
const title = $derived(p.kind === 'text' ? p.title : titleOf(p, unit));
const voted = $derived(p.myVote !== null && !p.myVoteStale);
const ballot = $derived(p.myBallot);
// An order (ADR 0009): what one votes on is the list — the moves of a proposal marked.
const order = $derived(p.kind === 'order' ? p.order : undefined);
const shifted = $derived(order && p.status !== 'in_force' ? moved(unit.members ?? [], order.ids) : new Set<string>());
const source = $derived(view?.doc.sourceLang ?? 'fr');
const nameOf = (id: string) => doc.articleTitle(id, doc.original ? source : i18n.lang, source);
$effect(() => {
const id = p.id;
@@ -106,6 +112,12 @@
</div>
</div>
{#if p.blocked}<p class="warn">{t('vote.blocked')}</p>{/if}
{#if order}
<ol class="order" aria-label={t(p.status === 'in_force' ? 'module.order.inforce' : 'module.order.proposal')}>
{#each order.ids as id (id)}<li class:shifted={shifted.has(id)}>{nameOf(id)}</li>{/each}
</ol>
{#each orderNote(p) as note (note)}<p class="faint small">{note}</p>{/each}
{/if}
<div class="mine" aria-live="polite">
{#if ballot?.status === 'pending'}
@@ -190,6 +202,18 @@
.state {
font-weight: 700;
}
.order {
margin: 0;
padding-left: 1.6rem;
display: grid;
gap: 0.15rem;
font-size: 0.92rem;
color: var(--ink-soft);
}
.order .shifted {
color: var(--ink);
font-weight: 750;
}
.small {
font-size: 0.84rem;
}