const { HandlebarsApplicationMixin } = foundry.applications.api export default class YggdrasillItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) { constructor(options = {}) { super(options) this.#dragDrop = this.#createDragDropHandlers() } #dragDrop /** @override */ static DEFAULT_OPTIONS = { classes: ["fvtt-yggdrasill", "item"], position: { width: 620, height: 600, }, form: { submitOnChange: true, }, window: { resizable: true, }, tabs: [ { navSelector: 'nav[data-group="primary"]', contentSelector: "section.sheet-body", initial: "description", }, ], dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }], actions: { editImage: YggdrasillItemSheet.#onEditImage, postItem: YggdrasillItemSheet.#onPostItem, }, } /** * Tab groups state * @type {object} */ tabGroups = { primary: "description" } /** @override */ async _prepareContext() { // Import config const YGGDRASILL_CONFIG = game.system.yggdrasill?.config || game.system.config || {}; // Create options for niveau 0-5 const optionsNiveaux4 = {}; for (let i = 0; i <= 5; i++) { optionsNiveaux4[`${i}`] = `${i}`; } // Create options for base (0-20) const optionsBase = {}; for (let i = 0; i <= 20; i++) { optionsBase[`${i}`] = `${i}`; } const context = { fields: this.document.schema.fields, systemFields: this.document.system.schema.fields, item: this.document, system: this.document.system, data: this.document.system, source: this.document.toObject(), enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description || "", { async: true }), enrichedEffet: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effet || "", { async: true }), isEditMode: true, isEditable: this.isEditable, editable: this.isEditable, isGM: game.user.isGM, config: YGGDRASILL_CONFIG, optionsBase: optionsBase, optionsNiveaux4: optionsNiveaux4, } return context } /** @override */ _onRender(context, options) { super._onRender(context, options) // Activate tab navigation manually const nav = this.element.querySelector('nav.tabs[data-group]') if (nav) { const group = nav.dataset.group // Activate the current tab const activeTab = this.tabGroups[group] || "description" nav.querySelectorAll('[data-tab]').forEach(link => { const tab = link.dataset.tab link.classList.toggle('active', tab === activeTab) link.addEventListener('click', (event) => { event.preventDefault() this.tabGroups[group] = tab this.render() }) }) // Show/hide tab content const body = this.element.querySelector('section.sheet-body') if (body) { body.querySelectorAll('[data-tab]').forEach(content => { const tab = content.dataset.tab content.style.display = tab === activeTab ? 'block' : 'none' }) } } } /** * Creates drag-and-drop handlers for this application * @returns {DragDrop[]} An array of DragDrop handlers * @private */ #createDragDropHandlers() { return [] } /** * Handle changing a Document's image * @this {YggdrasillItemSheet} * @param {PointerEvent} event - The triggering event * @param {HTMLElement} target - The button element */ static async #onEditImage(event, target) { const attr = target.dataset.edit || "img" const current = foundry.utils.getProperty(this.document, attr) const fp = new FilePicker({ current, type: "image", callback: (path) => { this.document.update({ [attr]: path }) }, }) return fp.browse() } /** * Handle posting item to chat * @this {YggdrasillItemSheet} * @param {PointerEvent} event - The triggering event * @param {HTMLElement} target - The button element */ static async #onPostItem(event, target) { const item = this.document const chatData = { user: game.user.id, speaker: ChatMessage.getSpeaker(), content: await foundry.applications.handlebars.renderTemplate("systems/fvtt-yggdrasill/templates/chat-item-card.hbs", { item: item, system: item.system, description: await TextEditor.enrichHTML(item.system.description || "", { async: true }) }) } ChatMessage.create(chatData) } /** * Handle beginning of a drag operation * @param {DragEvent} event - The originating drag event * @protected */ _onDragStart(event) { const dragData = this.document.toDragData() event.dataTransfer.setData("text/plain", JSON.stringify(dragData)) } /** * Handle a drop event * @param {DragEvent} event - The originating drop event * @protected */ async _onDrop(event) { // Items generally don't handle drops, but method exists for extensibility return false } }