Lot U : le lecteur refait — l'ordre en une ligne au bout de sa section, poignées sur place (Reorder), le titre et l'ordre votés à leur place ; Propositions seed en tête quand rien n'est en vigueur ; Propositions en cours repliées par section ; panneau sans onglets ; oui pour passer · non pour bloquer ; quorum de l'auteur ; votes simulés dits simulés
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,49 +1,60 @@
|
||||
<script lang="ts">
|
||||
// The title of the document is a module (ADR 0009, inertia 4): under the title,
|
||||
// the gestures of an article — the vote, the proposals, another title.
|
||||
// The title of the document is a module (ADR 0009, inertia 4): one line under the title,
|
||||
// of the same voice as the order of a section — its weight in notches, its state, the
|
||||
// titles proposed. « Le vote » unfolds here the vote of any of its versions; another title
|
||||
// is written in the panel.
|
||||
import type { Snippet } from 'svelte';
|
||||
import { i18n, t } from '$lib/i18n/index.svelte';
|
||||
import { inertiaBadge, moduleName } from '$lib/labels';
|
||||
import type { Unit } from '$lib/types';
|
||||
import { moduleName } from '$lib/labels';
|
||||
import type { Proposal, Unit } from '$lib/types';
|
||||
import Crans from './Crans.svelte';
|
||||
|
||||
let {
|
||||
unit,
|
||||
stale = false,
|
||||
selected = false,
|
||||
voteOpen = false,
|
||||
vote,
|
||||
fold,
|
||||
onaction,
|
||||
onvote,
|
||||
onpropose,
|
||||
}: {
|
||||
/** The title module of the document. */
|
||||
unit: Unit;
|
||||
/** The title read is a translation of an older title. */
|
||||
stale?: boolean;
|
||||
selected?: boolean;
|
||||
voteOpen?: boolean;
|
||||
fold?: Snippet;
|
||||
onaction: (action: 'vote' | 'proposals' | 'propose') => void;
|
||||
/** The version whose vote is unfolded, wherever it lives. */
|
||||
vote: string | null;
|
||||
fold: Snippet<[Proposal]>;
|
||||
onvote: (proposalId: string) => void;
|
||||
onpropose: () => void;
|
||||
} = $props();
|
||||
|
||||
const p = $derived(unit.inForce);
|
||||
const votes = $derived((p?.tally.for ?? 0) + (p?.tally.against ?? 0));
|
||||
const rivals = $derived(unit.proposals.filter((x) => x.status === 'open' && x.kind === 'title').length);
|
||||
const proposed = $derived(unit.proposals.filter((x) => x.status === 'open' && x.kind === 'title'));
|
||||
const shown = $derived([p, ...unit.proposals.filter((x) => x.status === 'open')].find((x) => x?.id === vote) ?? null);
|
||||
</script>
|
||||
|
||||
<div class="title-unit" class:selected class:unfolded={voteOpen}>
|
||||
<div class="title-unit" class:selected class:unfolded={!!shown} role="group" aria-label={moduleName(unit)}>
|
||||
<p class="bar">
|
||||
<span class="status faint">
|
||||
{moduleName(unit)} · {inertiaBadge(unit.inertia)}
|
||||
{moduleName(unit)}
|
||||
{#if p?.seedMinimal} · <span title={t('doc.seed.long')}>{i18n.plural('doc.seed.votes', votes)}</span>
|
||||
{:else if p?.enteredAt} · {t('doc.adopted', { date: i18n.date(p.enteredAt) })}{/if}
|
||||
</span>
|
||||
<Crans level={unit.inertia} />
|
||||
{#if stale}<span class="tag ochre">{t('doc.lang.stale')}</span>{/if}
|
||||
{#if proposed.length}
|
||||
{@const first = proposed[0]}
|
||||
<button type="button" class="proposed" onclick={() => first && onvote(first.id)}>{i18n.plural('title.proposed', proposed.length)}</button>
|
||||
{/if}
|
||||
<span class="links">
|
||||
<button type="button" class:on={voteOpen} aria-expanded={voteOpen} aria-controls={p ? `vote-${p.id}` : undefined} onclick={() => onaction('vote')}>{t('doc.action.vote')}</button>
|
||||
<button type="button" onclick={() => onaction('proposals')}>{t('doc.action.proposals')}{#if rivals > 0}{` · ${rivals}`}{/if}</button>
|
||||
<button type="button" onclick={() => onaction('propose')}>{t('title.propose')}</button>
|
||||
{#if p}<button type="button" class:on={shown?.id === p.id} aria-expanded={shown?.id === p.id} aria-controls="vote-{p.id}" onclick={() => onvote(p.id)}>{t('doc.action.vote')}</button>{/if}
|
||||
<button type="button" onclick={onpropose}>{t('title.propose')}</button>
|
||||
</span>
|
||||
</p>
|
||||
{#if voteOpen && fold}<div class="fold">{@render fold()}</div>{/if}
|
||||
{#if shown}<div class="fold">{@render fold(shown)}</div>{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -65,11 +76,23 @@
|
||||
align-items: center;
|
||||
gap: 0.3rem 0.8rem;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 700;
|
||||
color: var(--ink-soft);
|
||||
min-height: 2.25rem;
|
||||
}
|
||||
.status {
|
||||
font-weight: 700;
|
||||
}
|
||||
.proposed {
|
||||
border: 0;
|
||||
background: var(--water-wash);
|
||||
color: var(--water);
|
||||
font-weight: 750;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.25rem 0.7rem;
|
||||
min-height: 2rem;
|
||||
border-radius: var(--r-pill);
|
||||
}
|
||||
.links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -105,6 +128,12 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 899px) {
|
||||
.links button,
|
||||
.proposed {
|
||||
min-height: 2.75rem;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.title-unit,
|
||||
.links {
|
||||
|
||||
Reference in New Issue
Block a user