The working screens of an evening. The home screen lists the events of the working folder, asks its question, loads demos, copies, renames, imports and deletes, and shows what the trash holds. An open event frames its mode, offers Modifier, Débloquer and a confirmed lock takeover, and shows its warnings. Participants get a grid, a form and a file; an import goes through a preview and a report; tables, the default and tours have their screens; the plan draws tables, chairs, empty seats and names. Checked: 2342 node, 356 browser, 60 node-long; the Electron start check. --- FR --- [ADD] interface : liste, événement, participants, import, tables, plan Les écrans de travail d'une soirée. L'accueil liste les événements du dossier de travail, pose sa question, charge les démonstrations, copie, renomme, importe et supprime, et montre ce que tient la corbeille. Un événement ouvert encadre son mode, offre Modifier, Débloquer et une reprise de verrou confirmée, et montre ses avertissements. Les participants ont une grille, un formulaire et une fiche ; un import passe par un aperçu et un rapport ; tables, défaut et tours ont leurs écrans ; le plan dessine tables, chaises, sièges vides et noms. Vérifié : 2342 node, 356 navigateur, 60 node-long ; démarrage d'Electron. Assisted-by: Claude Opus 5.5
193 lines
6 KiB
Svelte
193 lines
6 KiB
Svelte
<!-- © 2026 TechnoLibre (http://www.technolibre.ca)
|
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
|
|
|
<svelte:options namespace="svg" />
|
|
|
|
<script>
|
|
// Une table du plan (§ 7.1, § 7.3, § 7.5, § 7.6) : le groupe [data-table],
|
|
// qui ne porte que le plateau et les chaises, avec les marques posées sur
|
|
// eux ; puis, frères du groupe, la poignée [data-poignee] et la pastille
|
|
// [data-pastille]. Tout vient de la TableDessin du modèle (modele.js) ; le
|
|
// composant ne calcule rien.
|
|
//
|
|
// En régime table, les chaises ne se dessinent pas : l'emprise entière se
|
|
// peint au fond de la chaise et devient la seule cible, sous le plateau.
|
|
// En régime sièges, chaque chaise est un groupe [data-siege="table:siège"]
|
|
// dont seul le disque reçoit le pointeur : ses marques, comme la pastille,
|
|
// ont pointer-events: none, et la cible d'une chaise est le disque même que
|
|
// la désignation lit (designation.js).
|
|
//
|
|
// Une table en conflit, quand le plan signale, porte un contour épaissi
|
|
// (contourConflit) et une trame (trameConflit) par-dessus son plateau ; sa
|
|
// pastille porte le nombre de violations, signalée ou non (§ 7.5).
|
|
import { getContext } from 'svelte';
|
|
import { RAYON_POIGNEE } from '../../geometrie/tables.js';
|
|
import {
|
|
CADENAS_FERME,
|
|
CADENAS_OUVERT,
|
|
ECART_ANNEAU,
|
|
ECART_MISE_EN_EVIDENCE,
|
|
RAYON_PASTILLE,
|
|
TAILLE_TEXTE_PASTILLE_CM,
|
|
TRACE_GEL,
|
|
formesTable,
|
|
} from './modele.js';
|
|
|
|
let { table, signaler, prefixe } = $props();
|
|
|
|
const t = getContext('t');
|
|
|
|
// La marque que porte le disque d'une chaise, selon son remplissage.
|
|
const MARQUE_DU_REMPLISSAGE = { normal: 'contourChaise', plein: 'remplissagePlein', hachure: 'hachure' };
|
|
const TRACE_DU_CADENAS = { cadenasFerme: CADENAS_FERME, cadenasOuvert: CADENAS_OUVERT };
|
|
|
|
const formes = $derived(formesTable(table.geometrie));
|
|
const poignee = $derived(table.geometrie.poignee);
|
|
const signal = $derived(signaler && table.conflit);
|
|
const hachure = $derived(`url(#${prefixe}-hachure)`);
|
|
const trame = $derived(`url(#${prefixe}-trame)`);
|
|
</script>
|
|
|
|
<g data-table={table.id} role="group" aria-label={t(table.nomAccessible.cle, table.nomAccessible.details)}>
|
|
{#if table.regime === 'table'}
|
|
{#if formes.ronde}
|
|
<circle class="emprise" data-marque="contourChaise" {...formes.emprise} />
|
|
{:else}
|
|
<rect class="emprise" data-marque="contourChaise" {...formes.emprise} />
|
|
{/if}
|
|
{/if}
|
|
{#if formes.ronde}
|
|
<circle class="plateau" class:conflit={signal} data-marque={signal ? 'contourConflit' : 'contourTable'} {...formes.plateau} />
|
|
{:else}
|
|
<rect class="plateau" class:conflit={signal} data-marque={signal ? 'contourConflit' : 'contourTable'} {...formes.plateau} />
|
|
{/if}
|
|
{#if signal}
|
|
{#if formes.ronde}
|
|
<circle class="trame" data-marque="trameConflit" fill={trame} {...formes.plateau} />
|
|
{:else}
|
|
<rect class="trame" data-marque="trameConflit" fill={trame} {...formes.plateau} />
|
|
{/if}
|
|
{/if}
|
|
{#if table.gelee}
|
|
<path class="gel" data-marque="gel" d={TRACE_GEL} transform="translate({formes.gel.x},{formes.gel.y})" />
|
|
{/if}
|
|
{#each table.chaises as chaise (chaise.siege)}
|
|
<g data-siege="{table.id}:{chaise.siege}">
|
|
<circle
|
|
class="chaise"
|
|
class:pleine={chaise.remplissage === 'plein'}
|
|
data-marque={MARQUE_DU_REMPLISSAGE[chaise.remplissage]}
|
|
style:fill={chaise.remplissage === 'hachure' ? hachure : null}
|
|
cx={chaise.x}
|
|
cy={chaise.y}
|
|
r={chaise.rayon}
|
|
/>
|
|
{#each chaise.marques as marque (marque)}
|
|
{#if marque === 'anneau'}
|
|
<circle class="anneau" data-marque="anneau" cx={chaise.x} cy={chaise.y} r={chaise.rayon + ECART_ANNEAU} />
|
|
{:else}
|
|
<path class="cadenas" data-marque={marque} d={TRACE_DU_CADENAS[marque]} transform="translate({chaise.x},{chaise.y})" />
|
|
{/if}
|
|
{/each}
|
|
{#if chaise.miseEnEvidence}
|
|
<circle class="evidence" data-marque="miseEnEvidence" cx={chaise.x} cy={chaise.y} r={chaise.rayon + ECART_MISE_EN_EVIDENCE} />
|
|
{/if}
|
|
</g>
|
|
{/each}
|
|
</g>
|
|
<circle class="poignee" data-poignee={table.id} data-marque="poignee" cx={poignee.x} cy={poignee.y} r={RAYON_POIGNEE} />
|
|
{#if table.pastille > 0}
|
|
<g class="pastille" data-pastille={table.id}>
|
|
<circle class="disque" data-marque="pastille" cx={formes.pastille.x} cy={formes.pastille.y} r={RAYON_PASTILLE} />
|
|
<text
|
|
class="nombre"
|
|
x={formes.pastille.x}
|
|
y={formes.pastille.y}
|
|
font-size={TAILLE_TEXTE_PASTILLE_CM}
|
|
text-anchor="middle"
|
|
dominant-baseline="central">{table.pastille}</text>
|
|
</g>
|
|
{/if}
|
|
|
|
<style>
|
|
/* Les traits gardent leur épaisseur à l'écran, à tout zoom (§ 7.2). */
|
|
.emprise,
|
|
.plateau,
|
|
.chaise,
|
|
.poignee {
|
|
vector-effect: non-scaling-stroke;
|
|
stroke-width: 1.5;
|
|
}
|
|
|
|
.emprise {
|
|
fill: var(--couleur-chaise-fond);
|
|
stroke: var(--couleur-chaise-trait);
|
|
}
|
|
|
|
.plateau {
|
|
fill: var(--couleur-table-fond);
|
|
stroke: var(--couleur-table-trait);
|
|
}
|
|
|
|
.plateau.conflit {
|
|
stroke: var(--couleur-conflit);
|
|
stroke-width: 4;
|
|
}
|
|
|
|
.trame {
|
|
stroke: none;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.gel {
|
|
fill: var(--couleur-gel);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.chaise {
|
|
fill: var(--couleur-chaise-fond);
|
|
stroke: var(--couleur-chaise-trait);
|
|
}
|
|
|
|
.chaise.pleine {
|
|
fill: var(--couleur-chaise-pleine);
|
|
}
|
|
|
|
.anneau {
|
|
fill: none;
|
|
stroke: var(--couleur-marque);
|
|
stroke-width: 4;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cadenas {
|
|
fill: var(--couleur-marque);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.evidence {
|
|
fill: none;
|
|
stroke: var(--couleur-mise-en-evidence);
|
|
stroke-width: 4;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.poignee {
|
|
fill: var(--couleur-poignee);
|
|
stroke: var(--couleur-poignee);
|
|
}
|
|
|
|
.pastille {
|
|
pointer-events: none;
|
|
}
|
|
|
|
.disque {
|
|
fill: var(--couleur-pastille-fond);
|
|
}
|
|
|
|
.nombre {
|
|
fill: var(--couleur-pastille-texte);
|
|
font-family: var(--police-interface);
|
|
font-weight: 700;
|
|
}
|
|
</style>
|