diff --git a/lang/en.json b/lang/en.json index 868ee74b..f19b69db 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1028,6 +1028,13 @@ } }, "Sheets": { + "TABS": { + "features": "Features", + "effects": "Effects", + "settings": "Settings", + "actions": "Actions", + "description": "Description" + }, "PC": { "Name": "Name", "Pronouns": "Pronouns", diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 65eafe09..2c2847ee 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -12,4 +12,6 @@ export { default as DhpWeapon } from './sheets/items/weapon.mjs'; export { default as DhpArmor } from './sheets/items/armor.mjs'; export { default as DhpChatMessage } from './chatMessage.mjs'; export { default as DhpEnvironment } from './sheets/environment.mjs'; -export { default as DhActiveEffectConfig } from './sheets/activeEffectConfig.mjs'; \ No newline at end of file +export { default as DhActiveEffectConfig } from './sheets/activeEffectConfig.mjs'; + +export * as api from './sheets/api/_modules.mjs'; \ No newline at end of file diff --git a/module/applications/sheets/api/_modules.mjs b/module/applications/sheets/api/_modules.mjs new file mode 100644 index 00000000..d5ef290d --- /dev/null +++ b/module/applications/sheets/api/_modules.mjs @@ -0,0 +1,2 @@ +export {default as DHApplicationMixin} from "./application-mixin.mjs"; +export {default as DHBaseItemSheet} from "./base-item.mjs"; diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs new file mode 100644 index 00000000..d45cafe6 --- /dev/null +++ b/module/applications/sheets/api/application-mixin.mjs @@ -0,0 +1,102 @@ +const { HandlebarsApplicationMixin } = foundry.applications.api; + +/** + * @typedef {object} DragDropConfig + * @property {string|null} dragSelector - A CSS selector that identifies draggable elements. + * @property {string|null} dropSelector - A CSS selector that identifies drop targets. + */ + +/** + * @typedef {import("@client/applications/api/handlebars-application.mjs").HandlebarsRenderOptions} HandlebarsRenderOptions + * @typedef {foundry.applications.types.ApplicationConfiguration & HandlebarsRenderOptions & { dragDrop?: DragDropConfig[] }} DHSheetV2Configuration + */ + +/** + * @template {Constructor} BaseDocumentSheet + * @param {BaseDocumentSheet} Base - The base class to extend. + * @returns {BaseDocumentSheet} + */ +export default function DHApplicationMixin(Base) { + class DHSheetV2 extends HandlebarsApplicationMixin(Base) { + /** + * @param {DHSheetV2Configuration} [options={}] + */ + constructor(options = {}) { + super(options); + /** + * @type {foundry.applications.ux.DragDrop[]} + * @private + */ + this._dragDrop = this._createDragDropHandlers(); + } + + /** + * The default options for the sheet. + * @type {DHSheetV2Configuration} + */ + static DEFAULT_OPTIONS = { + classes: ['daggerheart', 'sheet', 'dh-style'], + position: { + width: 480, + height: 'auto' + }, + + dragDrop: [] + }; + + /* -------------------------------------------- */ + + /**@inheritdoc */ + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + this._dragDrop.forEach(d => d.bind(htmlElement)); + } + + /* -------------------------------------------- */ + /* Drag and Drop */ + /* -------------------------------------------- */ + + /** + * Creates drag-drop handlers from the configured options. + * @returns {foundry.applications.ux.DragDrop[]} + * @private + */ + _createDragDropHandlers() { + return this.options.dragDrop.map(d => { + d.callbacks = { + drop: this._onDrop.bind(this) + }; + return new foundry.applications.ux.DragDrop.implementation(d); + }); + } + + /** + * Handle drop event. + * @param {DragEvent} event + * @protected + */ + _onDrop(event) { } + + /* -------------------------------------------- */ + /* Prepare Context */ + /* -------------------------------------------- */ + + /** + * Prepare the template context. + * @param {object} options + * @param {string} [objectPath='document'] + * @returns {Promise} + * @inheritdoc + */ + async _prepareContext(options, objectPath = 'document') { + const context = await super._prepareContext(options); + context.config = CONFIG.daggerheart; + context.source = this[objectPath]; + context.fields = this[objectPath].schema.fields; + context.systemFields = this[objectPath].system ? this[objectPath].system.schema.fields : {}; + return context; + } + } + + return DHSheetV2; +} diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs new file mode 100644 index 00000000..e6fcf26a --- /dev/null +++ b/module/applications/sheets/api/base-item.mjs @@ -0,0 +1,129 @@ +import DHApplicationMixin from "./application-mixin.mjs"; + +const { ItemSheetV2 } = foundry.applications.sheets; + +/** + * A base item sheet extending {@link ItemSheetV2} via {@link DHApplicationMixin} + * @extends ItemSheetV2 + * @mixes DHSheetV2 + */ +export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { + /** @inheritDoc */ + static DEFAULT_OPTIONS = { + classes: ['item'], + position: { width: 600 }, + form: { + submitOnChange: true + }, + actions: { + addAction: DHBaseItemSheet.#addAction, + editAction: DHBaseItemSheet.#editAction, + removeAction: DHBaseItemSheet.#removeAction + } + }; + + /* -------------------------------------------- */ + + /** @inheritdoc */ + static TABS = { + primary: { + tabs: [ + { id: 'description' }, + { id: 'actions' }, + { id: 'settings' } + ], + initial: "description", + labelPrefix: "DAGGERHEART.Sheets.TABS" + } + } + + /* -------------------------------------------- */ + /* Application Clicks Actions */ + /* -------------------------------------------- */ + + /** + * Render a dialog prompting the user to select an action type. + * + * @returns {Promise} An object containing the selected action type. + */ + static async selectActionType() { + const content = await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/views/actionType.hbs', + { types: SYSTEM.ACTIONS.actionTypes } + ), + title = 'Select Action Type', //useless var + type = 'form', + data = {}; //useless var + //TODO: use DialogV2 + return Dialog.prompt({ + title, + label: title, + content, + type, //this prop is useless + callback: html => { + const form = html[0].querySelector('form'), + fd = new foundry.applications.ux.FormDataExtended(form); + foundry.utils.mergeObject(data, fd.object, { inplace: true }); + // if (!data.name?.trim()) data.name = game.i18n.localize(SYSTEM.ACTIONS.actionTypes[data.type].name); + return data; + }, + rejectClose: false + }); + } + + /** + * 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"] + */ + static async #addAction(_event, _button) { + const actionType = await DHBaseItemSheet.selectActionType(), + actionIndexes = this.document.system.actions.map(x => x._id.split('-')[2]).sort((a, b) => a - b); + try { + const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack, + action = new cls( + { + // id: `${this.document.id}-Action-${actionIndexes.length > 0 ? actionIndexes[0] + 1 : 1}` + _id: foundry.utils.randomID(), + type: actionType.type, + name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name), + ...cls.getSourceConfig(this.document) + }, + { + parent: this.document + } + ); + await this.document.update({ 'system.actions': [...this.document.system.actions, action] }); + await new DHActionConfig(this.document.system.actions[this.document.system.actions.length - 1]).render( + true + ); + } catch (error) { + console.log(error); + } + } + + /** + * 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"] + */ + static async #editAction(_event, button) { + const action = this.document.system.actions[button.dataset.index]; + await new DHActionConfig(action).render(true); + } + + /** + * 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"] + */ + static async #removeAction(event, button) { + event.stopPropagation(); + await this.document.update({ + 'system.actions': this.document.system.actions.filter( + (_, index) => index !== Number.parseInt(button.dataset.index) + ) + }); + } + +} \ No newline at end of file diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 32c482ba..4cc05fe2 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -1,14 +1,14 @@ -import { armorFeatures } from '../../../config/itemConfig.mjs'; +import DHBaseItemSheet from '../api/base-item.mjs'; import { tagifyElement } from '../../../helpers/utils.mjs'; -import DHItemSheetV2 from '../item.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class ArmorSheet extends DHItemSheetV2(ItemSheetV2) { +export default class ArmorSheet extends DHBaseItemSheet { + /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['armor'], dragDrop: [{ dragSelector: null, dropSelector: null }] }; + /**@override */ static PARTS = { header: { template: 'systems/daggerheart/templates/sheets/items/armor/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, @@ -23,6 +23,7 @@ export default class ArmorSheet extends DHItemSheetV2(ItemSheetV2) { } }; + /**@inheritdoc */ async _preparePartContext(partId, context) { super._preparePartContext(partId, context); @@ -35,15 +36,20 @@ export default class ArmorSheet extends DHItemSheetV2(ItemSheetV2) { return context; } + /**@inheritdoc */ _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); const featureInput = htmlElement.querySelector('.features-input'); - tagifyElement(featureInput, armorFeatures, this.onFeatureSelect.bind(this)); + tagifyElement(featureInput, CONFIG.daggerheart.ITEM.armorFeatures, ArmorSheet.onFeatureSelect.bind(this)); } - async onFeatureSelect(features) { - await this.document.update({ 'system.features': features.map(x => ({ value: x.value })) }); - this.render(true); + /** + * Callback function used by `tagifyElement`. + * @param {Array} selectedOptions - The currently selected tag objects. + */ + static async onFeatureSelect(selectedOptions ) { + await this.document.update({ 'system.features': selectedOptions .map(x => ({ value: x.value })) }); + this.render({force: false, parts: ["settings"]}); } } diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index a4659598..f55c2b5f 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -1,15 +1,14 @@ +import DHBaseItemSheet from '../api/base-item.mjs'; import { actionsTypes } from '../../../data/_module.mjs'; import { tagifyElement } from '../../../helpers/utils.mjs'; import DHActionConfig from '../../config/Action.mjs'; -import DaggerheartSheet from '../daggerheart-sheet.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; const { TextEditor } = foundry.applications.ux; -export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { +export default class ClassSheet extends DHBaseItemSheet { static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'class'], + classes: ['class'], position: { width: 700 }, actions: { removeSubclass: this.removeSubclass, @@ -23,11 +22,6 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { removeSecondaryWeapon: this.removeSecondaryWeapon, removeArmor: this.removeArmor }, - form: { - handler: this.updateForm, - submitOnChange: true, - closeOnSubmit: false - }, dragDrop: [ { dragSelector: '.suggested-item', dropSelector: null }, { dragSelector: null, dropSelector: '.take-section' }, @@ -53,24 +47,17 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { } }; + /** @inheritdoc */ static TABS = { - features: { - active: true, - cssClass: '', - group: 'primary', - id: 'features', - icon: null, - label: 'DAGGERHEART.Sheets.Class.Tabs.Features' - }, - settings: { - active: false, - cssClass: '', - group: 'primary', - id: 'settings', - icon: null, - label: 'DAGGERHEART.Sheets.Class.Tabs.settings' + primary: { + tabs: [ + { id: 'description' }, + { id: 'settings' }, + ], + initial: "description", + labelPrefix: "DAGGERHEART.Sheets.Feature.Tabs" } - }; + } _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); @@ -81,17 +68,10 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.document = this.document; - context.tabs = super._getTabs(this.constructor.TABS); context.domains = this.document.system.domains; - return context; } - static async updateForm(event, _, formData) { - await this.document.update(formData.object); - this.render(); - } onAddTag(e) { if (e.detail.index === 2) { @@ -157,9 +137,9 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } - ), + 'systems/daggerheart/templates/views/actionType.hbs', + { types: SYSTEM.ACTIONS.actionTypes } + ), title = 'Select Action Type', type = 'form', data = {}; diff --git a/module/applications/sheets/items/consumable.mjs b/module/applications/sheets/items/consumable.mjs index 815c6b9b..26fdd312 100644 --- a/module/applications/sheets/items/consumable.mjs +++ b/module/applications/sheets/items/consumable.mjs @@ -1,7 +1,6 @@ -import DHItemSheetV2 from '../item.mjs'; +import DHBaseItemSheet from '../api/base-item.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class ConsumableSheet extends DHItemSheetV2(ItemSheetV2) { +export default class ConsumableSheet extends DHBaseItemSheet { static DEFAULT_OPTIONS = { classes: ['consumable'], position: { width: 550 } diff --git a/module/applications/sheets/items/domainCard.mjs b/module/applications/sheets/items/domainCard.mjs index 17a83f95..285573cc 100644 --- a/module/applications/sheets/items/domainCard.mjs +++ b/module/applications/sheets/items/domainCard.mjs @@ -1,7 +1,6 @@ -import DHItemSheetV2 from '../item.mjs'; +import DHBaseItemSheet from '../api/base-item.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class DomainCardSheet extends DHItemSheetV2(ItemSheetV2) { +export default class DomainCardSheet extends DHBaseItemSheet { static DEFAULT_OPTIONS = { classes: ['domain-card'], position: { width: 450, height: 700 } diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index 40fa9b02..c312b7b6 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -1,17 +1,11 @@ -import DHItemSheetV2 from '../item.mjs'; - -const { ItemSheetV2 } = foundry.applications.sheets; -export default class FeatureSheet extends DHItemSheetV2(ItemSheetV2) { - constructor(options = {}) { - super(options); - - this.selectedEffectType = null; - } +import DHBaseItemSheet from '../api/base-item.mjs'; +export default class FeatureSheet extends DHBaseItemSheet { + /** @inheritDoc */ static DEFAULT_OPTIONS = { id: 'daggerheart-feature', classes: ['feature'], - position: { width: 600, height: 600 }, + position: { height: 600 }, window: { resizable: true }, actions: { addEffect: this.addEffect, @@ -19,6 +13,7 @@ export default class FeatureSheet extends DHItemSheetV2(ItemSheetV2) { } }; + /**@override */ static PARTS = { header: { template: 'systems/daggerheart/templates/sheets/items/feature/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, @@ -37,58 +32,85 @@ export default class FeatureSheet extends DHItemSheetV2(ItemSheetV2) { } }; + /** + * Internally tracks the selected effect type from the select. + * @type {String} + * @private + */ + _selectedEffectType; + + /**@override */ static TABS = { - ...super.TABS, - effects: { - active: false, - cssClass: '', - group: 'primary', - id: 'effects', - icon: null, - label: 'DAGGERHEART.Sheets.Feature.Tabs.Effects' + primary: { + tabs: [ + { id: 'description' }, + { id: 'actions' }, + { id: 'settings' }, + { id: 'effects' } + ], + initial: "description", + labelPrefix: "DAGGERHEART.Sheets.TABS" } }; + /**@inheritdoc*/ _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); - $(htmlElement).find('.effect-select').on('change', this.effectSelect.bind(this)); + if (partId === "effects") + htmlElement.querySelector('.effect-select')?.addEventListener('change', this._effectSelect.bind(this)); } + + /** + * Handles selection of a new effect type. + * @param {Event} event - Change Event + */ + _effectSelect(event) { + const value = event.currentTarget.value; + this._selectedEffectType = value; + this.render({ parts: ["effects"] }); + } + + /**@inheritdoc */ async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.document = this.document; - context.tabs = super._getTabs(this.constructor.TABS); - context.generalConfig = SYSTEM.GENERAL; - context.itemConfig = SYSTEM.ITEM; - context.properties = SYSTEM.ACTOR.featureProperties; - context.dice = SYSTEM.GENERAL.diceTypes; - context.selectedEffectType = this.selectedEffectType; - context.effectConfig = SYSTEM.EFFECTS; + context.properties = CONFIG.daggerheart.ACTOR.featureProperties; + context.dice = CONFIG.daggerheart.GENERAL.diceTypes; + context.effectConfig = CONFIG.daggerheart.EFFECTS; + + context.selectedEffectType = this._selectedEffectType; return context; } - effectSelect(event) { - this.selectedEffectType = event.currentTarget.value; - this.render(true); - } - static async addEffect() { - if (!this.selectedEffectType) return; - - const { id, name, ...rest } = SYSTEM.EFFECTS.effectTypes[this.selectedEffectType]; - const update = { - [foundry.utils.randomID()]: { - type: this.selectedEffectType, + /** + * Adds a new effect to the item, based on the selected effect type. + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} _target - The capturing HTML element which defines the [data-action] + * @returns + */ + static async addEffect(_event, _target) { + const type = this._selectedEffectType; + if (!type) return; + const { id, name, ...rest } = CONFIG.daggerheart.EFFECTS.effectTypes[type]; + await this.item.update({ + [`system.effects.${foundry.utils.randomID()}`]: { + type, value: '', ...rest } - }; - await this.item.update({ 'system.effects': update }); + }); } - static async removeEffect(_, button) { - const path = `system.effects.-=${button.dataset.effect}`; + /** + * Removes an effect from the item. + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} target - The capturing HTML element which defines the [data-action] + * @returns + */ + static async removeEffect(_event, target) { + const path = `system.effects.-=${target.dataset.effect}`; await this.item.update({ [path]: null }); } } diff --git a/module/applications/sheets/items/miscellaneous.mjs b/module/applications/sheets/items/miscellaneous.mjs index dd22d216..4ef74b5c 100644 --- a/module/applications/sheets/items/miscellaneous.mjs +++ b/module/applications/sheets/items/miscellaneous.mjs @@ -1,7 +1,6 @@ -import DHItemSheetV2 from '../item.mjs'; +import DHBaseItemSheet from '../api/base-item.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class MiscellaneousSheet extends DHItemSheetV2(ItemSheetV2) { +export default class MiscellaneousSheet extends DHBaseItemSheet { static DEFAULT_OPTIONS = { classes: ['miscellaneous'], position: { width: 550 } diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs index e6e9725f..823a953a 100644 --- a/module/applications/sheets/items/subclass.mjs +++ b/module/applications/sheets/items/subclass.mjs @@ -1,12 +1,10 @@ +import DHBaseItemSheet from '../api/base-item.mjs'; import { actionsTypes } from '../../../data/_module.mjs'; import DHActionConfig from '../../config/Action.mjs'; -import DhpApplicationMixin from '../daggerheart-sheet.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class SubclassSheet extends DhpApplicationMixin(ItemSheetV2) { +export default class SubclassSheet extends DHBaseItemSheet { static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'subclass'], + classes: ['subclass'], position: { width: 600 }, window: { resizable: false }, actions: { @@ -14,11 +12,6 @@ export default class SubclassSheet extends DhpApplicationMixin(ItemSheetV2) { editFeature: this.editFeature, deleteFeature: this.deleteFeature }, - form: { - handler: this.updateForm, - submitOnChange: true, - closeOnSubmit: false - } }; static PARTS = { @@ -35,45 +28,17 @@ export default class SubclassSheet extends DhpApplicationMixin(ItemSheetV2) { } }; + /** @inheritdoc */ static TABS = { - description: { - active: true, - cssClass: '', - group: 'primary', - id: 'description', - icon: null, - label: 'DAGGERHEART.Sheets.Feature.Tabs.Description' - }, - features: { - active: false, - cssClass: '', - group: 'primary', - id: 'features', - icon: null, - label: 'DAGGERHEART.Sheets.Feature.Tabs.Features' - }, - settings: { - active: false, - cssClass: '', - group: 'primary', - id: 'settings', - icon: null, - label: 'DAGGERHEART.Sheets.Feature.Tabs.Settings' + primary: { + tabs: [ + { id: 'description' }, + { id: 'features' }, + { id: 'settings' } + ], + initial: "description", + labelPrefix: "DAGGERHEART.Sheets.TABS" } - }; - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.document = this.document; - context.config = CONFIG.daggerheart; - context.tabs = super._getTabs(this.constructor.TABS); - - return context; - } - - static async updateForm(event, _, formData) { - await this.document.update(formData.object); - this.render(); } static addFeature(_, target) { @@ -93,9 +58,9 @@ export default class SubclassSheet extends DhpApplicationMixin(ItemSheetV2) { async #selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } - ), + 'systems/daggerheart/templates/views/actionType.hbs', + { types: SYSTEM.ACTIONS.actionTypes } + ), title = 'Select Action Type', type = 'form', data = {}; diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index b381e8bf..70f82f68 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -1,13 +1,14 @@ +import DHBaseItemSheet from '../api/base-item.mjs'; import { weaponFeatures } from '../../../config/itemConfig.mjs'; import { tagifyElement } from '../../../helpers/utils.mjs'; -import DHItemSheetV2 from '../item.mjs'; -const { ItemSheetV2 } = foundry.applications.sheets; -export default class WeaponSheet extends DHItemSheetV2(ItemSheetV2) { +export default class WeaponSheet extends DHBaseItemSheet { + /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['weapon'] }; + /**@override */ static PARTS = { header: { template: 'systems/daggerheart/templates/sheets/items/weapon/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, @@ -22,6 +23,7 @@ export default class WeaponSheet extends DHItemSheetV2(ItemSheetV2) { } }; + /**@inheritdoc */ async _preparePartContext(partId, context) { super._preparePartContext(partId, context); @@ -34,15 +36,20 @@ export default class WeaponSheet extends DHItemSheetV2(ItemSheetV2) { return context; } + /**@inheritdoc */ _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); const featureInput = htmlElement.querySelector('.features-input'); - tagifyElement(featureInput, weaponFeatures, this.onFeatureSelect.bind(this)); + tagifyElement(featureInput, weaponFeatures, WeaponSheet.onFeatureSelect.bind(this)); } - async onFeatureSelect(features) { - await this.document.update({ 'system.features': features.map(x => ({ value: x.value })) }); - this.render(true); + /** + * Callback function used by `tagifyElement`. + * @param {Array} selectedOptions - The currently selected tag objects. + */ + static async onFeatureSelect(selectedOptions) { + await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); + this.render({ force: false, parts: ["settings"] }); } } diff --git a/templates/sheets/items/feature/effects.hbs b/templates/sheets/items/feature/effects.hbs index 68fed719..52beb934 100755 --- a/templates/sheets/items/feature/effects.hbs +++ b/templates/sheets/items/feature/effects.hbs @@ -8,15 +8,15 @@ {{localize "DAGGERHEART.Sheets.Feature.effects.addEffect"}}
- - + +
- {{#each this.document.system.effects as |effect key|}} + {{#each document.system.effects as |effect key|}}
{{localize (concat 'DAGGERHEART.Effects.Types.' effect.type '.Name')}} @@ -32,8 +32,8 @@ {{selectOptions effect.applyLocationChoices selected=effect.appliesOn localize=true}} {{/if}} - {{#if (eq effect.valueType ../this.effectConfig.valueTypes.numberString.id)}} - {{#if (eq effect.type ../this.effectConfig.effectTypes.damage.id) }} + {{#if (eq effect.valueType @root.effectConfig.valueTypes.numberString.id)}} + {{#if (eq effect.type @root.effectConfig.effectTypes.damage.id) }} {{localize "DAGGERHEART.Sheets.Feature.effects.value"}} @@ -47,7 +47,7 @@ {{/if}} {{/if}} - {{#if (eq effect.valueType ../this.effectConfig.valueTypes.select.id)}} + {{#if (eq effect.valueType @root.effectConfig.valueTypes.select.id)}} {{localize effect.valueData.fromValue}} diff --git a/templates/sheets/items/feature/settings.hbs b/templates/sheets/items/feature/settings.hbs index cca672ea..dc5cb884 100755 --- a/templates/sheets/items/feature/settings.hbs +++ b/templates/sheets/items/feature/settings.hbs @@ -22,13 +22,13 @@ {{localize "DAGGERHEART.Sheets.Feature.ValueType.Title"}} {{localize "DAGGERHEART.Sheets.Feature.ValueType.Title"}} {{#if (eq document.system.featureType.type "dice")}} {{localize "DAGGERHEART.Sheets.Feature.ValueType.Dice"}} {{localize "DAGGERHEART.Feature.Max"}} @@ -36,7 +36,7 @@ {{localize "DAGGERHEART.Sheets.Feature.ValueType.Property"}} {{/if}}