Co-MJ v1 : quêtes de première classe, guidage de préparation, assistant IA,
All checks were successful
All checks were successful
mode séance, battlemaps multiples et export Foundry ciblé
- Quêtes (Niveau 1) : entité Quest orthogonale à l'arbre, rattachée à un arc HUB
ou libre (migrations V9-V12, V18, V20 ; réconciliation des jumeaux V10).
Fusion quête/conteneur dans la sidebar, progression par partie (statuts
disponible/en cours/terminée), et quêtes libres avec espace de scènes créé
automatiquement (arc technique « Quêtes libres », V21 : levée de la
contrainte arcs.type héritée du baseline).
- Guidage (Pilier B) : bilan de préparation 100 % dérivé (règles arc/chapitre/
scène/quête), panneau « Prochaines étapes » avec boutons « Corriger », et
pastilles détaillées (tooltip des manques) dans l'arbre.
- Assistant IA (Pilier A) : étoffage champ par champ (scène, chapitre, arc) et
brouillons de scènes en propose→applique (brain : narrative-fields,
scene-drafts).
- Horloges & menaces (V15-V17) : clocks à segments avec déclencheurs, fronts.
- Mode séance : préparation de séance (readiness + quêtes dispo), scène
épinglée (V19), récap « précédemment » (brain : session-recap), onglet
« Partie » du panneau de référence, graphe amélioré (pan/zoom, éditeur de
liens).
- Perf : endpoint agrégé GET /api/campaigns/{id}/tree — la sidebar charge en
1 requête au lieu de ~15.
- Battlemaps multiples par scène (variantes jour/nuit, étages…) : liste JSON
étiquetée (V22, reprise automatique de la carte existante), rendu PDF avec
légendes, export/import rétro-compatible.
- Export Foundry ciblé : modale de périmètre (cartes+ennemis / journaux /
tables), bundle filtré côté serveur (zip allégé), module Foundry à jour
(respect du périmètre + une Scene Foundry par variante de carte,
rétro-compatible anciens bundles).
This commit is contained in:
51
web/src/app/shared/node-picker/node-picker.component.html
Normal file
51
web/src/app/shared/node-picker/node-picker.component.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<div class="node-picker">
|
||||
|
||||
<div class="node-list">
|
||||
@for (n of nodes; track $index) {
|
||||
<div class="node-chip">
|
||||
<lucide-icon class="node-icon" [img]="n.nodeType === 'SCENE' ? MapPin : BookOpen" [size]="15"></lucide-icon>
|
||||
<span class="node-name">{{ nodeName(n) || ('nodePicker.deletedNode' | translate) }}</span>
|
||||
<span class="node-type">{{ (n.nodeType === 'SCENE' ? 'nodePicker.scene' : 'nodePicker.chapter') | translate }}</span>
|
||||
<button type="button" (click)="moveUp($index)" [disabled]="$index === 0" [title]="'nodePicker.moveUp' | translate">
|
||||
<lucide-icon [img]="ChevronUp" [size]="15"></lucide-icon>
|
||||
</button>
|
||||
<button type="button" (click)="moveDown($index)" [disabled]="$index === nodes.length - 1" [title]="'nodePicker.moveDown' | translate">
|
||||
<lucide-icon [img]="ChevronDown" [size]="15"></lucide-icon>
|
||||
</button>
|
||||
<button type="button" (click)="remove($index)" [title]="'nodePicker.remove' | translate">
|
||||
<lucide-icon [img]="X" [size]="15"></lucide-icon>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@if (nodes.length === 0) {
|
||||
<p class="empty-hint">{{ 'nodePicker.empty' | translate }}</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="add-row">
|
||||
<select [(ngModel)]="selectedChapterId" [attr.aria-label]="'nodePicker.selectChapter' | translate">
|
||||
<option value="">{{ 'nodePicker.selectChapter' | translate }}</option>
|
||||
@for (c of availableChapters; track c.id) {
|
||||
<option [value]="c.id">{{ c.name }}</option>
|
||||
}
|
||||
</select>
|
||||
<button type="button" class="btn-secondary" (click)="addChapter()" [disabled]="!selectedChapterId">
|
||||
<lucide-icon [img]="Plus" [size]="14"></lucide-icon>
|
||||
{{ 'nodePicker.addChapter' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="add-row">
|
||||
<select [(ngModel)]="selectedSceneId" [attr.aria-label]="'nodePicker.selectScene' | translate">
|
||||
<option value="">{{ 'nodePicker.selectScene' | translate }}</option>
|
||||
@for (s of availableScenes; track s.id) {
|
||||
<option [value]="s.id">{{ sceneOptionLabel(s) }}</option>
|
||||
}
|
||||
</select>
|
||||
<button type="button" class="btn-secondary" (click)="addScene()" [disabled]="!selectedSceneId">
|
||||
<lucide-icon [img]="Plus" [size]="14"></lucide-icon>
|
||||
{{ 'nodePicker.addScene' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user