53 lines
2.1 KiB
TypeScript
53 lines
2.1 KiB
TypeScript
// « Info ouverture doc de réf. » (lot U3; Yvv, 2026-11-03: « un petit chapitre qui explicite les
|
|
// réglages initiaux de l'auteur, notamment Quorum et Inertie »): what the chapter says is read in
|
|
// the data of the document, never written in. Pure: the component only says it.
|
|
|
|
import type { DocView, Inertia, Unit } from './types';
|
|
|
|
/**
|
|
* The level a module opened at: the one before the first change voted. A change of the seed's own
|
|
* settings (an amendment, « réglage de départ du texte ») is the author's, part of the opening.
|
|
*/
|
|
export function openedAt(u: Unit): Inertia {
|
|
const voted = u.inertiaChanges.find((c) => c.cause === 'vote');
|
|
return voted?.from ?? u.inertia;
|
|
}
|
|
|
|
/** A Proposition d'amorce (ADR 0011): put forward by the seed, open or in force since. */
|
|
export function isAmorce(u: Unit): boolean {
|
|
return [u.inForce, ...u.proposals].some((p) => p?.seedFeatured === true);
|
|
}
|
|
|
|
/** An article the seed wrote (the author's): not one a member proposed since. */
|
|
function fromSeed(u: Unit): boolean {
|
|
return [u.inForce, ...u.proposals].some((p) => p?.origin === 'seed');
|
|
}
|
|
|
|
const levels = (units: (Unit | null | undefined)[]): Inertia[] =>
|
|
[...new Set(units.filter((u): u is Unit => !!u).map(openedAt))].sort((a, b) => a - b);
|
|
|
|
export interface OpeningLevels {
|
|
amorce: Inertia[];
|
|
title: Inertia[];
|
|
orders: Inertia[];
|
|
others: Inertia[];
|
|
}
|
|
|
|
/** The levels at the opening, by kind of module, each said once, lowest first. */
|
|
export function openingLevels(view: Pick<DocView, 'units' | 'modules'>): OpeningLevels {
|
|
const seeded = view.units.filter(fromSeed);
|
|
return {
|
|
amorce: levels(seeded.filter(isAmorce)),
|
|
title: levels([view.modules.title]),
|
|
orders: levels(view.modules.orders),
|
|
others: levels(seeded.filter((u) => !isAmorce(u))),
|
|
};
|
|
}
|
|
|
|
/** The quorum of each level, 1 to 5 (ADR 0013): said once when they are all the same. */
|
|
export function quorumsOf(quorums: number[] | undefined): { same: number | null; list: number[] } | null {
|
|
if (!quorums?.length) return null;
|
|
const first = quorums[0] ?? 0;
|
|
return { same: quorums.every((q) => q === first) ? first : null, list: quorums };
|
|
}
|