Possibilité d'importer un template de monstre depuis le systeme qu'on utilise sur Foundry pour forcer le template. Lors de l'export, le monstre est automatiquement adapté comme ça.
All checks were successful
All checks were successful
à l'import des monstres depuis foundry : on garde la structure originelle utilisée sur foundry également
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
<div class="picker">
|
||||
|
||||
<!-- Chips des ennemis déjà liés -->
|
||||
@if (linkedEnemies.length > 0) {
|
||||
<!-- Chips des ennemis déjà liés (avec quantité) -->
|
||||
@if (linkedGroups.length > 0) {
|
||||
<div class="linked-chips">
|
||||
@for (e of linkedEnemies; track e.id) {
|
||||
@for (g of linkedGroups; track g.enemy.id) {
|
||||
<span class="chip">
|
||||
<a
|
||||
class="chip-label"
|
||||
[href]="enemyUrl(e.id!)"
|
||||
[href]="enemyUrl(g.enemy.id!)"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
[title]="'enemyLinkPicker.openInNewTab' | translate">
|
||||
<lucide-icon [img]="Skull" [size]="12"></lucide-icon>
|
||||
{{ label(e) }}
|
||||
{{ label(g.enemy) }}
|
||||
</a>
|
||||
<button type="button" class="chip-remove" (click)="remove(e.id!)" [title]="'enemyLinkPicker.removeLink' | translate">
|
||||
<span class="chip-qty">
|
||||
<button type="button" class="chip-step" (click)="decrement(g.enemy.id!)" [title]="'enemyLinkPicker.decrement' | translate">−</button>
|
||||
<span class="chip-count">×{{ g.count }}</span>
|
||||
<button type="button" class="chip-step" (click)="increment(g.enemy.id!)" [title]="'enemyLinkPicker.increment' | translate">+</button>
|
||||
</span>
|
||||
<button type="button" class="chip-remove" (click)="remove(g.enemy.id!)" [title]="'enemyLinkPicker.removeLink' | translate">
|
||||
<lucide-icon [img]="X" [size]="12"></lucide-icon>
|
||||
</button>
|
||||
</span>
|
||||
|
||||
@@ -33,6 +33,32 @@
|
||||
&:hover { color: #fecdd3; }
|
||||
}
|
||||
|
||||
.chip-qty {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-left: 1px solid #2a2a3d;
|
||||
|
||||
.chip-step {
|
||||
width: 1.4rem;
|
||||
padding: 0.25rem 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1;
|
||||
opacity: 0.8;
|
||||
&:hover { opacity: 1; background: #2a2a3d; color: #fecdd3; }
|
||||
}
|
||||
|
||||
.chip-count {
|
||||
min-width: 1.6rem;
|
||||
text-align: center;
|
||||
font-variant-numeric: tabular-nums;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.chip-remove {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -44,11 +44,20 @@ export class EnemyLinkPickerComponent {
|
||||
/** true tant que l'input a le focus (pour afficher le dropdown). */
|
||||
dropdownOpen = false;
|
||||
|
||||
/** Ennemis actuellement liés (résolus en objets complets pour affichage). */
|
||||
get linkedEnemies(): Enemy[] {
|
||||
return this.value
|
||||
.map(id => this.availableEnemies.find(e => e.id === id))
|
||||
.filter((e): e is Enemy => !!e);
|
||||
/**
|
||||
* Ennemis liés groupés AVEC leur quantité (le même id peut apparaître N fois
|
||||
* dans `value` → N tokens à l'export). Ordre = première apparition.
|
||||
*/
|
||||
get linkedGroups(): { enemy: Enemy; count: number }[] {
|
||||
const counts = new Map<string, number>();
|
||||
const order: string[] = [];
|
||||
for (const id of this.value) {
|
||||
if (!counts.has(id)) order.push(id);
|
||||
counts.set(id, (counts.get(id) ?? 0) + 1);
|
||||
}
|
||||
return order
|
||||
.map(id => ({ enemy: this.availableEnemies.find(e => e.id === id), count: counts.get(id)! }))
|
||||
.filter((g): g is { enemy: Enemy; count: number } => !!g.enemy);
|
||||
}
|
||||
|
||||
/** Ennemis proposables dans le dropdown — filtrés par query, exclut les déjà liés. */
|
||||
@@ -66,14 +75,28 @@ export class EnemyLinkPickerComponent {
|
||||
return level ? `${enemy.name} (${level})` : enemy.name;
|
||||
}
|
||||
|
||||
/** Ajoute un ennemi aux liens. */
|
||||
/** Ajoute un ennemi aux liens (première occurrence). */
|
||||
add(enemy: Enemy): void {
|
||||
if (!enemy.id || this.value.includes(enemy.id)) return;
|
||||
if (!enemy.id) return;
|
||||
this.valueChange.emit([...this.value, enemy.id]);
|
||||
this.query = '';
|
||||
}
|
||||
|
||||
/** Retire un ennemi des liens. */
|
||||
/** +1 du même ennemi (un token de plus à l'export). */
|
||||
increment(enemyId: string): void {
|
||||
this.valueChange.emit([...this.value, enemyId]);
|
||||
}
|
||||
|
||||
/** −1 du même ennemi (retire UNE occurrence). */
|
||||
decrement(enemyId: string): void {
|
||||
const i = this.value.indexOf(enemyId);
|
||||
if (i < 0) return;
|
||||
const next = [...this.value];
|
||||
next.splice(i, 1);
|
||||
this.valueChange.emit(next);
|
||||
}
|
||||
|
||||
/** Retire TOUTES les occurrences de cet ennemi. */
|
||||
remove(enemyId: string): void {
|
||||
this.valueChange.emit(this.value.filter(id => id !== enemyId));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user