mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Refactor/275 actor sheets simplification (#291)
* FEAT: create isNPC geeter and add the prop on metada on actors FEAT: create common method for documents sheets FEAT: create BaseActorSheet and implementation * FIX: tabs label * REFACTOR: remove unused methods REFACTOR: simplify CharacterSheet's click actions methods REFACTOR: minor fix on DHActor class * REFACTOR: remove unused methods REFACTOR: create method on BaseActorSheet REFACTOR: make Datamodel metadata getter * REFACTOR: remove unused method on setting sheet FEAT: create BaseActorSetting FIX: add type="button" to button on actor's sheet * FIX jsdoc * PRETTIER --------- Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com>
This commit is contained in:
parent
7d7fb88035
commit
87b3677956
34 changed files with 723 additions and 1253 deletions
|
|
@ -1,3 +1,5 @@
|
|||
export { default as DHApplicationMixin } from './application-mixin.mjs';
|
||||
export { default as DHBaseItemSheet } from './base-item.mjs';
|
||||
export { default as DHHeritageSheet } from './heritage-sheet.mjs';
|
||||
export { default as DHBaseActorSheet } from './base-actor.mjs';
|
||||
export { default as DHBaseActorSettings } from './actor-setting.mjs';
|
||||
|
|
|
|||
50
module/applications/sheets/api/actor-setting.mjs
Normal file
50
module/applications/sheets/api/actor-setting.mjs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import DHApplicationMixin from './application-mixin.mjs';
|
||||
const { DocumentSheetV2 } = foundry.applications.api;
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
||||
/**
|
||||
* Base settings sheet for Daggerheart actors.
|
||||
* @extends {DHApplicationMixin<DocumentSheetV2>}
|
||||
*/
|
||||
export default class DHBaseActorSettings extends DHApplicationMixin(DocumentSheetV2) {
|
||||
/**@inheritdoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['dialog'],
|
||||
window: {
|
||||
icon: 'fa-solid fa-wrench',
|
||||
resizable: false,
|
||||
title: 'DAGGERHEART.GENERAL.Tabs.settings'
|
||||
},
|
||||
position: { width: 455, height: 'auto' },
|
||||
actions: {},
|
||||
form: {
|
||||
submitOnChange: true
|
||||
},
|
||||
dragDrop: [
|
||||
{ dragSelector: null, dropSelector: '.tab.features' },
|
||||
{ dragSelector: '.feature-item', dropSelector: null }
|
||||
]
|
||||
};
|
||||
|
||||
/** @inheritDoc */
|
||||
_initializeApplicationOptions(options) {
|
||||
options = super._initializeApplicationOptions(options);
|
||||
options.classes = options.classes.filter(c => c !== 'sheet');
|
||||
return options;
|
||||
}
|
||||
|
||||
/**@returns {foundry.documents.Actor} */
|
||||
get actor() {
|
||||
return this.document;
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
context.systemFields.attack.fields = this.actor.system.attack.schema.fields;
|
||||
context.isNPC = this.actor.isNPC;
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,14 @@ import { tagifyElement } from '../../../helpers/utils.mjs';
|
|||
* @property {string} [dragSelector] - A CSS selector that identifies draggable elements.
|
||||
* @property {string} [dropSelector] - A CSS selector that identifies drop targets.
|
||||
*
|
||||
* @typedef {object} ContextMenuConfig
|
||||
* @property {() => ContextMenuEntry[]} handler - A handler function that provides initial context options
|
||||
* @property {string} selector - A CSS selector to which the ContextMenu will be bound
|
||||
* @property {object} [options] - Additional options which affect ContextMenu construction
|
||||
* @property {HTMLElement} [options.container] - A parent HTMLElement which contains the selector target
|
||||
* @property {string} [options.hookName] - The hook name
|
||||
* @property {boolean} [options.parentClassHooks=true] - Whether to call hooks for the parent classes in the inheritance chain.
|
||||
*
|
||||
* @typedef {Object} TagOption
|
||||
* @property {string} label
|
||||
* @property {string} [src]
|
||||
|
|
@ -24,9 +32,17 @@ import { tagifyElement } from '../../../helpers/utils.mjs';
|
|||
*
|
||||
* @typedef {Object} TagifyOptions
|
||||
* @property {number} [maxTags] - Maximum number of allowed tags
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import("@client/applications/api/handlebars-application.mjs").HandlebarsRenderOptions} HandlebarsRenderOptions
|
||||
* @typedef {foundry.applications.types.ApplicationConfiguration & HandlebarsRenderOptions & { dragDrop?: DragDropConfig[], tagifyConfigs?: TagifyConfig[] }} DHSheetV2Configuration
|
||||
* @typedef {foundry.applications.types.ApplicationConfiguration} FoundryAppConfig
|
||||
*
|
||||
* @typedef {FoundryAppConfig & HandlebarsRenderOptions & {
|
||||
* dragDrop?: DragDropConfig[],
|
||||
* tagifyConfigs?: TagifyConfig[],
|
||||
* contextMenus?: ContextMenuConfig[],
|
||||
* }} DHSheetV2Configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -54,15 +70,12 @@ export default function DHApplicationMixin(Base) {
|
|||
*/
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart', 'sheet', 'dh-style'],
|
||||
position: {
|
||||
width: 480,
|
||||
height: 'auto'
|
||||
},
|
||||
actions: {
|
||||
addEffect: DHSheetV2.#addEffect,
|
||||
editEffect: DHSheetV2.#editEffect,
|
||||
removeEffect: DHSheetV2.#removeEffect
|
||||
createDoc: DHSheetV2.#createDoc,
|
||||
editDoc: DHSheetV2.#editDoc,
|
||||
deleteDoc: DHSheetV2.#deleteDoc
|
||||
},
|
||||
contextMenus: [],
|
||||
dragDrop: [],
|
||||
tagifyConfigs: []
|
||||
};
|
||||
|
|
@ -74,6 +87,11 @@ export default function DHApplicationMixin(Base) {
|
|||
super._attachPartListeners(partId, htmlElement, options);
|
||||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
}
|
||||
/**@inheritdoc */
|
||||
async _onFirstRender(context, options) {
|
||||
await super._onFirstRender(context, options);
|
||||
if (!!this.options.contextMenus.length) this._createContextMenus();
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _onRender(context, options) {
|
||||
|
|
@ -81,6 +99,10 @@ export default function DHApplicationMixin(Base) {
|
|||
this._createTagifyElements(this.options.tagifyConfigs);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Tags */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Creates Tagify elements from configuration objects
|
||||
* @param {TagifyConfig[]} tagConfigs - Array of Tagify configuration objects
|
||||
|
|
@ -150,22 +172,38 @@ export default function DHApplicationMixin(Base) {
|
|||
_onDrop(event) {}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Prepare Context */
|
||||
/* Context Menu */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
_createContextMenus() {
|
||||
for (const config of this.options.contextMenus) {
|
||||
const { handler, selector, options } = config;
|
||||
this._createContextMenu(handler.bind(this), selector, options);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Prepare the template context.
|
||||
* @param {object} options
|
||||
* @param {string} [objectPath='document']
|
||||
* @returns {Promise<object>}
|
||||
* @inheritdoc
|
||||
* Get the set of ContextMenu options which should be used for journal entry pages in the sidebar.
|
||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]}
|
||||
* @protected
|
||||
*/
|
||||
async _prepareContext(options, objectPath = 'document') {
|
||||
_getEntryContextOptions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Prepare Context */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**@inheritdoc*/
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
context.config = CONFIG.DH;
|
||||
context.source = this[objectPath];
|
||||
context.fields = this[objectPath].schema.fields;
|
||||
context.systemFields = this[objectPath].system ? this[objectPath].system.schema.fields : {};
|
||||
context.source = this.document;
|
||||
context.fields = this.document.schema.fields;
|
||||
context.systemFields = this.document.system.schema.fields;
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -174,37 +212,45 @@ export default function DHApplicationMixin(Base) {
|
|||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Renders an ActiveEffect's sheet sheet.
|
||||
* Create an embedded document.
|
||||
* @param {PointerEvent} event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeAction"]
|
||||
*/
|
||||
static async #addEffect() {
|
||||
const cls = foundry.documents.ActiveEffect;
|
||||
await cls.create(
|
||||
{
|
||||
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize(cls.metadata.label) })
|
||||
},
|
||||
{ parent: this.document }
|
||||
static async #createDoc(event, button) {
|
||||
const { documentClass, type } = button.dataset;
|
||||
console.log(documentClass, type);
|
||||
const parent = this.document;
|
||||
|
||||
const cls = getDocumentClass(documentClass);
|
||||
return await cls.createDocuments(
|
||||
[
|
||||
{
|
||||
name: cls.defaultName({ type, parent }),
|
||||
type
|
||||
}
|
||||
],
|
||||
{ parent, renderSheet: !event.shiftKey }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an ActiveEffect's sheet sheet.
|
||||
* Renders an embedded document.
|
||||
* @param {PointerEvent} event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeAction"]
|
||||
*/
|
||||
static async #editEffect(_event, button) {
|
||||
const effect = this.document.effects.get(button.dataset.effect);
|
||||
effect.sheet.render({ force: true });
|
||||
static #editDoc(_event, button) {
|
||||
const { type, docId } = button.dataset;
|
||||
this.document.getEmbeddedDocument(type, docId, { strict: true }).sheet.render({ force: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an ActiveEffect from the item.
|
||||
* Delete an embedded document.
|
||||
* @param {PointerEvent} _event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeAction"]
|
||||
*/
|
||||
static async #removeEffect(_event, button) {
|
||||
await this.document.effects.get(button.dataset.effect).delete();
|
||||
static async #deleteDoc(_event, button) {
|
||||
const { type, docId } = button.dataset;
|
||||
await this.document.getEmbeddedDocument(type, docId, { strict: true }).delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
52
module/applications/sheets/api/base-actor.mjs
Normal file
52
module/applications/sheets/api/base-actor.mjs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import DHBaseActorSettings from './actor-setting.mjs';
|
||||
import DHApplicationMixin from './application-mixin.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
||||
/**
|
||||
* A base actor sheet extending {@link ActorSheetV2} via {@link DHApplicationMixin}
|
||||
* @extends ActorSheetV2
|
||||
* @mixes DHSheetV2
|
||||
*/
|
||||
export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['actor'],
|
||||
position: {
|
||||
width: 480
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true
|
||||
},
|
||||
actions: {
|
||||
openSettings: DHBaseActorSheet.#openSettings
|
||||
},
|
||||
dragDrop: []
|
||||
};
|
||||
|
||||
/**@type {typeof DHBaseActorSettings}*/
|
||||
#settingSheet;
|
||||
|
||||
/**@returns {DHBaseActorSettings|null} */
|
||||
get settingSheet() {
|
||||
const SheetClass = this.document.system.metadata.settingSheet;
|
||||
return (this.#settingSheet ??= SheetClass ? new SheetClass({ document: this.document }) : null);
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.isNPC = this.document.isNPC;
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the Actor Setting Sheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #openSettings() {
|
||||
await this.settingSheet.render({ force: true });
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ import DHApplicationMixin from './application-mixin.mjs';
|
|||
|
||||
const { ItemSheetV2 } = foundry.applications.sheets;
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
||||
/**
|
||||
* A base item sheet extending {@link ItemSheetV2} via {@link DHApplicationMixin}
|
||||
* @extends ItemSheetV2
|
||||
|
|
@ -92,8 +94,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Add a new action to the item, prompting the user for its type.
|
||||
* @param {PointerEvent} _event - The originating click event
|
||||
* @param {HTMLElement} _button - The capturing HTML element which defines the [data-action="addAction"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #addAction(_event, _button) {
|
||||
const actionType = await DHBaseItemSheet.selectActionType();
|
||||
|
|
@ -124,8 +125,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Edit an existing action on the item
|
||||
* @param {PointerEvent} _event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="editAction"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #editAction(_event, button) {
|
||||
const action = this.document.system.actions[button.dataset.index];
|
||||
|
|
@ -134,8 +134,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Remove an action from the item.
|
||||
* @param {PointerEvent} event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeAction"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #removeAction(event, button) {
|
||||
event.stopPropagation();
|
||||
|
|
@ -147,8 +146,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Add a new feature to the item, prompting the user for its type.
|
||||
* @param {PointerEvent} _event - The originating click event
|
||||
* @param {HTMLElement} _button - The capturing HTML element which defines the [data-action="addFeature"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #addFeature(_event, _button) {
|
||||
const feature = await game.items.documentClass.create({
|
||||
|
|
@ -162,8 +160,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Edit an existing feature on the item
|
||||
* @param {PointerEvent} _event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="editFeature"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #editFeature(_event, button) {
|
||||
const target = button.closest('.feature-item');
|
||||
|
|
@ -178,8 +175,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
|
||||
/**
|
||||
* Remove a feature from the item.
|
||||
* @param {PointerEvent} event - The originating click event
|
||||
* @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeFeature"]
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #removeFeature(event, button) {
|
||||
event.stopPropagation();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue