Replace compendium calls

This commit is contained in:
Dapoolp 2025-08-06 03:04:00 +02:00
parent 42867a4be1
commit 3ea050997b
12 changed files with 220 additions and 70 deletions

View file

@ -1,6 +1,7 @@
import { abilities } from '../../config/actorConfig.mjs'; import { abilities } from '../../config/actorConfig.mjs';
import { burden } from '../../config/generalConfig.mjs'; import { burden } from '../../config/generalConfig.mjs';
import { createEmbeddedItemWithEffects } from '../../helpers/utils.mjs'; import { createEmbeddedItemWithEffects } from '../../helpers/utils.mjs';
import { ItemBrowser } from '../ui/itemBrowser.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -485,8 +486,24 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
}); });
} }
static async viewCompendium(_, target) { static async viewCompendium(event, target) {
(await game.packs.get(`daggerheart.${target.dataset.compendium}`))?.render(true); const type = target.dataset.compendium ?? target.dataset.type;
const presets = {
compendium: "daggerheart",
folder: type,
render: {
noFolder: true
}
};
if(type == "domains")
presets.filter = {
'level.max': { key: 'level.max', value: 1 },
'system.domain': { key: 'system.domain', value: this.setup.class?.system.domains ?? null },
};
return new ItemBrowser({ presets }).render({ force: true });
} }
static async viewItem(_, target) { static async viewItem(_, target) {

View file

@ -1,6 +1,7 @@
import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs'; import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs';
import { domains } from '../../config/domainConfig.mjs'; import { domains } from '../../config/domainConfig.mjs';
import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs'; import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs';
import { ItemBrowser } from '../ui/itemBrowser.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -525,8 +526,24 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
this.render(); this.render();
} }
static async viewCompendium(_, button) { static async viewCompendium(event, target) {
(await game.packs.get(`daggerheart.${button.dataset.compendium}`))?.render(true); const type = target.dataset.compendium ?? target.dataset.type;
const presets = {
compendium: "daggerheart",
folder: type,
render: {
noFolder: true
}
};
// if(type == "domains")
// presets.filter = {
// 'level.max': { key: 'level.max', value: 1 },
// 'system.domain': { key: 'system.domain', value: this.setup.class?.system.domains ?? null },
// };
return new ItemBrowser({ presets }).render({ force: true });
} }
static async selectPreview(_, button) { static async selectPreview(_, button) {

View file

@ -594,7 +594,16 @@ export default class CharacterSheet extends DHBaseActorSheet {
*/ */
static async #openPack(_event, button) { static async #openPack(_event, button) {
const { key } = button.dataset; const { key } = button.dataset;
game.packs.get(key)?.render(true);
const presets = {
compendium: "daggerheart",
folder: key,
render: {
noFolder: true
}
};
return new ItemBrowser({ presets }).render({ force: true });
} }
/** /**

View file

@ -1,5 +1,6 @@
const { HandlebarsApplicationMixin } = foundry.applications.api; const { HandlebarsApplicationMixin } = foundry.applications.api;
import { getDocFromElement, getDocFromElementSync, tagifyElement } from '../../../helpers/utils.mjs'; import { getDocFromElement, getDocFromElementSync, tagifyElement } from '../../../helpers/utils.mjs';
import { ItemBrowser } from '../../ui/itemBrowser.mjs';
/** /**
* @typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction * @typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction
@ -82,7 +83,9 @@ export default function DHApplicationMixin(Base) {
toChat: DHSheetV2.#toChat, toChat: DHSheetV2.#toChat,
useItem: DHSheetV2.#useItem, useItem: DHSheetV2.#useItem,
toggleEffect: DHSheetV2.#toggleEffect, toggleEffect: DHSheetV2.#toggleEffect,
toggleExtended: DHSheetV2.#toggleExtended toggleExtended: DHSheetV2.#toggleExtended,
addNewItem: DHSheetV2.#addNewItem,
browseItem: DHSheetV2.#browseItem,
}, },
contextMenus: [ contextMenus: [
{ {
@ -409,6 +412,71 @@ export default function DHApplicationMixin(Base) {
/* Application Clicks Actions */ /* Application Clicks Actions */
/* -------------------------------------------- */ /* -------------------------------------------- */
static async #addNewItem(event, target) {
const { type } = target.dataset;
const createChoice = await foundry.applications.api.DialogV2.wait({
classes: ['dh-style', 'two-big-buttons'],
buttons: [
{
action: "create",
label: "Create Item",
icon: "fa-solid fa-plus"
},
{
action: "browse",
label: "Browse Compendium",
icon: "fa-solid fa-book"
}
]
});
if(!createChoice) return;
if(createChoice === "browse")
return DHSheetV2.#browseItem.call(this, event, target);
else
return DHSheetV2.#createDoc.call(this, event, target);
}
static async #browseItem(event, target) {
const type = target.dataset.compendium ?? target.dataset.type;
const presets = {};
switch (type) {
case 'loot':
case 'consumable':
case 'armor':
case 'weapon':
presets.compendium = "daggerheart";
presets.folder = "equipments";
presets.render = {
noFolder: true
};
presets.filter = {
type: { key: 'type', value: type, forced: true }
};
break;
case 'domainCard':
presets.compendium = "daggerheart";
presets.folder = "domains";
presets.render = {
noFolder: true
};
presets.filter = {
'level.max': { key: 'level.max', value: this.document.system.levelData.level.current },
'system.domain': { key: 'system.domain', value: this.document.system.domains },
};
break;
default:
return;
}
return new ItemBrowser({ presets }).render({ force: true });
}
/** /**
* Create an embedded document. * Create an embedded document.
* @type {ApplicationClickAction} * @type {ApplicationClickAction}

View file

@ -15,6 +15,10 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this.fieldFilter = []; this.fieldFilter = [];
this.selectedMenu = { path: [], data: null }; this.selectedMenu = { path: [], data: null };
this.config = CONFIG.DH.ITEMBROWSER.compendiumConfig; this.config = CONFIG.DH.ITEMBROWSER.compendiumConfig;
this.presets = options.presets;
if(this.presets?.folder)
ItemBrowser.selectFolder.call(this, null, null, this.presets.compendium, this.presets.folder);
} }
/** @inheritDoc */ /** @inheritDoc */
@ -37,10 +41,10 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
sortList: this.sortList sortList: this.sortList
}, },
position: { position: {
width: 1000, top: 70,
height: 800 left: 120,
// top: "200px", width: 800,
// left: "120px" height: 600
} }
}; };
@ -89,6 +93,11 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this._createSearchFilter(); this._createSearchFilter();
this._createFilterInputs(); this._createFilterInputs();
this._createDragProcess(); this._createDragProcess();
if(this.presets?.filter) {
Object.entries(this.presets.filter).forEach(([k,v]) => this.fieldFilter.find(c => c.name === k).value = v.value);
await this._onInputFilterBrowser();
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -105,7 +114,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
context.formatChoices = this.formatChoices; context.formatChoices = this.formatChoices;
context.fieldFilter = this.fieldFilter = this._createFieldFilter(); context.fieldFilter = this.fieldFilter = this._createFieldFilter();
context.items = this.items; context.items = this.items;
console.log(this.items); context.presets = this.presets;
return context; return context;
} }
@ -128,10 +137,10 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
return folders; return folders;
} }
static async selectFolder(_, target) { static async selectFolder(_, target, compend, folder) {
const config = foundry.utils.deepClone(this.config), const config = foundry.utils.deepClone(this.config),
compendium = target.closest('[data-compendium-id]').dataset.compendiumId, compendium = compend ?? target.closest('[data-compendium-id]').dataset.compendiumId,
folderId = target.dataset.folderId, folderId = folder ?? target.dataset.folderId,
folderPath = `${compendium}.folders.${folderId}`, folderPath = `${compendium}.folders.${folderId}`,
folderData = foundry.utils.getProperty(config, folderPath); folderData = foundry.utils.getProperty(config, folderPath);
@ -186,9 +195,9 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
if (typeof f.field === 'string') f.field = foundry.utils.getProperty(game, f.field); if (typeof f.field === 'string') f.field = foundry.utils.getProperty(game, f.field);
else if (typeof f.choices === 'function') { else if (typeof f.choices === 'function') {
f.choices = f.choices(); f.choices = f.choices();
console.log(f.choices)
} }
f.name ??= f.key; f.name ??= f.key;
f.value = this.presets.filter?.[f.name]?.value ?? null;
// filters.push(f); // filters.push(f);
}); });
return filters; return filters;
@ -286,11 +295,9 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
async _onInputFilterBrowser(event) { async _onInputFilterBrowser(event) {
this.#filteredItems.browser.input.clear(); this.#filteredItems.browser.input.clear();
this.fieldFilter.find(f => f.name === event.target.name).value = event.target.value; if(event) this.fieldFilter.find(f => f.name === event.target.name).value = event.target.value;
// console.log(_event, html, filters) for (const li of this.element.querySelectorAll('.item-container')) {
for (const li of event.target.closest('[data-application-part="list"]').querySelectorAll('.item-container')) {
const itemUUID = li.dataset.itemUuid, const itemUUID = li.dataset.itemUuid,
item = this.items.find(i => i.uuid === itemUUID); item = this.items.find(i => i.uuid === itemUUID);
@ -308,6 +315,8 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
li.hidden = !(search.has(item.id) && matchesMenu); li.hidden = !(search.has(item.id) && matchesMenu);
// li.hidden = !(matchesMenu); // li.hidden = !(matchesMenu);
} }
console.log(this.fieldFilter)
} }
/** /**
@ -316,24 +325,18 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
* @param {*} filter * @param {*} filter
*/ */
static evaluateFilter(obj, filter) { static evaluateFilter(obj, filter) {
const docValue = foundry.utils.getProperty(obj, filter.field); let docValue = foundry.utils.getProperty(obj, filter.field);
const filterValue = filter.value; let filterValue = filter.value;
switch (filter.operator) { switch (filter.operator) {
case "contains2": case "contains2":
return Array.isArray(docValue) ? docValue.includes(filterValue) : [docValue].includes(filterValue); filterValue = Array.isArray(filterValue) ? filterValue : [filterValue];
break; docValue = Array.isArray(docValue) ? docValue : [docValue];
return docValue.some(dv => filterValue.includes(dv));
case "contains3": case "contains3":
return docValue.some(f => f.value === filterValue); return docValue.some(f => f.value === filterValue);
break;
default: default:
return foundry.applications.ux.SearchFilter.evaluateFilter(obj, filter); return foundry.applications.ux.SearchFilter.evaluateFilter(obj, filter);
break;
} }
if(filter.operator === "contains2") {
const docValue = foundry.utils.getProperty(obj, filter.field);
const filterValue = filter.value;
return Array.isArray(docValue) ? docValue.includes(filterValue) : [docValue].includes(filterValue);
} return foundry.applications.ux.SearchFilter.evaluateFilter(obj, filter)
} }
createFilterData(filter) { createFilterData(filter) {
@ -414,8 +417,9 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
async _onDragStart(event) { async _onDragStart(event) {
// console.log(event) // console.log(event)
// ui.context?.close({ animate: false }); // ui.context?.close({ animate: false });
const { itemUuid } = event.target.closest('[data-item-uuid]').dataset; const { itemUuid } = event.target.closest('[data-item-uuid]').dataset,
const dragData = foundry.utils.fromUuidSync(itemUuid).toDragData(); item = await foundry.utils.fromUuid(itemUuid),
dragData = item.toDragData();
// console.log(dragData) // console.log(dragData)
// const dragData = { UUID: itemUuid }; // const dragData = { UUID: itemUuid };
event.dataTransfer.setData('text/plain', JSON.stringify(dragData)); event.dataTransfer.setData('text/plain', JSON.stringify(dragData));

View file

@ -169,7 +169,8 @@ export const typeConfig = {
{ {
key: "system.domain", key: "system.domain",
label: "Domain", label: "Domain",
field: 'system.api.models.items.DHDomainCard.schema.fields.domain' field: 'system.api.models.items.DHDomainCard.schema.fields.domain',
operator: "contains2"
}, },
{ {
key: "system.level", key: "system.level",

View file

@ -67,4 +67,29 @@
gap: 5px; gap: 5px;
} }
} }
&.two-big-buttons {
.window-content {
padding-top: 0;
.form-footer {
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
}
button[type="submit"] {
flex-direction: column-reverse;
font-family: @font-body;
font-size: var(--font-size-14);
height: unset;
padding: .5rem 1rem;
white-space: nowrap;
i {
font-size: var(--font-size-20);
}
}
}
}
} }

View file

@ -333,5 +333,10 @@
font-family: @font-body; font-family: @font-body;
} }
} }
[disabled] {
opacity: .5;
pointer-events: none;
}
} }
} }

