FEAT: add template to items sheet

This commit is contained in:
Joaquin Pereyra 2025-07-12 19:49:09 -03:00
parent 542742447d
commit 2e02d95afa
24 changed files with 283 additions and 457 deletions

View file

@ -223,19 +223,59 @@ export default function DHApplicationMixin(Base) {
* @type {ApplicationClickAction} * @type {ApplicationClickAction}
*/ */
static async #createDoc(event, target) { static async #createDoc(event, target) {
const { documentClass, type } = target.dataset; const { documentClass, type, inVault, disabled } = target.dataset;
const parent = this.document; const parentIsItem = this.document.documentName === 'Item';
const parent = parentIsItem && documentClass === 'Item' ? null : this.document;
const cls = getDocumentClass(documentClass); if (type === 'action') {
return await cls.createDocuments( const { type: actionType } = await foundry.applications.api.DialogV2.input({
[ window: { title: 'Select Action Type' },
{ content: await foundry.applications.handlebars.renderTemplate(
name: cls.defaultName({ type, parent }), 'systems/daggerheart/templates/actionTypes/actionType.hbs',
type { types: CONFIG.DH.ACTIONS.actionTypes }
),
ok: {
label: game.i18n.format('DOCUMENT.Create', {
type: game.i18n.localize('DAGGERHEART.GENERAL.Action.single')
}),
} }
], });
{ parent, renderSheet: !event.shiftKey } if (!actionType) return;
); const cls = game.system.api.models.actions.actionsTypes[actionType]
const action = new cls({
_id: foundry.utils.randomID(),
type: actionType,
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].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({
force: true
});
return action;
} else {
const cls = getDocumentClass(documentClass);
const data = {
name: cls.defaultName({ type, parent }),
type,
}
if (inVault) data["system.inVault"] = true;
if (disabled) data.disabled = true;
const doc = await cls.create(data, { parent, renderSheet: !event.shiftKey });
if (parentIsItem && type === 'feature') {
await this.document.update({
'system.features': [...this.document.system.features, doc]
});
}
return doc;
}
} }
/** /**
@ -244,9 +284,9 @@ export default function DHApplicationMixin(Base) {
*/ */
static #editDoc(_event, target) { static #editDoc(_event, target) {
const doc = getDocFromElement(target); const doc = getDocFromElement(target);
if (doc) return doc.sheet.render({ force: true });
// TODO: REDO this // TODO: REDO this
if (doc) return doc.sheet.render({ force: true });
const { actionId } = target.closest('[data-action-id]').dataset; const { actionId } = target.closest('[data-action-id]').dataset;
const { actions, attack } = this.document.system; const { actions, attack } = this.document.system;
const action = attack.id === actionId ? attack : actions?.find(a => a.id === actionId); const action = attack.id === actionId ? attack : actions?.find(a => a.id === actionId);

View file

@ -15,15 +15,13 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
classes: ['item'], classes: ['item'],
position: { width: 600 }, position: { width: 600 },
window: { resizable: true },
form: { form: {
submitOnChange: true submitOnChange: true
}, },
actions: { actions: {
addAction: DHBaseItemSheet.#addAction,
editAction: DHBaseItemSheet.#editAction,
removeAction: DHBaseItemSheet.#removeAction, removeAction: DHBaseItemSheet.#removeAction,
addFeature: DHBaseItemSheet.#addFeature, addFeature: DHBaseItemSheet.#addFeature,
editFeature: DHBaseItemSheet.#editFeature,
removeFeature: DHBaseItemSheet.#removeFeature removeFeature: DHBaseItemSheet.#removeFeature
}, },
dragDrop: [ dragDrop: [
@ -48,8 +46,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
/* -------------------------------------------- */ /* -------------------------------------------- */
/**@inheritdoc */ /**@inheritdoc */
async _preparePartContext(partId, context) { async _preparePartContext(partId, context, options) {
await super._preparePartContext(partId, context); await super._preparePartContext(partId, context, options);
const { TextEditor } = foundry.applications.ux; const { TextEditor } = foundry.applications.ux;
switch (partId) { switch (partId) {
@ -61,76 +59,37 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
secrets: this.item.isOwner secrets: this.item.isOwner
}); });
break; break;
case "effects":
await this._prepareEffectsContext(context, options)
break;
} }
return context; return context;
} }
/**
* Prepare render context for the Effect part.
* @param {ApplicationRenderContext} context
* @param {ApplicationRenderOptions} options
* @returns {Promise<void>}
* @protected
*/
async _prepareEffectsContext(context, _options) {
context.effects = {
actives: [],
inactives: [],
};
for (const effect of this.item.effects) {
const list = effect.active ? context.effects.actives : context.effects.inactives;
list.push(effect);
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Application Clicks Actions */ /* Application Clicks Actions */
/* -------------------------------------------- */ /* -------------------------------------------- */
/**
* Render a dialog prompting the user to select an action type.
*
* @returns {Promise<object>} An object containing the selected action type.
*/
static async selectActionType() {
const content = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/actionTypes/actionType.hbs',
{ types: CONFIG.DH.ACTIONS.actionTypes }
),
title = 'Select Action Type';
return foundry.applications.api.DialogV2.prompt({
window: { title },
content,
ok: {
label: title,
callback: (event, button, dialog) => button.form.elements.type.value
}
});
}
/**
* Add a new action to the item, prompting the user for its type.
* @type {ApplicationClickAction}
*/
static async #addAction(_event, _button) {
const actionType = await DHBaseItemSheet.selectActionType();
if (!actionType) return;
try {
const cls =
game.system.api.models.actions.actionsTypes[actionType] ??
game.system.api.models.actions.actionsTypes.attack,
action = new cls(
{
_id: foundry.utils.randomID(),
type: actionType,
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].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({
force: true
});
} catch (error) {
console.log(error);
}
}
/**
* Edit an existing action on the item
* @type {ApplicationClickAction}
*/
static async #editAction(_event, button) {
const action = this.document.system.actions[button.dataset.index];
await new DHActionConfig(action).render({ force: true });
}
/** /**
* Remove an action from the item. * Remove an action from the item.
@ -162,30 +121,16 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
* @type {ApplicationClickAction} * @type {ApplicationClickAction}
*/ */
static async #addFeature(_event, _button) { static async #addFeature(_event, _button) {
const feature = await game.items.documentClass.create({ const cls = foundry.documents.Item.implementation;
const feature = await cls.create({
type: 'feature', type: 'feature',
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) name: cls.defaultName({ type: 'feature' }),
}); });
await this.document.update({ await this.document.update({
'system.features': [...this.document.system.features.filter(x => x).map(x => x.uuid), feature.uuid] 'system.features': [...this.document.system.features, feature]
}); });
} }
/**
* Edit an existing feature on the item
* @type {ApplicationClickAction}
*/
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. * Remove a feature from the item.
* @type {ApplicationClickAction} * @type {ApplicationClickAction}

