Mise en place de l'export foundry ; modification des Arc, chapitres et scènes..... => Suppression de la section maps pour arc, chapitres ; et dans scène on importe les maps format foundry (image / vidéo + json)
All checks were successful
Build & Push Images / build (brain) (push) Successful in 1m35s
Build & Push Images / build (web) (push) Successful in 1m56s
Build & Push Images / build (core) (push) Successful in 3m37s
Build & Push Images / build-switcher (push) Successful in 19s

This commit is contained in:
2026-06-25 12:16:27 +02:00
parent 5bc038acd8
commit c0e1da78c8
72 changed files with 2274 additions and 223 deletions

View File

@@ -28,6 +28,10 @@
</div>
</div>
<div class="header-actions">
<button type="button" class="btn-secondary" (click)="exportFoundry()" [disabled]="exportingFoundry">
<lucide-icon [img]="Download" [size]="14"></lucide-icon>
{{ (exportingFoundry ? 'campaignDetail.foundryExporting' : 'campaignDetail.foundryExport') | translate }}
</button>
<button type="button" class="btn-secondary" (click)="startEdit()">
<lucide-icon [img]="Pencil" [size]="14"></lucide-icon>
{{ 'common.edit' | translate }}

View File

@@ -2,7 +2,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { LucideAngularModule, Swords, Plus, Globe, Pencil, Trash2, Dices, Drama, Check, Play, Upload, Sparkles } from 'lucide-angular';
import { LucideAngularModule, Swords, Plus, Globe, Pencil, Trash2, Dices, Drama, Check, Play, Upload, Sparkles, Download } from 'lucide-angular';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { Router, RouterLink } from '@angular/router';
import { forkJoin, of } from 'rxjs';
@@ -45,6 +45,10 @@ export class CampaignDetailComponent implements OnInit, OnDestroy {
readonly Play = Play;
readonly Upload = Upload;
readonly Sparkles = Sparkles;
readonly Download = Download;
/** Export Foundry en cours (anti double-clic). */
exportingFoundry = false;
campaign: Campaign | null = null;
arcs: Arc[] = [];
@@ -251,6 +255,33 @@ export class CampaignDetailComponent implements OnInit, OnDestroy {
this.router.navigate(['/campaigns', this.campaign.id, 'arcs', 'create']);
}
/** Télécharge le bundle Foundry de la campagne via un lien temporaire. */
exportFoundry(): void {
if (!this.campaign?.id || this.exportingFoundry) return;
this.exportingFoundry = true;
this.campaignService.exportFoundry(this.campaign.id).subscribe({
next: (blob) => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'foundry-export.zip';
// Certains navigateurs ignorent un click() sur un <a> détaché : on l'attache
// au DOM le temps du déclenchement, puis on nettoie.
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// Révocation différée : libère l'URL sans annuler le téléchargement en cours.
setTimeout(() => URL.revokeObjectURL(url), 1000);
this.exportingFoundry = false;
},
error: (err) => {
// Ne pas avaler l'erreur en silence : visible en console pour diagnostic.
console.error('Échec de l\'export Foundry', err);
this.exportingFoundry = false;
}
});
}
openArc(arc: Arc): void {
if (!this.campaign || !arc.id) return;
this.router.navigate(['/campaigns', this.campaign.id, 'arcs', arc.id]);