View file

@ -31,25 +31,25 @@
{{#if document.system.class.value}} {{#if document.system.class.value}}
<span data-action="editDoc" data-item-uuid="{{document.system.class.value.uuid}}">{{document.system.class.value.name}}</span> <span data-action="editDoc" data-item-uuid="{{document.system.class.value.uuid}}">{{document.system.class.value.name}}</span>
{{else}} {{else}}
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.classes">{{localize 'TYPES.Item.class'}}</span> <span class="missing-header-feature" data-action="openPack" data-key="classes">{{localize 'TYPES.Item.class'}}</span>
{{/if}} {{/if}}
<span class="dot">•</span> <span class="dot">•</span>
{{#if document.system.class.subclass}} {{#if document.system.class.subclass}}
<span data-action="editDoc" data-item-uuid="{{document.system.class.subclass.uuid}}">{{document.system.class.subclass.name}}</span> <span data-action="editDoc" data-item-uuid="{{document.system.class.subclass.uuid}}">{{document.system.class.subclass.name}}</span>
{{else}} {{else}}
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.subclasses">{{localize 'TYPES.Item.subclass'}}</span> <span class="missing-header-feature" data-action="openPack" data-key="subclasses">{{localize 'TYPES.Item.subclass'}}</span>
{{/if}} {{/if}}
<span class="dot">•</span> <span class="dot">•</span>
{{#if document.system.community}} {{#if document.system.community}}
<span data-action="editDoc" data-item-uuid="{{document.system.community.uuid}}">{{document.system.community.name}}</span> <span data-action="editDoc" data-item-uuid="{{document.system.community.uuid}}">{{document.system.community.name}}</span>
{{else}} {{else}}
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.communities">{{localize 'TYPES.Item.community'}}</span> <span class="missing-header-feature" data-action="openPack" data-key="communities">{{localize 'TYPES.Item.community'}}</span>
{{/if}} {{/if}}
<span class="dot">•</span> <span class="dot">•</span>
{{#if document.system.ancestry}} {{#if document.system.ancestry}}
<span data-action="editDoc" data-item-uuid="{{document.system.ancestry.uuid}}">{{document.system.ancestry.name}}</span> <span data-action="editDoc" data-item-uuid="{{document.system.ancestry.uuid}}">{{document.system.ancestry.name}}</span>
{{else}} {{else}}
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.ancestries">{{localize 'TYPES.Item.ancestry'}}</span> <span class="missing-header-feature" data-action="openPack" data-key="ancestries">{{localize 'TYPES.Item.ancestry'}}</span>
{{/if}} {{/if}}
</div> </div>
@ -58,13 +58,13 @@
{{#if document.system.multiclass.value}} {{#if document.system.multiclass.value}}
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span> <span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>
{{else}} {{else}}
<span data-action="openPack" data-key="daggerheart.classes">{{localize 'DAGGERHEART.GENERAL.multiclass'}}</span> <span data-action="openPack" data-key="classes">{{localize 'DAGGERHEART.GENERAL.multiclass'}}</span>
{{/if}} {{/if}}
<span class="dot">•</span> <span class="dot">•</span>
{{#if document.system.multiclass.subclass}} {{#if document.system.multiclass.subclass}}
<span data-action="editDoc" data-item-uuid="{{document.system.multiclass.subclass.uuid}}">{{document.system.multiclass.subclass.name}}</span> <span data-action="editDoc" data-item-uuid="{{document.system.multiclass.subclass.uuid}}">{{document.system.multiclass.subclass.name}}</span>
{{else}} {{else}}
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.subclasses">{{localize 'TYPES.Item.subclass'}}</span> <span class="missing-header-feature" data-action="openPack" data-key="subclasses">{{localize 'TYPES.Item.subclass'}}</span>
{{/if}} {{/if}}
</div> </div>
{{/if}} {{/if}}

View file

@ -26,7 +26,7 @@ Parameters:
<legend> <legend>
{{localize title}} {{localize title}}
{{#if canCreate}} {{#if canCreate}}
<a data-action="createDoc" data-document-class="{{ifThen (eq type 'effect') 'ActiveEffect' 'Item' }}" <a data-action="addNewItem" data-document-class="{{ifThen (eq type 'effect') 'ActiveEffect' 'Item' }}"
data-type="{{ifThen (eq type 'effect') 'base' type}}" data-type="{{ifThen (eq type 'effect') 'base' type}}"
{{#if inVault}}data-in-vault="{{inVault}}"{{/if}} {{#if inVault}}data-in-vault="{{inVault}}"{{/if}}
{{#if disabled}} data-disabled="{{disabled}}"{{/if}} {{#if disabled}} data-disabled="{{disabled}}"{{/if}}

View file

@ -1,49 +1,53 @@
<div class="compendium-results"> <div class="compendium-results">
{{#if menu.data }} {{#if menu.data }}
<div class="menu-path"> {{#unless (or presets.render.lite presets.render.noFolder)}}
{{#each menu.path}} <div class="menu-path">
{{#if (eq this "folders")}} {{#each menu.path}}
<span class="path-link"> {{#if (eq this "folders")}}
/ <span class="path-link">
</span> /
{{else}} </span>
<span class="item-path">{{this}}</span> {{else}}
{{/if}} <span class="item-path">{{this}}</span>
{{/each}} {{/if}}
</div> {{/each}}
<div class="item-filter">
<div class="filter-header">
<div class="search-bar">
<div class="icon">
<i class="fa-solid fa-magnifying-glass"></i>
</div>
<input type="search" name="search" class="search-input" placeholder="Search...">
</div>
{{#if fieldFilter}}
<a data-tooltip="Filters" data-action="expandContent"><i class="fa-solid fa-filter"></i></a>
{{/if}}
<a data-tooltip="Erase" data-action="resetFilters"><i class="fa-solid fa-eraser"></i></a>
</div> </div>
{{/unless}}
<div class="item-filter">
{{#unless presets.render.lite}}
<div class="filter-header">
<div class="search-bar">
<div class="icon">
<i class="fa-solid fa-magnifying-glass"></i>
</div>
<input type="search" name="search" class="search-input" placeholder="Search...">
</div>
{{#if (and fieldFilter (not presets.render.noFilter))}}
<a data-tooltip="Filters" data-action="expandContent"><i class="fa-solid fa-filter"></i></a>
{{/if}}
<a data-tooltip="Erase" data-action="resetFilters"><i class="fa-solid fa-eraser"></i></a>
</div>
{{/unless}}
<div class="filter-content extensible"> <div class="filter-content extensible">
<div class="wrapper"> <div class="wrapper">
{{#each fieldFilter}} {{#each fieldFilter}}
{{#if choices }} {{#if choices }}
<div class="form-group"> <div class="form-group"{{#with (lookup @root.presets.filter key)}}{{#if forced}} disabled{{/if}}{{/with}}>
<label>{{localize label}}</label> <label>{{localize label}}</label>
<div class="form-fields"> <div class="form-fields">
<select data-key="{{key}}" name={{name}}> <select data-key="{{key}}" name={{name}}>
{{selectOptions choices valueAttr="value" blank="" localize=true}} {{selectOptions choices valueAttr="value" blank="" localize=true selected=value}}
</select> </select>
</div> </div>
</div> </div>
{{else}} {{else}}
{{#if filtered }} {{#if filtered }}
{{formField field localize=true blank="" name=name choices=(@root.formatChoices this) valueAttr="value" dataset=(object key=key)}} {{formField field localize=true blank="" name=name choices=(@root.formatChoices this) valueAttr="value" dataset=(object key=key) value=value}}
{{else}} {{else}}
{{#if field.label}} {{#if field.label}}
{{formField field localize=true blank="" name=name dataset=(object key=key) value=""}} {{formField field localize=true blank="" name=name dataset=(object key=key) value=value}}
{{else}} {{else}}
{{formField field localize=true blank="" name=name dataset=(object key=key) label=label value=""}} {{formField field localize=true blank="" name=name dataset=(object key=key) label=label value=value}}
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}

View file

@ -1,4 +1,4 @@
<div class="compendium-sidebar"> <div class="compendium-sidebar" {{#if (or presets.render.lite presets.render.noFolder)}}style="display: none;"{{/if}}>
{{#each compendiums}} {{#each compendiums}}
<details class="compendium-container" data-compendium-id="{{id}}" open> <details class="compendium-container" data-compendium-id="{{id}}" open>
<summary> <summary>
@ -25,4 +25,4 @@
<line-div></line-div> <line-div></line-div>
</details> </details>
{{/each}} {{/each}}
</div> </div>