forked from yvv/decision
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:
@@ -83,13 +83,25 @@ export class DocState {
|
||||
this.preview = r.units;
|
||||
}
|
||||
|
||||
/** The modules of the document (ADR 0009): its title, then the order of each section. */
|
||||
get modules(): Unit[] {
|
||||
const m = this.view?.modules;
|
||||
return m ? [...(m.title ? [m.title] : []), ...m.orders] : [];
|
||||
}
|
||||
|
||||
/** The order of a section, when it has something to decide (two articles or more). */
|
||||
orderOf(section: string | null): Unit | undefined {
|
||||
return this.view?.modules.orders.find((o) => o.section === section && !o.moot);
|
||||
}
|
||||
|
||||
/** An article or a module. */
|
||||
unit(id: string | null): Unit | undefined {
|
||||
return this.view?.units.find((u) => u.id === id);
|
||||
return this.view?.units.find((u) => u.id === id) ?? this.modules.find((u) => u.id === id);
|
||||
}
|
||||
|
||||
proposal(id: string | null): Proposal | undefined {
|
||||
if (!id || !this.view) return undefined;
|
||||
for (const u of this.view.units) {
|
||||
for (const u of [...this.view.units, ...this.modules]) {
|
||||
if (u.inForce?.id === id) return u.inForce;
|
||||
const p = u.proposals.find((x) => x.id === id);
|
||||
if (p) return p;
|
||||
@@ -101,15 +113,57 @@ export class DocState {
|
||||
return (this.view?.units ?? []).filter((u) => u.inForce);
|
||||
}
|
||||
|
||||
/** Open proposals, in document order; drafts apart. */
|
||||
/**
|
||||
* Articles and modules in document order (ADR 0009): the title first, then the
|
||||
* articles of each section followed by its order, when it has something to decide.
|
||||
*/
|
||||
get ordered(): Unit[] {
|
||||
const m = this.view?.modules;
|
||||
const out: Unit[] = m?.title ? [m.title] : [];
|
||||
const units = this.view?.units ?? [];
|
||||
units.forEach((u, i) => {
|
||||
out.push(u);
|
||||
if (units[i + 1]?.section === u.section) return;
|
||||
const order = this.orderOf(u.section);
|
||||
if (order) out.push(order);
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* The text in force by section, each closed by its order (ADR 0009) — shown even
|
||||
* where no article is in force yet, as long as it has something to decide.
|
||||
*/
|
||||
get inForceBySection(): { section: string | null; units: Unit[]; order: Unit | undefined }[] {
|
||||
const out: { section: string | null; units: Unit[]; order: Unit | undefined }[] = [];
|
||||
for (const u of this.view?.units ?? []) {
|
||||
let last = out.at(-1);
|
||||
if (!last || last.section !== u.section) {
|
||||
last = { section: u.section, units: [], order: this.orderOf(u.section) };
|
||||
out.push(last);
|
||||
}
|
||||
if (u.inForce) last.units.push(u);
|
||||
}
|
||||
return out.filter((s) => s.units.length || s.order);
|
||||
}
|
||||
|
||||
/** Open proposals, of articles and modules, in document order; drafts apart. */
|
||||
get open(): { unit: Unit; proposal: Proposal }[] {
|
||||
const out: { unit: Unit; proposal: Proposal }[] = [];
|
||||
for (const unit of this.view?.units ?? []) {
|
||||
for (const unit of this.ordered) {
|
||||
for (const proposal of unit.proposals) if (proposal.status === 'open') out.push({ unit, proposal });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** The title of an article as it is read: its text in force, else its latest open text. */
|
||||
articleTitle(id: string, lang: Lang, source: Lang): string {
|
||||
const u = this.view?.units.find((x) => x.id === id);
|
||||
if (!u) return id;
|
||||
const v = u.inForce ?? u.proposals.findLast((p) => p.status === 'open' && p.kind === 'text');
|
||||
return v ? shown(v, lang, source).title : u.code;
|
||||
}
|
||||
|
||||
get drafts(): { unit: Unit; proposal: Proposal }[] {
|
||||
const out: { unit: Unit; proposal: Proposal }[] = [];
|
||||
for (const unit of this.view?.units ?? []) {
|
||||
|
||||
Reference in New Issue
Block a user