View file

@ -28,20 +28,4 @@ export default class BeastformSheet extends DHBaseItemSheet {
labelPrefix: 'DAGGERHEART.GENERAL.Tabs' labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
} }
}; };
/**@inheritdoc */
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.document = context.document.toObject();
context.document.effects = this.document.effects.map(effect => {
const data = effect.toObject();
data.id = effect.id;
if (effect.type === 'beastform') data.mandatory = true;
return data;
});
return context;
}
} }

View file

@ -10,10 +10,8 @@ export default class ClassSheet extends DHBaseItemSheet {
actions: { actions: {
removeItemFromCollection: ClassSheet.#removeItemFromCollection, removeItemFromCollection: ClassSheet.#removeItemFromCollection,
removeSuggestedItem: ClassSheet.#removeSuggestedItem, removeSuggestedItem: ClassSheet.#removeSuggestedItem,
viewDoc: ClassSheet.#viewDoc, addFeature: ClassSheet.#addFeature,
addFeature: this.addFeature, deleteFeature: ClassSheet.#deleteFeature
editFeature: this.editFeature,
deleteFeature: this.deleteFeature
}, },
tagifyConfigs: [ tagifyConfigs: [
{ {
@ -157,55 +155,27 @@ export default class ClassSheet extends DHBaseItemSheet {
await this.document.update({ [`system.characterGuide.${target}`]: null }); await this.document.update({ [`system.characterGuide.${target}`]: null });
} }
/** static async #addFeature(_, target) {
* Open the sheet of a item by UUID. const { actionPath } = target.dataset;
* @param {PointerEvent} _event - const cls = foundry.documents.Item.implementation;
* @param {HTMLElement} button
*/
static async #viewDoc(_event, button) {
const doc = await fromUuid(button.dataset.uuid);
doc.sheet.render({ force: true });
}
getActionPath(type) { const feature = await cls.create({
return type === 'hope' ? 'hopeFeatures' : 'classFeatures';
}
static async addFeature(_, target) {
const actionPath = this.getActionPath(target.dataset.type);
const feature = await game.items.documentClass.create({
type: 'feature', type: 'feature',
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) name: cls.defaultName({ type: 'feature'}),
}); });
await this.document.update({ await this.document.update({
[`system.${actionPath}`]: [ [`system.${actionPath}`]: [
...this.document.system[actionPath].filter(x => x).map(x => x.uuid), ...this.document.system[actionPath],
feature.uuid feature.uuid
] ]
}); });
} }
static async editFeature(_, button) { static async #deleteFeature(_, button) {
const target = button.closest('.feature-item'); const { actionPath, itemUuid } = button.dataset;
const actionPath = this.getActionPath(button.dataset.type);
const feature = this.document.system[actionPath].find(x => x?.id === target.dataset.featureId);
if (!feature) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
return;
}
feature.sheet.render(true);
}
static async deleteFeature(event, button) {
event.stopPropagation();
const target = button.closest('.feature-item');
const actionPath = this.getActionPath(button.dataset.type);
await this.document.update({ await this.document.update({
[`system.${actionPath}`]: this.document.system[actionPath] [`system.${actionPath}`]: this.document.system[actionPath].filter(f => f.uuid !== itemUuid)
.filter(feature => feature && feature.id !== target.dataset.featureId)
.map(x => x.uuid)
}); });
} }
} }

