fix(migration): StatusEffects + SystemCompendiums -> ApplicationV2

Plus aucun FormApplication V1 dans module/settings/.
- Tous les settings menus migrés vers HandlebarsApplicationMixin(ApplicationV2)
- Templates sans wrapper <form>
- Scrollbar via LESS pour #status-effects et #system-compendiums
- Listeners jQuery -> DOM natif dans _onRender
This commit is contained in:
fabres
2026-07-22 00:29:56 +02:00
parent 70092ffd8f
commit 54fc1e8e1a
6 changed files with 67 additions and 89 deletions
+5 -1
View File
@@ -4902,9 +4902,13 @@ body {
.system-foundryvtt-reve-de-dragon .window-app.regles-optionnelles > .window-content, .system-foundryvtt-reve-de-dragon .window-app.regles-optionnelles > .window-content,
.system-foundryvtt-reve-de-dragon .window-app.dialog-encaissement-tables > .window-content, .system-foundryvtt-reve-de-dragon .window-app.dialog-encaissement-tables > .window-content,
.system-foundryvtt-reve-de-dragon .window-app.options-avancees > .window-content, .system-foundryvtt-reve-de-dragon .window-app.options-avancees > .window-content,
.system-foundryvtt-reve-de-dragon .window-app.status-effects > .window-content,
.system-foundryvtt-reve-de-dragon .window-app.system-compendiums > .window-content,
.system-foundryvtt-reve-de-dragon #regles-optionnelles > .window-content, .system-foundryvtt-reve-de-dragon #regles-optionnelles > .window-content,
.system-foundryvtt-reve-de-dragon #dialog-encaissement-tables > .window-content, .system-foundryvtt-reve-de-dragon #dialog-encaissement-tables > .window-content,
.system-foundryvtt-reve-de-dragon #options-avancees > .window-content { .system-foundryvtt-reve-de-dragon #options-avancees > .window-content,
.system-foundryvtt-reve-de-dragon #status-effects > .window-content,
.system-foundryvtt-reve-de-dragon #system-compendiums > .window-content {
overflow-y: auto; overflow-y: auto;
} }
.system-foundryvtt-reve-de-dragon .encaissement-tables { .system-foundryvtt-reve-de-dragon .encaissement-tables {
+5 -1
View File
@@ -77,9 +77,13 @@
.window-app.regles-optionnelles > .window-content, .window-app.regles-optionnelles > .window-content,
.window-app.dialog-encaissement-tables > .window-content, .window-app.dialog-encaissement-tables > .window-content,
.window-app.options-avancees > .window-content, .window-app.options-avancees > .window-content,
.window-app.status-effects > .window-content,
.window-app.system-compendiums > .window-content,
#regles-optionnelles > .window-content, #regles-optionnelles > .window-content,
#dialog-encaissement-tables > .window-content, #dialog-encaissement-tables > .window-content,
#options-avancees > .window-content { #options-avancees > .window-content,
#status-effects > .window-content,
#system-compendiums > .window-content {
overflow-y: auto; overflow-y: auto;
} }
+30 -38
View File
@@ -2,6 +2,8 @@ import { RDD_CONFIG, SYSTEM_RDD } from "../constants.js";
import { Misc } from "../misc.js"; import { Misc } from "../misc.js";
import { RdDBonus } from "../rdd-bonus.js"; import { RdDBonus } from "../rdd-bonus.js";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export const STATUSES = { export const STATUSES = {
StatusGrappling: 'grappling', StatusGrappling: 'grappling',
StatusGrappled: 'grappled', StatusGrappled: 'grappled',
@@ -46,7 +48,7 @@ const rddStatusEffects = [
const statusDemiSurprise = new Set([STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained, STATUSES.StatusForceWeak]) const statusDemiSurprise = new Set([STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained, STATUSES.StatusForceWeak])
const statusSurpriseTotale = new Set([STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma]) const statusSurpriseTotale = new Set([STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma])
export class StatusEffects extends FormApplication { export class StatusEffects extends HandlebarsApplicationMixin(ApplicationV2) {
static onReady() { static onReady() {
const rddEffectIds = rddStatusEffects.map(it => it.id) const rddEffectIds = rddStatusEffects.map(it => it.id)
@@ -151,51 +153,41 @@ export class StatusEffects extends FormApplication {
return demiReveStatusEffect; return demiReveStatusEffect;
} }
constructor(...args) { static DEFAULT_OPTIONS = {
super(...args); tag: "form",
id: "status-effects",
classes: ["rdd-dialog", "status-effects"],
form: { submitOnChange: false, closeOnSubmit: true },
position: { width: 350, height: 800 },
window: { title: "Choix des status/effets", icon: "fa-solid fa-bars" }
} }
static get defaultOptions() { static PARTS = {
const options = super.defaultOptions; form: { template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.hbs" }
foundry.utils.mergeObject(options, {
id: "status-effects",
template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.hbs",
classes: ["rdd-dialog", "status-effects"],
height: 800,
width: 350,
minimizable: false,
closeOnSubmit: true,
title: "Choix des status/effets"
});
return options;
} }
getData() { async _prepareContext() {
const used = StatusEffects._getUseStatusEffects(); const used = StatusEffects._getUseStatusEffects();
let formData = super.getData(); const effects = foundry.utils.duplicate(CONFIG.RDD.allEffects);
formData.effects = foundry.utils.duplicate(CONFIG.RDD.allEffects); effects.forEach(it => it.active = used.includes(it.id))
formData.effects.forEach(it => it.active = used.includes(it.id)) return { effects }
return formData;
} }
activateListeners(html) { async _onRender(context, options) {
$(html).find(".select-effect").click((event) => { this.element.querySelectorAll(".select-effect").forEach(el => {
let id = event.currentTarget.attributes.name?.value; el.addEventListener("click", async event => {
if (id) { let id = event.currentTarget.getAttribute("name");
let selected = StatusEffects._getUseStatusEffects(); if (id) {
let isChecked = event.currentTarget.checked; let selected = StatusEffects._getUseStatusEffects();
if (isChecked) { let isChecked = event.currentTarget.checked;
selected.push(id); if (isChecked) {
selected.push(id);
} else {
selected = selected.filter(it => it != id)
}
StatusEffects._setUseStatusEffects(selected);
} }
else { });
selected = selected.filter(it => it != id)
}
StatusEffects._setUseStatusEffects(selected);
}
}); });
} }
async _updateObject(event, formData) {
this.close();
}
} }
+23 -45
View File
@@ -6,6 +6,8 @@ import { Misc } from "../misc.js";
import { RdDDice } from "../rdd-dice.js"; import { RdDDice } from "../rdd-dice.js";
import { ReglesOptionnelles } from "./regles-optionnelles.js"; import { ReglesOptionnelles } from "./regles-optionnelles.js";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
const COMPENDIUM_SETTING_PREFIX = 'compendium-'; const COMPENDIUM_SETTING_PREFIX = 'compendium-';
const CONFIGURABLE_COMPENDIUMS = { const CONFIGURABLE_COMPENDIUMS = {
@@ -24,10 +26,7 @@ const CONFIGURABLE_COMPENDIUMS = {
'equipement': { label: "Equipements", type: "Item" }, 'equipement': { label: "Equipements", type: "Item" },
} }
/** export class SystemCompendiums extends HandlebarsApplicationMixin(ApplicationV2) {
* ======= Gestion des accès aux compendiums systèmes (ou surchargés) =======
*/
export class SystemCompendiums extends FormApplication {
static initSettings() { static initSettings() {
Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => { Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
const definition = CONFIGURABLE_COMPENDIUMS[compendium]; const definition = CONFIGURABLE_COMPENDIUMS[compendium];
@@ -85,7 +84,6 @@ export class SystemCompendiums extends FormApplication {
return [] return []
} }
/* -------------------------------------------- */
static async getWorldOrCompendiumItems(itemType, compendium) { static async getWorldOrCompendiumItems(itemType, compendium) {
let items = game.items.filter(it => it.type == itemType) let items = game.items.filter(it => it.type == itemType)
if (compendium) { if (compendium) {
@@ -118,19 +116,16 @@ export class SystemCompendiums extends FormApplication {
return elements; return elements;
} }
/* -------------------------------------------- */
static async loadCompendiumData(compendium) { static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium); const pack = game.packs.get(compendium);
return await pack?.getDocuments() ?? []; return await pack?.getDocuments() ?? [];
} }
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) { static async loadCompendium(compendium, filter = item => true) {
let compendiumData = await SystemCompendiums.loadCompendiumData(compendium); let compendiumData = await SystemCompendiums.loadCompendiumData(compendium);
return compendiumData.filter(filter); return compendiumData.filter(filter);
} }
static async getDefaultItems(compendium) { static async getDefaultItems(compendium) {
const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium)); const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
if (pack.metadata.type == 'Item') { if (pack.metadata.type == 'Item') {
@@ -152,25 +147,20 @@ export class SystemCompendiums extends FormApplication {
return `${SYSTEM_RDD}.${compendium}`; return `${SYSTEM_RDD}.${compendium}`;
} }
constructor(...args) { static DEFAULT_OPTIONS = {
super(...args); tag: "form",
id: "system-compendiums",
classes: ["system-compendiums"],
form: { submitOnChange: false, closeOnSubmit: true },
position: { width: 600, height: "auto" },
window: { title: "Compendiums système", icon: "fa-solid fa-bars" }
} }
static get defaultOptions() { static PARTS = {
const options = super.defaultOptions; form: { template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.hbs" }
foundry.utils.mergeObject(options, {
id: "system-compendiums",
template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.hbs",
height: 'fit-content',
width: 600,
minimizable: false,
closeOnSubmit: true,
title: "Compendiums système"
});
return options;
} }
getData() { async _prepareContext() {
const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS) const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS)
.map(it => foundry.utils.mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }, { inplace: false })) .map(it => foundry.utils.mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }, { inplace: false }))
const availableCompendiums = game.packs.map(pack => { const availableCompendiums = game.packs.map(pack => {
@@ -180,26 +170,21 @@ export class SystemCompendiums extends FormApplication {
type: pack.metadata.type type: pack.metadata.type
} }
}); });
return foundry.utils.mergeObject(super.getData(), { return { systemCompendiums, availableCompendiums }
systemCompendiums: systemCompendiums,
availableCompendiums: availableCompendiums
}, { inplace: false })
} }
activateListeners(html) { async _onRender(context, options) {
$(html).find("select.system-compendium-setting").change((event) => { this.element.querySelectorAll("select.system-compendium-setting").forEach(el => {
const compendium = $(event.currentTarget).data('compendium') el.addEventListener("change", async event => {
const value = $(event.currentTarget).val(); const compendium = event.currentTarget.dataset.compendium
const systemCompendium = CONFIGURABLE_COMPENDIUMS[compendium]; const value = event.currentTarget.value;
const systemCompendium = CONFIGURABLE_COMPENDIUMS[compendium];
game.settings.set(SYSTEM_RDD, systemCompendium.setting, value); await game.settings.set(SYSTEM_RDD, systemCompendium.setting, value);
});
}); });
} }
} }
/**
* ======= Gestion de jets dans une table correspondant à un compendium =======
*/
export class CompendiumTable { export class CompendiumTable {
constructor(compendium, type, subTypes = undefined, sorting = undefined) { constructor(compendium, type, subTypes = undefined, sorting = undefined) {
@@ -234,9 +219,6 @@ export class CompendiumTable {
} }
} }
/**
* ======= Gestion de tables correspondant à un compendium =======
*/
export class CompendiumTableHelpers { export class CompendiumTableHelpers {
static buildTable(elements, itemFrequence) { static buildTable(elements, itemFrequence) {
@@ -272,7 +254,6 @@ export class CompendiumTableHelpers {
return await CompendiumTableHelpers.selectRow(table, forcedRoll); return await CompendiumTableHelpers.selectRow(table, forcedRoll);
} }
/* -------------------------------------------- */
static async selectRow(table, forcedRoll = undefined) { static async selectRow(table, forcedRoll = undefined) {
if (table.length == 0) { if (table.length == 0) {
return undefined return undefined
@@ -289,7 +270,6 @@ export class CompendiumTableHelpers {
return row; return row;
} }
/* -------------------------------------------- */
static async tableRowToChatMessage(row, type, options = {}) { static async tableRowToChatMessage(row, type, options = {}) {
if (options.showSource == undefined){ if (options.showSource == undefined){
options.showSource = ReglesOptionnelles.isUsing('afficher-table-source') options.showSource = ReglesOptionnelles.isUsing('afficher-table-source')
@@ -314,7 +294,6 @@ export class CompendiumTableHelpers {
{ rollMode: options.rollMode })) { rollMode: options.rollMode }))
} }
/* -------------------------------------------- */
static async tableToChatMessage(table, type, subTypes, typeName = undefined) { static async tableToChatMessage(table, type, subTypes, typeName = undefined) {
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.hbs', { const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.hbs', {
img: RdDItem.getDefaultImg(subTypes[0]), img: RdDItem.getDefaultImg(subTypes[0]),
@@ -330,5 +309,4 @@ export class CompendiumTableHelpers {
} }
)) ))
} }
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
<form autocomplete="off" onsubmit="event.preventDefault();"> <div>
<ul> <ul>
{{#each effects as |effect key|}} {{#each effects as |effect key|}}
<li > <li >
@@ -12,5 +12,5 @@
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
</form> </div>
+2 -2
View File
@@ -1,4 +1,4 @@
<form autocomplete="off" onsubmit="event.preventDefault();"> <div>
<ul> <ul>
{{#each systemCompendiums as |definition key|}} {{#each systemCompendiums as |definition key|}}
<li class="flexrow"> <li class="flexrow">
@@ -15,5 +15,5 @@
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
</form> </div>