Refonte du système JDR + système de personnage joueurs / non joueurs :
Some checks failed
E2E Tests / e2e (push) Failing after 21s
Some checks failed
E2E Tests / e2e (push) Failing after 21s
- Système de templating dans le game system : en effet, les templates sont liés au game system car les fiches personnages ne sont pas forcément les même selon les jeux (perso Dnd possède + de compétences que Nimble par exemple) - changement des fiches personnages pour adapter le templating au niveau des campagnes et remplir des pages de perso
This commit is contained in:
@@ -90,6 +90,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Templates de fiches PJ/PNJ -->
|
||||
<div class="templates-area">
|
||||
<h2 class="sections-title">Fiches de personnages</h2>
|
||||
<p class="sections-hint">
|
||||
Definissez la structure des fiches PJ et PNJ pour ce systeme. Les champs
|
||||
universels (nom, portrait, header) sont automatiques — ne rajoutez ici
|
||||
que les champs specifiques au systeme (Histoire, PV, Stats…).
|
||||
</p>
|
||||
|
||||
<app-template-fields-editor
|
||||
label="Champs de la fiche PJ"
|
||||
hint="Affiches lors de la creation/edition d'un personnage joueur."
|
||||
[fields]="characterTemplate"
|
||||
[suggestions]="characterFieldSuggestions"
|
||||
(fieldsChange)="characterTemplate = $event">
|
||||
</app-template-fields-editor>
|
||||
|
||||
<app-template-fields-editor
|
||||
label="Champs de la fiche PNJ"
|
||||
hint="Affiches lors de la creation/edition d'un personnage non-joueur."
|
||||
[fields]="npcTemplate"
|
||||
[suggestions]="npcFieldSuggestions"
|
||||
(fieldsChange)="npcTemplate = $event">
|
||||
</app-template-fields-editor>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="button" class="btn-primary" [disabled]="!name.trim()" (click)="submit()">
|
||||
<lucide-icon [img]="Save" [size]="16"></lucide-icon>
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.templates-area {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.gse-header {
|
||||
margin-bottom: 2rem;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { LucideAngularModule, Save, ArrowLeft, Dices, Plus, Trash2, ChevronDown, ChevronRight } from 'lucide-angular';
|
||||
import { GameSystemService } from '../../services/game-system.service';
|
||||
import { TemplateField } from '../../services/template-field.model';
|
||||
import { TemplateFieldsEditorComponent } from '../../shared/template-fields-editor/template-fields-editor.component';
|
||||
|
||||
/**
|
||||
* Éditeur plein écran d'un GameSystem. Rôle double création/édition :
|
||||
@@ -31,10 +33,16 @@ const SUGGESTED_SECTIONS = [
|
||||
'Combat', 'Classes', 'Stats', 'Magie', 'Monstres', 'Progression'
|
||||
];
|
||||
|
||||
/** Suggestions de champs pour la fiche PJ — generiques (extension par template). */
|
||||
const CHARACTER_FIELD_SUGGESTIONS = ['Histoire', 'Personnalite', 'Apparence', 'Notes'];
|
||||
|
||||
/** Suggestions de champs pour la fiche PNJ — focus sur les besoins MJ. */
|
||||
const NPC_FIELD_SUGGESTIONS = ['Motivation', 'Apparence', 'Faction', 'Notes MJ'];
|
||||
|
||||
@Component({
|
||||
selector: 'app-game-system-edit',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, LucideAngularModule],
|
||||
imports: [CommonModule, FormsModule, LucideAngularModule, TemplateFieldsEditorComponent],
|
||||
templateUrl: './game-system-edit.component.html',
|
||||
styleUrls: ['./game-system-edit.component.scss']
|
||||
})
|
||||
@@ -53,8 +61,12 @@ export class GameSystemEditComponent implements OnInit {
|
||||
description = '';
|
||||
author = '';
|
||||
sections: RuleSection[] = [];
|
||||
characterTemplate: TemplateField[] = [];
|
||||
npcTemplate: TemplateField[] = [];
|
||||
|
||||
readonly suggestedSections = SUGGESTED_SECTIONS;
|
||||
readonly characterFieldSuggestions = CHARACTER_FIELD_SUGGESTIONS;
|
||||
readonly npcFieldSuggestions = NPC_FIELD_SUGGESTIONS;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@@ -71,6 +83,8 @@ export class GameSystemEditComponent implements OnInit {
|
||||
this.description = gs.description ?? '';
|
||||
this.author = gs.author ?? '';
|
||||
this.sections = this.parseMarkdown(gs.rulesMarkdown ?? '');
|
||||
this.characterTemplate = gs.characterTemplate ? [...gs.characterTemplate] : [];
|
||||
this.npcTemplate = gs.npcTemplate ? [...gs.npcTemplate] : [];
|
||||
},
|
||||
error: () => this.back()
|
||||
});
|
||||
@@ -104,11 +118,17 @@ export class GameSystemEditComponent implements OnInit {
|
||||
|
||||
submit(): void {
|
||||
if (!this.name.trim()) return;
|
||||
if (this.hasInvalidTemplateFields()) {
|
||||
console.warn('Champs templates invalides (noms vides ou doublons) — sauvegarde bloquee.');
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
name: this.name.trim(),
|
||||
description: this.description.trim() || null,
|
||||
author: this.author.trim() || null,
|
||||
rulesMarkdown: this.serializeMarkdown(),
|
||||
characterTemplate: this.characterTemplate,
|
||||
npcTemplate: this.npcTemplate,
|
||||
isPublic: false
|
||||
};
|
||||
const req = this.id
|
||||
@@ -124,6 +144,22 @@ export class GameSystemEditComponent implements OnInit {
|
||||
this.router.navigate(['/game-systems']);
|
||||
}
|
||||
|
||||
/** Validation cote front : nom vide ou doublons (case-insensitive). */
|
||||
private hasInvalidTemplateFields(): boolean {
|
||||
return this.hasInvalidList(this.characterTemplate) || this.hasInvalidList(this.npcTemplate);
|
||||
}
|
||||
|
||||
private hasInvalidList(fields: TemplateField[]): boolean {
|
||||
const seen = new Set<string>();
|
||||
for (const f of fields) {
|
||||
const name = f.name?.trim().toLowerCase();
|
||||
if (!name) return true;
|
||||
if (seen.has(name)) return true;
|
||||
seen.add(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Parse / Serialize markdown ------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user