forked from yvv/decision
Lot V, interface : les types du contrat (tallyPending, tallySimulated, myVoteState, vote.simulated, mode des bulletins, publication.waitsFor, messages « ballot ») ; i18n des états (simulé, écarté par une objection, messages d'un vote écarté) en fr, en, es ; la boîte « Messages » dit les votes écartés ; « Tes bulletins » marque un vote simulé
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,8 @@
|
||||
|
||||
function standing(b: BallotEntry): string {
|
||||
if (b.status === 'pending') return t('ballots.status.pending');
|
||||
// A vote of the simulation (ADR 0012): counted for the session, never on the chain.
|
||||
if (b.status === 'confirmed' && b.mode === 'simulated') return t('ballots.status.simulated', { name: b.voter ?? '' });
|
||||
if (b.status === 'confirmed') return t('ballots.status.confirmed', { name: b.voter ?? '' });
|
||||
if (b.status === 'refused') return t('ballots.status.refused', { reason: t(`ballot.reason.${b.reason ?? 'transfer'}`) });
|
||||
return t('ballots.status.expired');
|
||||
@@ -62,7 +64,7 @@
|
||||
{#each data.value.ballots as b (b.id)}
|
||||
<li class="card block ballot">
|
||||
<p class="small faint">{i18n.date(b.createdAt)} · {titleOf(b.doc.title)} · {i18n.plural('ballots.lines', b.lines)}</p>
|
||||
<p class="state {b.status}">
|
||||
<p class="state {b.status}" class:simulated={b.mode === 'simulated'}>
|
||||
{standing(b)}{#if b.block !== null}<span class="faint"> · {t('ballots.block', { n: i18n.number(b.block) })}</span>{/if}
|
||||
</p>
|
||||
<code class="comment">{b.comment}</code>
|
||||
@@ -159,7 +161,8 @@
|
||||
.state.confirmed {
|
||||
color: var(--moss);
|
||||
}
|
||||
.state.pending {
|
||||
.state.pending,
|
||||
.state.confirmed.simulated {
|
||||
color: var(--water);
|
||||
}
|
||||
.state.refused,
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// The box « Messages » of trustinWallet, in the application (2026-10-31, lot F,
|
||||
// ADR 0010): what waits for a gesture of the person — an objection to answer,
|
||||
// to lift or to reiterate, a typo fix to validate or refuse —, each with its
|
||||
// deadline. A message dealt with offers no gesture any more. No mail.
|
||||
// deadline. A message dealt with offers no gesture any more. No mail. A ballot set
|
||||
// aside (ADR 0012) is told here too, without gesture: one votes again in the text.
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { api } from '$lib/api';
|
||||
@@ -44,10 +45,27 @@
|
||||
await reload();
|
||||
}
|
||||
|
||||
/** The lines of a ballot a message is about: those set aside by an objection, or all. */
|
||||
function linesOf(m: Message) {
|
||||
const lines = m.ballot?.lines ?? [];
|
||||
const held = lines.filter((l) => l.outcome === 'objection');
|
||||
return m.kind === 'ballot_objection' && held.length ? held : lines;
|
||||
}
|
||||
|
||||
/** The text of a message, in the language of the reader, from its subject. */
|
||||
function textOf(m: Message): string {
|
||||
const o = m.objection;
|
||||
const fix = m.typo;
|
||||
const b = m.ballot;
|
||||
if (b) {
|
||||
const articles = linesOf(m)
|
||||
.map((l) => l.code)
|
||||
.join(', ');
|
||||
const date = i18n.date(b.createdAt);
|
||||
if (m.kind === 'ballot_expired') return t('messages.ballot_expired', { date, articles });
|
||||
if (m.kind === 'ballot_refused') return t('messages.ballot_refused', { date, articles, reason: t(`ballot.reason.${b.reason ?? 'transfer'}`) });
|
||||
return t('messages.ballot_objection', { articles });
|
||||
}
|
||||
if (o) {
|
||||
const held = o.heldVersion?.title ?? '';
|
||||
if (m.kind === 'objection_raised') return t(`messages.objection_raised.${o.kind}`, { name: o.objector ?? '', held, other: o.other.title ?? '' });
|
||||
@@ -73,6 +91,8 @@
|
||||
function hrefOf(m: Message): string {
|
||||
const v = m.objection?.heldVersion ?? m.typo?.version ?? null;
|
||||
const base = `/g/${m.doc.groupSlug}/docs/${m.doc.slug}`;
|
||||
const line = linesOf(m)[0];
|
||||
if (line) return `${base}?${panelSearch({ tab: 'details', unitId: line.unitId, proposalId: line.proposalId }, null)}`;
|
||||
if (!v) return base;
|
||||
return `${base}?${panelSearch({ tab: 'details', unitId: v.unitId ?? null, proposalId: v.id }, null)}`;
|
||||
}
|
||||
@@ -149,7 +169,7 @@
|
||||
<p class="text">{textOf(m)}</p>
|
||||
{#if m.objection?.reason && m.kind !== 'objection_answered'}<p class="reason">{m.objection.reason}</p>{/if}
|
||||
{#if m.typo}<DiffText parts={condense(m.typo.diff)} />{/if}
|
||||
{#if m.done}
|
||||
{#if m.done && m.topic !== 'ballot'}
|
||||
<p class="outcome">{outcomeOf(m)}</p>
|
||||
{:else if m.dueAt}
|
||||
<p class="due">{t('messages.due', { date: i18n.date(m.dueAt) })}</p>
|
||||
|
||||
Reference in New Issue
Block a user