forked from yvv/decision
v3 : interface des objections, des coquilles validées et de la messagerie ; contrôles C28–C31
Une version retenue par une objection le dit sous l'article, à chacun selon son rôle : la personne qui vote voit qu'elle ne se vote plus (les votes faits restent) ; l'auteur, quoi faire (« Modifier l'article visé » pour une redite, « Reformuler » pour une contradiction) ; la personne qui objecte, lever ou réitérer avant l'échéance. Le panier la montre sans choix et ne l'envoie jamais. « Détails » : faire une objection (redit / contredit), les objections et où elles en sont, les coquilles proposées par d'autres avec leur diff resserré, valider / refuser / revenir, l'historique dit qui a validé. Une coquille se propose sur toute version ouverte ou en vigueur. Boîte « Messages » dans le menu, avec le nombre de non-lus (pastille sur le bouton du menu en mobile) : objet, texte, gestes, échéance ; un message traité n'a plus de geste. Répondre à une objection lit son message. Trilingue (fr, en, es). C6 suit la règle : la coquille d'un administrateur sur un texte du seed passe tout de suite ; C28–C31 couvrent le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+12
-4
@@ -17,6 +17,8 @@ export interface Slot {
|
||||
versions: Proposal[];
|
||||
/** Open changes of its inertia: another question, never filled by a grouped gesture. */
|
||||
inertia: Proposal[];
|
||||
/** Versions held back by an objection: shown, not votable until it is lifted (ADR 0010). */
|
||||
held: Proposal[];
|
||||
}
|
||||
|
||||
export interface Section {
|
||||
@@ -32,12 +34,13 @@ export function sections(units: Unit[]): Section[] {
|
||||
const open = unit.proposals.filter((p) => p.status === 'open');
|
||||
const versions = [
|
||||
...(unit.inForce?.status === 'in_force' ? [unit.inForce] : []),
|
||||
...open.filter((p) => p.kind !== 'inertia'),
|
||||
...open.filter((p) => p.kind !== 'inertia' && p.votable !== false),
|
||||
];
|
||||
const inertia = open.filter((p) => p.kind === 'inertia');
|
||||
if (!versions.length && !inertia.length) continue;
|
||||
const held = open.filter((p) => p.kind !== 'inertia' && p.votable === false);
|
||||
if (!versions.length && !inertia.length && !held.length) continue;
|
||||
const last = out.at(-1);
|
||||
const slot = { unit, versions, inertia };
|
||||
const slot = { unit, versions, inertia, held };
|
||||
if (last && last.key === unit.section) last.slots.push(slot);
|
||||
else out.push({ key: unit.section, slots: [slot] });
|
||||
}
|
||||
@@ -59,9 +62,14 @@ export function waiting(slots: Slot[], picks: Picks): Slot[] {
|
||||
return slots.filter((s) => s.versions.length > 1 && !s.versions.some((p) => p.id in picks));
|
||||
}
|
||||
|
||||
/** The versions one may vote now: those a choice of the basket is sent for. */
|
||||
export function votableIds(all: Section[]): Set<string> {
|
||||
return new Set(all.flatMap((s) => s.slots.flatMap((x) => [...x.versions, ...x.inertia].map((p) => p.id))));
|
||||
}
|
||||
|
||||
/** Empties the basket of these articles only. */
|
||||
export function clearScope(slots: Slot[], picks: Picks): Picks {
|
||||
const ids = new Set(slots.flatMap((s) => [...s.versions, ...s.inertia].map((p) => p.id)));
|
||||
const ids = new Set(slots.flatMap((s) => [...s.versions, ...s.inertia, ...s.held].map((p) => p.id)));
|
||||
return Object.fromEntries(Object.entries(picks).filter(([id]) => !ids.has(id)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user