View file

@ -1,5 +1,3 @@
import { actionsTypes } from '../../../data/action/_module.mjs';
import DHActionConfig from '../../sheets-configs/action-config.mjs';
import DHBaseItemSheet from '../api/base-item.mjs'; import DHBaseItemSheet from '../api/base-item.mjs';
export default class FeatureSheet extends DHBaseItemSheet { export default class FeatureSheet extends DHBaseItemSheet {
@ -7,13 +5,7 @@ export default class FeatureSheet extends DHBaseItemSheet {
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
id: 'daggerheart-feature', id: 'daggerheart-feature',
classes: ['feature'], classes: ['feature'],
position: { height: 600 }, actions: {}
window: { resizable: true },
actions: {
addAction: FeatureSheet.#addAction,
editAction: FeatureSheet.#editAction,
removeAction: FeatureSheet.#removeAction
}
}; };
/**@override */ /**@override */
@ -39,92 +31,4 @@ export default class FeatureSheet extends DHBaseItemSheet {
labelPrefix: 'DAGGERHEART.GENERAL.Tabs' labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
} }
}; };
/* -------------------------------------------- */
/**@inheritdoc */
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
return context;
}
/* -------------------------------------------- */
/* Application Clicks Actions */
/* -------------------------------------------- */
/**
* Render a dialog prompting the user to select an action type.
*
* @returns {Promise<object>} An object containing the selected action type.
*/
static async selectActionType() {
const content = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/actionTypes/actionType.hbs',
{ types: CONFIG.DH.ACTIONS.actionTypes }
),
title = 'Select Action Type';
return foundry.applications.api.DialogV2.prompt({
window: { title },
content,
ok: {
label: title,
callback: (event, button, dialog) => button.form.elements.type.value
}
});
}
/**
* 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 FeatureSheet.selectActionType();
if (!actionType) return;
try {
const cls = actionsTypes[actionType] ?? actionsTypes.attack,
action = new cls(
{
_id: foundry.utils.randomID(),
type: actionType,
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].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({
force: 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({ force: 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();
const actionIndex = button.closest('[data-index]').dataset.index;
await this.document.update({
'system.actions': this.document.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex))
});
}
} }

View file

@ -8,7 +8,6 @@ export default class SubclassSheet extends DHBaseItemSheet {
window: { resizable: false }, window: { resizable: false },
actions: { actions: {
addFeature: this.addFeature, addFeature: this.addFeature,
editFeature: this.editFeature,
deleteFeature: this.deleteFeature deleteFeature: this.deleteFeature
} }
}; };
@ -38,30 +37,20 @@ export default class SubclassSheet extends DHBaseItemSheet {
}; };
static async addFeature(_, target) { static async addFeature(_, target) {
const feature = await game.items.documentClass.create({ const cls = foundry.documents.Item.implementation;
const feature = await cls.create({
type: 'feature', type: 'feature',
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) name: cls.defaultName({ type: 'feature' }),
}); });
await this.document.update({ await this.document.update({
[`system.${target.dataset.type}`]: feature.uuid [`system.${target.dataset.type}`]: feature
}); });
} }
static async editFeature(_, button) { static async deleteFeature(_, button) {
const feature = this.document.system[button.dataset.type];
if (!feature) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing'));
return;
}
feature.sheet.render(true);
}
static async deleteFeature(event, button) {
event.stopPropagation();
await this.document.update({ await this.document.update({
[`system.${button.dataset.type}`]: null [`system.${button.dataset.actionPath}`]: null
}); });
} }

View file

@ -5,6 +5,7 @@
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.actives collection=effects.actives
canCreate=true
}} }}
{{> 'daggerheart.inventory-items' {{> 'daggerheart.inventory-items'
@ -12,5 +13,6 @@
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.inactives collection=effects.inactives
canCreate=true
}} }}
</section> </section>

View file

@ -6,6 +6,7 @@
type='feature' type='feature'
collection=document.system.features collection=document.system.features
hideControls=true hideControls=true
canCreate=true
}} }}
</div> </div>
</section> </section>

View file

@ -6,6 +6,7 @@
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.actives collection=effects.actives
canCreate=true
}} }}
{{> 'daggerheart.inventory-items' {{> 'daggerheart.inventory-items'
@ -13,5 +14,6 @@
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.inactives collection=effects.inactives
canCreate=true
}} }}
</section> </section>

View file

@ -8,6 +8,7 @@
title=category.title title=category.title
type='feature' type='feature'
collection=category.values collection=category.values
canCreate=true
}} }}
{{/if}} {{/if}}

View file

@ -1,8 +1,5 @@
<section <section class='tab {{tabs.inventory.cssClass}} {{tabs.inventory.id}}' data-tab='{{tabs.inventory.id}}'
class='tab {{tabs.inventory.cssClass}} {{tabs.inventory.id}}' data-group='{{tabs.inventory.group}}'>
data-tab='{{tabs.inventory.id}}'
data-group='{{tabs.inventory.group}}'
>
<div class="search-section"> <div class="search-section">
<div class="search-bar"> <div class="search-bar">
<div class="icon"> <div class="icon">
@ -16,22 +13,34 @@
</div> </div>
<div class="items-section"> <div class="items-section">
{{> 'daggerheart.inventory-items' title='TYPES.Item.weapon' {{> 'daggerheart.inventory-items'
title='TYPES.Item.weapon'
type='weapon' type='weapon'
collection=document.itemTypes.weapon collection=document.itemTypes.weapon
isGlassy=true}} isGlassy=true
{{> 'daggerheart.inventory-items' title='TYPES.Item.armor' canCreate=true
}}
{{> 'daggerheart.inventory-items'
title='TYPES.Item.armor'
type='armor' type='armor'
collection=document.itemTypes.armor collection=document.itemTypes.armor
isGlassy=true}} isGlassy=true
{{> 'daggerheart.inventory-items' title='TYPES.Item.consumable' canCreate=true
}}
{{> 'daggerheart.inventory-items'
title='TYPES.Item.consumable'
type='consumable' type='consumable'
collection=document.itemTypes.consumable collection=document.itemTypes.consumable
isGlassy=true}} isGlassy=true
{{> 'daggerheart.inventory-items' title='TYPES.Item.miscellaneous' canCreate=true
}}
{{> 'daggerheart.inventory-items'
title='TYPES.Item.miscellaneous'
type='miscellaneous' type='miscellaneous'
collection=document.itemTypes.miscellaneous collection=document.itemTypes.miscellaneous
isGlassy=true}} isGlassy=true
canCreate=true
}}
</div> </div>
<div class="currency-section"> <div class="currency-section">

View file

@ -27,14 +27,16 @@
isGlassy=true isGlassy=true
cardView=cardView cardView=cardView
collection=document.system.domainCards.loadout collection=document.system.domainCards.loadout
canCreate=true
}} }}
{{> 'daggerheart.inventory-items' {{> 'daggerheart.inventory-items'
title='DAGGERHEART.GENERAL.Tabs.vault' title='DAGGERHEART.GENERAL.Tabs.vault'
type='domainCard' type='domainCard'
isGlassy=true isGlassy=true
cardView=cardView cardView=cardView
collection=document.system.domainCards.vault collection=document.system.domainCards.vault
canCreate=true
inVault=true
}} }}
</div> </div>
</section> </section>

View file

@ -1,13 +1,12 @@
<section <section class='tab {{tabs.effects.cssClass}} {{tabs.effects.id}}' data-tab='{{tabs.effects.id}}'
class='tab {{tabs.effects.cssClass}} {{tabs.effects.id}}' data-group='{{tabs.effects.group}}'>
data-tab='{{tabs.effects.id}}'
data-group='{{tabs.effects.group}}'
>
{{> 'daggerheart.inventory-items' {{> 'daggerheart.inventory-items'
title='DAGGERHEART.GENERAL.activeEffects' title='DAGGERHEART.GENERAL.activeEffects'
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.actives collection=effects.actives
canCreate=true
}} }}
{{> 'daggerheart.inventory-items' {{> 'daggerheart.inventory-items'
@ -15,5 +14,6 @@
type='effect' type='effect'
isGlassy=true isGlassy=true
collection=effects.inactives collection=effects.inactives
canCreate=true
}} }}
</section> </section>

View file

@ -9,6 +9,7 @@
type='feature' type='feature'
collection=document.system.features collection=document.system.features
hideControls=true hideControls=true
canCreate=true
}} }}
</div> </div>
</section> </section>

View file

@ -2,30 +2,16 @@
<img src="{{item.img}}" data-action="useItem" class="card-img" /> <img src="{{item.img}}" data-action="useItem" class="card-img" />
<div class="card-label"> <div class="card-label">
<div class="controls"> <div class="controls">
{{#if (eq type 'weapon')}} <a data-action="toggleVault"
<a class="{{#unless item.system.equipped}}unequipped{{/unless}}" data-action="toggleEquipItem" data-tooltip="{{#unless item.system.equipped}}{{localize 'DAGGERHEART.UI.Tooltip.equip'}}{{else}}{{localize 'DAGGERHEART.UI.Tooltip.unequip'}}{{/unless}}"> data-tooltip="DAGGERHEART.UI.Tooltip.{{ifThen item.system.inVault 'sendToLoadout' 'sendToVault' }}">
<i class="fa-solid fa-hands"></i> <i class="fa-solid {{ifThen item.system.inVault 'fa-arrow-up' 'fa-arrow-down'}}"></i>
</a> </a>
{{/if}} <a data-action="toChat" data-tooltip="DAGGERHEART.UI.Tooltip.sendToChat">
{{#if (eq type 'armor')}} <i class="fa-regular fa-message"></i>
<a class="{{#unless item.system.equipped}}unequipped{{/unless}}" data-action="toggleEquipItem" data-tooltip="{{#unless item.system.equipped}}{{localize 'DAGGERHEART.UI.Tooltip.equip'}}{{else}}{{localize 'DAGGERHEART.UI.Tooltip.unequip'}}{{/unless}}"> </a>
<i class="fa-solid fa-shield"></i> <a data-action="triggerContextMenu" data-tooltip="DAGGERHEART.UI.Tooltip.moreOptions">
</a> <i class="fa-solid fa-ellipsis-vertical"></i>
{{/if}} </a>
{{#if (eq type 'domainCard')}}
{{#unless item.system.inVault}}
<a data-action="toggleVault" data-tooltip="{{localize 'DAGGERHEART.UI.Tooltip.sendToVault'}}">
<i class="fa-solid fa-arrow-down"></i>
</a>
{{else}}
<a data-action="toggleVault" data-tooltip="{{localize 'DAGGERHEART.UI.Tooltip.sendToLoadout'}}">
<i class="fa-solid fa-arrow-up"></i>
</a>
{{/unless}}
{{/if}}
<a data-action="toChat" data-tooltip="{{localize 'DAGGERHEART.UI.Tooltip.sendToChat'}}"><i class="fa-regular fa-message"></i></a>
<a data-action="triggerContextMenu" data-tooltip="{{localize 'DAGGERHEART.UI.Tooltip.moreOptions'}}"><i class="fa-solid fa-ellipsis-vertical"></i></a>
</div> </div>
<div class="card-name">{{item.name}}</div> <div class="card-name">{{item.name}}</div>
</div> </div>

View file

@ -1,30 +1,20 @@
<li class='feature-item' data-feature-id='{{feature.id}}'> <li class='feature-item' data-item-uuid='{{feature.uuid}}'>
<div class='feature-line'> <div class='feature-line'>
<img class='image' src='{{feature.img}}' /> <img class='image' src='{{feature.img}}' />
<h4> <h4>
{{feature.name}} {{feature.name}}
</h4> </h4>
{{#unless hideContrals}} {{#unless hideContrals}}
<div class='controls'> <div class='controls'>
<a <a class='effect-control' data-action='editDoc' data-action-path='{{actionPath}}'
class='effect-control' data-tooltip="DAGGERHEART.UI.Tooltip.openItemWorld">
data-action='editFeature' <i class="fa-solid fa-globe"></i>
data-feature='{{feature._id}}' </a>
data-type='{{type}}' <a class='effect-control' data-action='deleteFeature' data-item-uuid='{{feature.uuid}}' data-action-path='{{actionPath}}'
data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}' data-tooltip="CONTROLS.CommonDelete">
> <i class='fas fa-trash'></i>
<i class="fa-solid fa-globe"></i> </a>
</a> </div>
<a
class='effect-control'
data-action='deleteFeature'
data-feature='{{feature._id}}'
data-type='{{type}}'
data-tooltip='{{localize "CONTROLS.CommonDelete"}}'
>
<i class='fas fa-trash'></i>
</a>
</div>
{{/unless}} {{/unless}}
</div> </div>
</li> </li>

View file

@ -11,6 +11,8 @@ Parameters:
- cardView {boolean} : If true and type is 'domainCard', renders using domain card layout. - cardView {boolean} : If true and type is 'domainCard', renders using domain card layout.
- isActor {boolean} : Passed through to inventory-item partials. - isActor {boolean} : Passed through to inventory-item partials.
- canCreate {boolean} : If true, show createDoc anchor on legend - canCreate {boolean} : If true, show createDoc anchor on legend
- inVault {boolean} : If true, the domainCard is created with inVault=true
- disabled {boolean}: If true, the ActiveEffect is created with disabled=true;
- categoryAdversary {string} : Category adversary id. - categoryAdversary {string} : Category adversary id.
- showLabels {boolean} : If true, show label-tags else show simple tags. - showLabels {boolean} : If true, show label-tags else show simple tags.
- hideTooltip {boolean} : If true, disables the tooltip on the item image. - hideTooltip {boolean} : If true, disables the tooltip on the item image.
@ -22,7 +24,12 @@ Parameters:
<legend> <legend>
{{localize title}} {{localize title}}
{{#if canCreate}} {{#if canCreate}}
<a data-action="createDoc" data-type="{{type}}"> <a data-action="createDoc" data-document-class="{{ifThen (eq type 'effect') 'ActiveEffect' 'Item' }}"
data-type="{{ifThen (eq type 'effect') 'base' type}}"
{{#if inVault}}data-in-vault="{{inVault}}"{{/if}}
{{#if disabled}} data-disabled="{{disabled}}"{{/if}}
data-tooltip="{{localize 'DOCUMENT.Create' type=''}}"
>
<i class="fa-solid fa-plus icon-button"></i> <i class="fa-solid fa-plus icon-button"></i>
</a> </a>
{{/if }} {{/if }}
@ -33,7 +40,7 @@ Parameters:
{{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs'
item=item item=item
type=../type type='domainCard'
}} }}
{{/each}} {{/each}}

View file

@ -28,7 +28,22 @@ Parameters:
{{!-- Weapon Block Start --}} {{!-- Weapon Block Start --}}
{{#if (eq type 'weapon')}} {{#if (eq type 'weapon')}}
{{#if (not hideTags)}} {{#if (not hideTags)}}
<div class="item-tags"></div> <div class="item-tags">
<div class="tag">
{{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}}
</div>
<div class="tag">
{{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}}
</div>
<div class="tag">
{{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} +
{{item.system.attack.damage.parts.0.value.bonus}}{{/if}}
({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' item.system.attack.damage.parts.0.type '.abbreviation')}})
</div>
<div class="tag">
{{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}}
</div>
</div>
{{else if (not hideLabels)}} {{else if (not hideLabels)}}
<div class="item-labels"> <div class="item-labels">
<div class="label"> <div class="label">
@ -158,7 +173,7 @@ Parameters:
<i class="fa-solid {{ifThen item.system.inVault 'fa-arrow-up' 'fa-arrow-down'}}"></i> <i class="fa-solid {{ifThen item.system.inVault 'fa-arrow-up' 'fa-arrow-down'}}"></i>
</a> </a>
{{/if}} {{/if}}
{{!-- I had to use the {{not}} helper because otherwise the function is called when rendering --}} {{!-- I had to use the {{not}} helper because otherwise the function is called when rendering --}}
{{#unless (not item.toChat)}} {{#unless (not item.toChat)}}
<a data-action="toChat" data-tooltip="DAGGERHEART.UI.Tooltip.sendToChat"> <a data-action="toChat" data-tooltip="DAGGERHEART.UI.Tooltip.sendToChat">
<i class="fa-regular fa-message"></i> <i class="fa-regular fa-message"></i>

View file

@ -3,21 +3,11 @@
data-tab='{{tabs.actions.id}}' data-tab='{{tabs.actions.id}}'
data-group='{{tabs.actions.group}}' data-group='{{tabs.actions.group}}'
> >
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.Action.plural"}} <a><i class="fa-solid fa-plus icon-button" data-action="addAction"></i></a></legend> {{> 'daggerheart.inventory-items'
<div class="actions-list"> title='DAGGERHEART.GENERAL.Action.plural'
{{#each document.system.actions as |action index|}} collection=document.system.actions
<div class="action-item" type='action'
data-action="editAction" canCreate=true
data-index="{{index}}" }}
>
<img class="image" src="{{action.img}}" />
<span>{{action.name}}</span>
<div class="controls">
<a data-action="removeAction"><i class="fa-solid fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</section> </section>

View file

@ -1,26 +1,19 @@
<section <section class='tab {{tabs.effects.cssClass}} {{tabs.effects.id}}' data-tab='{{tabs.effects.id}}'
class='tab {{tabs.effects.cssClass}} {{tabs.effects.id}}' data-group='{{tabs.effects.group}}'>
data-tab='{{tabs.effects.id}}'
data-group='{{tabs.effects.group}}' {{> 'daggerheart.inventory-items'
> title='DAGGERHEART.GENERAL.activeEffects'
<fieldset class="one-column"> type='effect'
<legend> isGlassy=true
{{localize "DAGGERHEART.GENERAL.Effect.plural"}} collection=effects.actives
<a data-action="createDoc" data-document-class="ActiveEffect" data-type="base"> canCreate=true
<i class="fa-solid fa-plus icon-button"></i> }}
</a>
</legend> {{> 'daggerheart.inventory-items'
<div class="effects-list"> title='DAGGERHEART.GENERAL.inactiveEffects'
{{#each document.effects as |effect|}} type='effect'
<div class="effect-item"> isGlassy=true
<img class="image" src="{{effect.img}}" /> collection=effects.inactives
<span>{{effect.name}}</span> canCreate=true
<div class="controls"> }}
<a data-action="editDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}"><i class="fa-solid fa-pen-to-square"></i></a>
<a data-action="deleteDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}" {{disabled effect.mandatory}}><i class="fa-solid fa-trash icon-button {{disabled effect.mandatory}}"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</section> </section>

View file

@ -1,23 +1,10 @@
<section <section class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-tab='{{tabs.features.id}}'
class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-group='{{tabs.features.group}}'>
data-tab='{{tabs.features.id}}' {{> 'daggerheart.inventory-items'
data-group='{{tabs.features.group}}' title='DAGGERHEART.GENERAL.features'
> type='feature'
<fieldset class="one-column drop-section"> isGlassy=true
<legend>{{localize "DAGGERHEART.GENERAL.features"}} <a><i data-action="addFeature" class="fa-solid fa-plus icon-button"></i></a></legend> collection=document.system.features
<div class="features-list"> canCreate=true
{{#each document.system.features as |feature|}} }}
<div class="feature-item"
data-action="editFeature"
id="{{feature.id}}"
>
<img class="image" src="{{feature.img}}" />
<span>{{feature.name}}</span>
<div class="controls">
<a data-action="removeFeature" id="{{feature.id}}"><i class="fa-solid fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</section> </section>

View file

@ -1,23 +1,32 @@
<section <section class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-tab='{{tabs.features.id}}'
class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-group='{{tabs.features.group}}'>
data-tab='{{tabs.features.id}}'
data-group='{{tabs.features.group}}'
>
<div class="two-columns even"> <div class="two-columns even">
<fieldset> <fieldset>
<legend>{{localize "DAGGERHEART.ITEMS.Class.hopeFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="hope" data-action="addFeature"></i></a></legend> <legend>
{{localize "DAGGERHEART.ITEMS.Class.hopeFeatures"}}
<a data-action-path="hopeFeatures" data-action="addFeature">
<i class="fa-solid fa-plus icon-button"></i>
</a>
</legend>
<div class="feature-list"> <div class="feature-list">
{{#each source.system.hopeFeatures as |feature|}} {{#each source.system.hopeFeatures as |feature|}}
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='hope' feature=feature}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
actionPath='hopeFeatures' feature=feature}}
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{{localize "DAGGERHEART.ITEMS.Class.classFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="class" data-action="addFeature"></i></a></legend> <legend>
{{localize "DAGGERHEART.ITEMS.Class.classFeatures"}}
<a data-action-path="classFeatures" data-action="addFeature">
<i class="fa-solid fa-plus icon-button"></i>
</a>
</legend>
<div class="feature-list"> <div class="feature-list">
{{#each source.system.classFeatures as |feature|}} {{#each source.system.classFeatures as |feature|}}
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='class' feature=feature}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
actionPath='classFeatures' feature=feature}}
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
@ -27,34 +36,25 @@
<legend>{{localize "TYPES.Item.subclass"}}</legend> <legend>{{localize "TYPES.Item.subclass"}}</legend>
<div class="feature-list"> <div class="feature-list">
{{#each source.system.subclasses as |subclass index|}} {{#each source.system.subclasses as |subclass index|}}
<li class='feature-item'> <li class='feature-item'>
<div class='feature-line'> <div class='feature-line'>
<img class='image' src='{{subclass.img}}' /> <img class='image' src='{{subclass.img}}' />
<h4> <h4>
{{subclass.name}} {{subclass.name}}
</h4> </h4>
<div class='controls'> <div class='controls'>
<a <a class='effect-control' data-action='viewDoc' data-uuid={{subclass.uuid}}
class='effect-control' data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}'>
data-action='viewDoc' <i class="fa-solid fa-globe"></i>
data-uuid={{subclass.uuid}} </a>
data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}' <a class='effect-control' data-action='removeItemFromCollection' data-target="subclasses"
> data-uuid={{subclass.uuid}} data-tooltip='{{localize "CONTROLS.CommonDelete"}}'>
<i class="fa-solid fa-globe"></i> <i class='fas fa-trash'></i>
</a> </a>
<a
class='effect-control'
data-action='removeItemFromCollection'
data-target="subclasses"
data-uuid={{subclass.uuid}}
data-tooltip='{{localize "CONTROLS.CommonDelete"}}'
>
<i class='fas fa-trash'></i>
</a>
</div>
</div> </div>
</li> </div>
</li>
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
</div> </div>

View file

@ -38,7 +38,7 @@
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedPrimaryWeaponTitle"}}</legend> <legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedPrimaryWeaponTitle"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#if document.system.characterGuide.suggestedPrimaryWeapon}} {{#if document.system.characterGuide.suggestedPrimaryWeapon}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{document.system.characterGuide.suggestedPrimaryWeapon.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{document.system.characterGuide.suggestedPrimaryWeapon.uuid}}">
<img class="image" src="{{document.system.characterGuide.suggestedPrimaryWeapon.img}}" /> <img class="image" src="{{document.system.characterGuide.suggestedPrimaryWeapon.img}}" />
<span>{{document.system.characterGuide.suggestedPrimaryWeapon.name}}</span> <span>{{document.system.characterGuide.suggestedPrimaryWeapon.name}}</span>
<div class="controls"> <div class="controls">
@ -53,7 +53,7 @@
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}</legend> <legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#if document.system.characterGuide.suggestedSecondaryWeapon}} {{#if document.system.characterGuide.suggestedSecondaryWeapon}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{system.system.characterGuide.suggestedSecondaryWeapon.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{system.system.characterGuide.suggestedSecondaryWeapon.uuid}}">
<img class="image" src="{{document.system.characterGuide.suggestedSecondaryWeapon.img}}" /> <img class="image" src="{{document.system.characterGuide.suggestedSecondaryWeapon.img}}" />
<span>{{document.system.characterGuide.suggestedSecondaryWeapon.name}}</span> <span>{{document.system.characterGuide.suggestedSecondaryWeapon.name}}</span>
<div class="controls"> <div class="controls">
@ -68,7 +68,7 @@
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedArmorTitle"}}</legend> <legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedArmorTitle"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#if document.system.characterGuide.suggestedArmor}} {{#if document.system.characterGuide.suggestedArmor}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{document.system.characterGuide.suggestedArmor.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{document.system.characterGuide.suggestedArmor.uuid}}">
<img class="image" src="{{document.system.characterGuide.suggestedArmor.img}}" /> <img class="image" src="{{document.system.characterGuide.suggestedArmor.img}}" />
<span>{{document.system.characterGuide.suggestedArmor.name}}</span> <span>{{document.system.characterGuide.suggestedArmor.name}}</span>
<div class="controls"> <div class="controls">
@ -86,7 +86,7 @@
<legend>{{localize "DAGGERHEART.GENERAL.take"}}</legend> <legend>{{localize "DAGGERHEART.GENERAL.take"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#each source.system.inventory.take}} {{#each source.system.inventory.take}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{this.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
<img class="image" src="{{this.img}}" /> <img class="image" src="{{this.img}}" />
<span>{{this.name}}</span> <span>{{this.name}}</span>
<div class="controls"> <div class="controls">
@ -101,7 +101,7 @@
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}</legend> <legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#each source.system.inventory.choiceA}} {{#each source.system.inventory.choiceA}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{this.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
<img class="image" src="{{this.img}}" /> <img class="image" src="{{this.img}}" />
<span>{{this.name}}</span> <span>{{this.name}}</span>
<div class="controls"> <div class="controls">
@ -116,7 +116,7 @@
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}</legend> <legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}</legend>
<div class="drop-section-body list-items"> <div class="drop-section-body list-items">
{{#each source.system.inventory.choiceB}} {{#each source.system.inventory.choiceB}}
<div class="suggested-item item-line" data-action="viewDoc" data-uuid="{{this.uuid}}"> <div class="suggested-item item-line" data-action="editDoc" data-item-uuid="{{this.uuid}}">
<img class="image" src="{{this.img}}" /> <img class="image" src="{{this.img}}" />
<span>{{this.name}}</span> <span>{{this.name}}</span>
<div class="controls"> <div class="controls">

View file

@ -1,17 +1,20 @@
<section <section class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-tab='{{tabs.features.id}}'
class='tab {{tabs.features.cssClass}} {{tabs.features.id}}' data-group='{{tabs.features.group}}'>
data-tab='{{tabs.features.id}}'
data-group='{{tabs.features.group}}'
>
<fieldset class="drop-section" data-type="foundationFeature"> <fieldset class="drop-section" data-type="foundationFeature">
<legend> <legend>
{{localize "DAGGERHEART.GENERAL.Tabs.foundation"}} {{localize "DAGGERHEART.GENERAL.Tabs.foundation"}}
<a {{#if source.system.foundationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="foundationFeature" class="fa-solid fa-plus icon-button {{#if source.system.foundationFeature}}disabled{{/if}}"></i></a> <a {{disabled source.system.foundationFeature}}>
<i data-action="addFeature" data-type="foundationFeature"
class="fa-solid fa-plus icon-button {{disabled source.system.foundationFeature}}"></i>
</a>
</legend> </legend>
<div class="feature-list"> <div class="feature-list">
{{#if source.system.foundationFeature}} {{#if source.system.foundationFeature}}
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundationFeature' feature=source.system.foundationFeature}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
actionPath='foundationFeature'
feature=source.system.foundationFeature
}}
{{/if}} {{/if}}
</div> </div>
</fieldset> </fieldset>
@ -19,12 +22,15 @@
<fieldset class="drop-section" data-type="specializationFeature"> <fieldset class="drop-section" data-type="specializationFeature">
<legend> <legend>
{{localize "DAGGERHEART.GENERAL.Tabs.specialization"}} {{localize "DAGGERHEART.GENERAL.Tabs.specialization"}}
<a {{#if source.system.specializationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="specializationFeature" class="fa-solid fa-plus icon-button {{#if source.system.specializationFeature}}disabled{{/if}}"></i></a> <a {{disabled source.system.specializationFeature}}><i data-action="addFeature"
data-type="specializationFeature"
class="fa-solid fa-plus icon-button {{disabled source.system.specializationFeature}}"></i></a>
</legend> </legend>
<div class="feature-list"> <div class="feature-list">
{{#if source.system.specializationFeature}} {{#if source.system.specializationFeature}}
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specializationFeature' feature=source.system.specializationFeature}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
actionPath='specializationFeature' feature=source.system.specializationFeature}}
{{/if}} {{/if}}
</div> </div>
</fieldset> </fieldset>
@ -32,12 +38,14 @@
<fieldset class="drop-section" data-type="masteryFeature"> <fieldset class="drop-section" data-type="masteryFeature">
<legend> <legend>
{{localize "DAGGERHEART.GENERAL.Tabs.mastery"}} {{localize "DAGGERHEART.GENERAL.Tabs.mastery"}}
<a {{#if source.system.masteryFeature}}disabled{{/if}}><i data-action="addFeature" data-type="masteryFeature" class="fa-solid fa-plus icon-button {{#if source.system.masteryFeature}}disabled{{/if}}"></i></a> <a {{disabled source.system.masteryFeature}}><i data-action="addFeature" data-type="masteryFeature"
class="fa-solid fa-plus icon-button {{disabled source.system.masteryFeature}}"></i></a>
</legend> </legend>
<div class="feature-list"> <div class="feature-list">
{{#if source.system.masteryFeature}} {{#if source.system.masteryFeature}}
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='masteryFeature' feature=source.system.masteryFeature}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
actionPath='masteryFeature' feature=source.system.masteryFeature}}
{{/if}} {{/if}}
</div> </div>
</fieldset> </fieldset>