daggerheart/module/applications/sheets/api/base-item.mjs
2025-07-05 13:16:39 +02:00

152 lines
5.4 KiB
JavaScript

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: {
addFeature: DHBaseItemSheet.#addFeature,
editFeature: DHBaseItemSheet.#editFeature,
removeFeature: DHBaseItemSheet.#removeFeature
},
dragDrop: [
{ dragSelector: null, dropSelector: '.tab.features .drop-section' },
{ dragSelector: '.feature-item', dropSelector: null }
]
};
/* -------------------------------------------- */
/** @inheritdoc */
static TABS = {
primary: {
tabs: [{ id: 'description' }, { id: 'features' }, { id: 'settings' }],
initial: 'description',
labelPrefix: 'DAGGERHEART.Sheets.TABS'
}
};
/* -------------------------------------------- */
/* Prepare Context */
/* -------------------------------------------- */
/**@inheritdoc */
async _preparePartContext(partId, context) {
await super._preparePartContext(partId, context);
const { TextEditor } = foundry.applications.ux;
switch (partId) {
case 'description':
const value = foundry.utils.getProperty(this.document, 'system.description') ?? '';
context.enrichedDescription = await TextEditor.enrichHTML(value, {
relativeTo: this.item,
rollData: this.item.getRollData(),
secrets: this.item.isOwner
});
break;
}
return context;
}
/* -------------------------------------------- */
/* Application Clicks Actions */
/* -------------------------------------------- */
/**
* 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"]
*/
static async #addFeature(_event, _button) {
const feature = await game.items.documentClass.create({
type: 'feature',
name: game.i18n.localize('DAGGERHEART.General.newFeature')
});
await this.document.update({
'system.features': [...this.document.system.features.filter(x => x).map(x => x.uuid), feature.uuid]
});
}
/**
* 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"]
*/
static async #editFeature(_event, button) {
const target = button.closest('.feature-item');
const feature = this.document.system.features.find(x => x?.id === target.id);
if (!feature) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
return;
}
feature.sheet.render(true);
}
/**
* 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"]
*/
static async #removeFeature(event, button) {
event.stopPropagation();
const target = button.closest('.feature-item');
await this.document.update({
'system.features': this.document.system.features
.filter(feature => feature && feature.id !== target.id)
.map(x => x.uuid)
});
}
/* -------------------------------------------- */
/* Application Drag/Drop */
/* -------------------------------------------- */
/**
* On dragStart on the item.
* @param {DragEvent} event - The drag event
*/
async _onDragStart(event) {
const featureItem = event.currentTarget.closest('.feature-item');
if (featureItem) {
const feature = this.document.system.features.find(x => x?.id === featureItem.id);
if (!feature) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
return;
}
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
}
}
/**
* On drop on the item.
* @param {DragEvent} event - The drag event
*/
async _onDrop(event) {
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
if (data.fromInternal) return;
const item = await fromUuid(data.uuid);
if (item?.type === 'feature') {
const current = this.document.system.features.map(x => x.uuid);
await this.document.update({ 'system.features': [...current, item.uuid] });
}
}
}