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

@@ -68,9 +68,6 @@ export interface Arc {
/** IDs des images (Shared Kernel) illustrant cet arc (ambiance). */
illustrationImageIds?: string[];
/** IDs des images utilisees comme cartes / plans (outil de table). */
mapImageIds?: string[];
}
// Payload pour la création d'un Arc (pas d'id)
@@ -90,7 +87,6 @@ export interface ArcCreate {
relatedPageIds?: string[];
illustrationImageIds?: string[];
mapImageIds?: string[];
}
export interface Chapter {
@@ -122,7 +118,6 @@ export interface Chapter {
relatedPageIds?: string[];
illustrationImageIds?: string[];
mapImageIds?: string[];
}
export interface ChapterCreate {
@@ -140,7 +135,6 @@ export interface ChapterCreate {
relatedPageIds?: string[];
illustrationImageIds?: string[];
mapImageIds?: string[];
}
/**
@@ -238,7 +232,13 @@ export interface Scene {
relatedPageIds?: string[];
illustrationImageIds?: string[];
mapImageIds?: string[];
/**
* Battlemap Foundry : ID du fichier media (image/video) + ID du sidecar JSON
* Universal VTT. Non affichee dans l'appli ; transportee a l'export Foundry.
*/
battlemapMediaFileId?: string | null;
battlemapDataFileId?: string | null;
/** Sorties narratives (graphe intra-chapitre). */
branches?: SceneBranch[];
@@ -268,7 +268,8 @@ export interface SceneCreate {
relatedPageIds?: string[];
illustrationImageIds?: string[];
mapImageIds?: string[];
battlemapMediaFileId?: string | null;
battlemapDataFileId?: string | null;
branches?: SceneBranch[];
rooms?: Room[];
}

View File

@@ -42,6 +42,11 @@ export class CampaignService {
return this.http.get<Campaign>(`${this.apiUrl}/${id}`);
}
/** Télécharge le bundle d'export Foundry de la campagne (.zip). */
exportFoundry(id: string): Observable<Blob> {
return this.http.get(`${this.apiUrl}/${id}/foundry-export`, { responseType: 'blob' });
}
createCampaign(campaign: CampaignCreate): Observable<Campaign> {
return this.http.post<Campaign>(this.apiUrl, campaign);
}

View File

@@ -0,0 +1,13 @@
// Interface TypeScript pour StoredFileDTO (Backend Java).
// Miroir de com.loremind.infrastructure.web.dto.files.StoredFileDTO.
// Fichier generique (battlemap : media video/image + sidecar JSON Universal VTT).
export interface StoredFile {
id: string;
filename: string;
contentType: string;
sizeBytes: number;
/** URL relative du binaire, ex: "/api/files/42/content". */
url: string;
uploadedAt: string;
}

View File

@@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { StoredFile } from './stored-file.model';
/**
* Service HTTP pour les fichiers generiques (/api/files).
* Pendant de {@link ImageService} pour les battlemaps : media (image/video) +
* sidecar JSON Universal VTT, qui sortent du perimetre des images (mp4, json,
* taille jusqu'a 128 Mo).
*/
@Injectable({ providedIn: 'root' })
export class StoredFileService {
readonly apiBase = '';
private apiUrl = `${this.apiBase}/api/files`;
constructor(private http: HttpClient) {}
/** Upload multipart/form-data. Le backend valide le MIME et la taille (128 Mo max). */
upload(file: File): Observable<StoredFile> {
const form = new FormData();
form.append('file', file);
return this.http.post<StoredFile>(this.apiUrl, form);
}
getById(id: string): Observable<StoredFile> {
return this.http.get<StoredFile>(`${this.apiUrl}/${id}`);
}
delete(id: string): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/${id}`);
}
/** URL absolue du binaire (peu utile : la battlemap n'est pas affichee). */
contentUrl(id: string): string {
return `${this.apiUrl}/${id}/content`;
}
}