Compare commits

...

5 commits

Author SHA1 Message Date
2c4dbb2620
fix: remove unused parameter in weapon callback
- Remove unused _dialog parameter from weapon attack type selection callback
- Resolves ESLint error: '_dialog' is defined but never used
- Maintains functionality while improving code quality

This fixes the npm run lint:fix error and ensures clean ESLint compliance.
2025-07-28 22:20:29 +02:00
e021fedcdf
style: fix code formatting inconsistencies
- Remove excessive blank lines (triple+ newlines reduced to double)
- Fix EditorConfig indent_size from 4 to 2 spaces to match Prettier
- Ensure consistent whitespace formatting across JavaScript/TypeScript files
- Clean up formatting in templates (HBS files)

Files affected:
- src/apps/actor/base-sheet.js: Remove 6 instances of triple+ blank lines
- src/apps/item-sheet.js: Remove 4 instances of triple+ blank lines
- src/apps/ruler/token-ruler.js: Remove 1 instance of triple+ blank lines
- src/hooks/hooks.ts: Remove 1 instance of triple+ blank lines
- templates/sheets/actor/*.hbs: Remove excessive blank lines
- .editorconfig: Fix indent_size to match Prettier tabWidth (2 spaces)
2025-07-28 22:18:44 +02:00
7fcdcf8a5c
fix: correct effects display in item sheet template
- Fix item sheet effects template to use enrichedEffects instead of data.effects
- Ensures effects are properly displayed in the item sheet effects tab
- Aligns with actor sheet implementation for consistency

The template was referencing data.effects but the context preparation creates
enrichedEffects array with additional metadata (id, uuid, sourceName).
2025-07-28 22:14:41 +02:00
f807b59c9a
fix: add missing localization keys for sheet titles
- Add DS4.ActorSheet localization key ("Aktorbogen" / "Actor Sheet")
- Add DS4.ItemSheet localization key ("Itembogen" / "Item Sheet")

These keys are used in the get title() methods of DS4ActorSheet and DS4ItemSheet
to display properly localized sheet window titles instead of showing the raw
localization key strings.

Both keys are placed logically near other Actor/Item-related localization entries
for consistency.
2025-07-28 22:01:00 +02:00
3eaf69f558
fix: remove duplicate action handlers and improve template action generation
- Remove duplicate action handlers (edititem, deleteitem, createitem, etc.) from DS4ActorSheet and DS4ItemSheet
- Fix editImage method reference from static to prototype in DS4ActorSheet
- Add capitalize helper to handlebars-helpers.ts for dynamic action name generation
- Update control-button-group.hbs and add-button.hbs templates to use concat and capitalize helpers
- Ensure consistent camelCase naming for all action handlers (editItem, deleteItem, createItem, etc.)

This resolves action handler conflicts and improves maintainability by using dynamic template generation
instead of hardcoded conditional logic.
2025-07-28 21:55:06 +02:00
24 changed files with 128 additions and 138 deletions

View file

@ -8,6 +8,6 @@ root = true
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true

View file

@ -184,7 +184,9 @@
"DS4.EffectFactor": "Faktor (wie oft der Effekt angewendet wird)",
"DS4.EffectFactorAbbr": "F",
"DS4.ActorName": "Name",
"DS4.ActorSheet": "Aktorbogen",
"DS4.ActorImageAltText": "Bild des Aktors",
"DS4.ItemSheet": "Itembogen",
"DS4.ActorTypeCharacter": "Charakter",
"DS4.ActorTypeCreature": "Kreatur",
"DS4.Attribute": "Attribut",

View file

@ -184,7 +184,9 @@
"DS4.EffectFactor": "Factor (the number of times the effect is being applied)",
"DS4.EffectFactorAbbr": "F",
"DS4.ActorName": "Name",
"DS4.ActorSheet": "Actor Sheet",
"DS4.ActorImageAltText": "Image of the Actor",
"DS4.ItemSheet": "Item Sheet",
"DS4.ActorTypeCharacter": "Character",
"DS4.ActorTypeCreature": "Creature",
"DS4.Attribute": "Attribute",

View file

@ -53,7 +53,8 @@
/* Icon animations */
@keyframes pulse {
0%, 100% {
0%,
100% {
opacity: 1;
}
50% {

View file

@ -6,7 +6,6 @@
@use "./colors";
$padding-sm: 5px;
$padding-md: 10px;
$padding-lg: 20px;

View file

@ -6,12 +6,12 @@
//
// SPDX-License-Identifier: MIT
/**
* The base sheet class for DS4 Actor Sheets
*/
export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.sheets.ActorSheetV2,
) {
static DEFAULT_OPTIONS = {
classes: ["sheet", "ds4-actor-sheet", "themed"],
tag: "form",
@ -41,14 +41,7 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
changeEffect: DS4ActorSheet.prototype._onChangeEffect,
sortItems: DS4ActorSheet.prototype._onSortItems,
changeTab: DS4ActorSheet.prototype._onChangeTab,
edititem: DS4ActorSheet.prototype._onEditItem,
deleteitem: DS4ActorSheet.prototype._onDeleteItem,
createitem: DS4ActorSheet.prototype._onCreateItem,
editeffect: DS4ActorSheet.prototype._onEditEffect,
deleteeffect: DS4ActorSheet.prototype._onDeleteEffect,
createeffect: DS4ActorSheet.prototype._onCreateEffect,
editImage: DS4ActorSheet._onEditImage,
editImage: DS4ActorSheet.prototype._onEditImage,
},
};
@ -65,14 +58,14 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
/** @override */
get template() {
const templatePath = !game.user?.isGM && this.document.limited
? "systems/ds4/templates/sheets/actor/limited-sheet.hbs"
: `systems/ds4/templates/sheets/actor/${this.document.type}-sheet.hbs`;
const templatePath =
!game.user?.isGM && this.document.limited
? "systems/ds4/templates/sheets/actor/limited-sheet.hbs"
: `systems/ds4/templates/sheets/actor/${this.document.type}-sheet.hbs`;
return templatePath;
}
/** @override */
async _renderHTML(context) {
return await foundry.applications.handlebars.renderTemplate(this.template, context);
@ -83,8 +76,6 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
content.innerHTML = result;
}
/** @override */
async _prepareContext(options) {
const context = await super._prepareContext(options);
@ -94,8 +85,6 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
throw new Error("Document not available for sheet rendering");
}
// Add document data
context.data = this.document;
context.system = this.document.system;
@ -111,8 +100,6 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
showSlayerPoints: game.settings.get("ds4", "showSlayerPoints") || false,
};
// Add items organized by type
context.itemsByType = {};
if (this.document.items && this.document.items.size > 0) {
@ -352,7 +339,6 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
}
}
/**
* Handle changing an item property
* @param {Event} event - The triggering event
@ -484,8 +470,6 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
}
}
/**
* Handle sorting items
* @param {Event} event - The triggering event
@ -497,7 +481,7 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
if (!dataPath || !itemType) return;
const items = this.document.items.filter(item => item.type === itemType);
const items = this.document.items.filter((item) => item.type === itemType);
const sortedItems = this.sortItems(items, dataPath);
const updates = sortedItems.map((item, index) => ({
@ -549,13 +533,13 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
if (!nav || !sheet) return;
// Update navigation active state
nav.querySelectorAll(".ds4-sheet-tab-nav__item").forEach(item => {
nav.querySelectorAll(".ds4-sheet-tab-nav__item").forEach((item) => {
item.classList.remove("active");
});
target.classList.add("active");
// Update tab content visibility
sheet.querySelectorAll(".ds4-sheet-tab").forEach(tabContent => {
sheet.querySelectorAll(".ds4-sheet-tab").forEach((tabContent) => {
tabContent.classList.remove("active");
});
@ -589,8 +573,8 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
const tabContents = sheet.querySelectorAll(".ds4-sheet-tab");
// Remove active class from all items first
navItems.forEach(item => item.classList.remove("active"));
tabContents.forEach(content => content.classList.remove("active"));
navItems.forEach((item) => item.classList.remove("active"));
tabContents.forEach((content) => content.classList.remove("active"));
// Find the currently active tab or default to first
let targetTab = this.activeTab;
@ -626,7 +610,7 @@ export class DS4ActorSheet extends foundry.applications.api.HandlebarsApplicatio
const fp = new foundry.applications.apps.FilePicker({
type: "image",
current: current,
callback: (path) => this.document.update({ [field]: path })
callback: (path) => this.document.update({ [field]: path }),
});
return fp.browse();

View file

@ -25,7 +25,7 @@ export class DS4CharacterActorSheet extends DS4ActorSheet {
{
async: true,
relativeTo: this.document,
}
},
);
}

View file

@ -25,7 +25,7 @@ export class DS4CreatureActorSheet extends DS4ActorSheet {
{
async: true,
relativeTo: this.document,
}
},
);
}

View file

@ -25,7 +25,7 @@ export class DialogWithListeners extends foundry.applications.api.DialogV2 {
await super._onRender(context, options);
// Attach additional listeners if provided
if (this.activateAdditionalListeners && typeof this.activateAdditionalListeners === 'function') {
if (this.activateAdditionalListeners && typeof this.activateAdditionalListeners === "function") {
this.activateAdditionalListeners(this.element, this);
}
}

View file

@ -8,7 +8,9 @@
/**
* The Sheet class for DS4 Items
*/
export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.sheets.ItemSheetV2,
) {
static DEFAULT_OPTIONS = {
classes: ["sheet", "ds4-item-sheet", "themed"],
tag: "form",
@ -26,18 +28,13 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
actions: {
controlEffect: DS4ItemSheet.prototype._onControlEffect,
createEffect: DS4ItemSheet.prototype._onCreateEffect,
createeffect: DS4ItemSheet.prototype._onCreateEffect,
editEffect: DS4ItemSheet.prototype._onEditEffect,
editeffect: DS4ItemSheet.prototype._onEditEffect,
deleteEffect: DS4ItemSheet.prototype._onDeleteEffect,
deleteeffect: DS4ItemSheet.prototype._onDeleteEffect,
changeTab: DS4ItemSheet.prototype._onChangeTab,
editImage: DS4ItemSheet.prototype._onEditImage,
},
};
static TABS = {};
constructor(options = {}) {
@ -105,14 +102,13 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
this.item.system.description,
{
secrets: this.item.isOwner,
relativeTo: this.item
}
relativeTo: this.item,
},
);
} else {
context.enrichedDescription = "";
}
return context;
}
@ -183,10 +179,12 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
const effect = this.item.effects.get(effectId);
if (!effect) {
throw new Error(game.i18n.format("DS4.ErrorItemDoesNotHaveEffect", {
id: effectId,
item: this.item.name
}));
throw new Error(
game.i18n.format("DS4.ErrorItemDoesNotHaveEffect", {
id: effectId,
item: this.item.name,
}),
);
}
await effect.sheet.render(true);
@ -235,13 +233,13 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
if (!nav || !sheet) return;
// Update navigation active state
nav.querySelectorAll(".ds4-sheet-tab-nav__item").forEach(item => {
nav.querySelectorAll(".ds4-sheet-tab-nav__item").forEach((item) => {
item.classList.remove("active");
});
target.classList.add("active");
// Update tab content visibility
sheet.querySelectorAll(".ds4-sheet-tab").forEach(tabContent => {
sheet.querySelectorAll(".ds4-sheet-tab").forEach((tabContent) => {
tabContent.classList.remove("active");
});
@ -263,7 +261,7 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
const fp = new foundry.applications.apps.FilePicker({
type: "image",
current: current,
callback: (path) => this.item.update({ [field]: path })
callback: (path) => this.item.update({ [field]: path }),
});
return fp.browse();
}
@ -276,8 +274,6 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
this._initializeTabs();
}
/** @override */
async _onClose(options) {
await super._onClose(options);
@ -299,8 +295,8 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
const tabContents = sheet.querySelectorAll(".ds4-sheet-tab");
// Remove active class from all items first
navItems.forEach(item => item.classList.remove("active"));
tabContents.forEach(content => content.classList.remove("active"));
navItems.forEach((item) => item.classList.remove("active"));
tabContents.forEach((content) => content.classList.remove("active"));
// Find the currently active tab or default to first
let targetTab = this.activeTab;
@ -312,8 +308,6 @@ export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplication
targetTab = targetNavItem?.dataset.tab;
}
// Set target tab navigation as active
if (targetNavItem && targetTab) {
targetNavItem.classList.add("active");

View file

@ -7,41 +7,38 @@
* Based on actor movement combat value
*/
export class DS4TokenRuler extends foundry.canvas.placeables.tokens.TokenRuler {
static WAYPOINT_LABEL_TEMPLATE = "systems/ds4/templates/partials/waypoint-label.hbs";
static WAYPOINT_LABEL_TEMPLATE = "systems/ds4/templates/partials/waypoint-label.hbs";
/**
* Enhance waypoint label context with movement range information
* @param {object} waypoint - The waypoint data
* @param {object} state - The current ruler state
* @returns {object} Enhanced context with range class
*/
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
// Only apply movement coloring for distance measurements in meters
if (context?.cost?.units === "m" || context?.distance?.units === "m") {
const movement = this.token?.actor?.system?.combatValues?.movement?.total;
if (movement) {
const total = Number(context.cost?.total || context.distance?.total || 0);
/**
* Enhance waypoint label context with movement range information
* @param {object} waypoint - The waypoint data
* @param {object} state - The current ruler state
* @returns {object} Enhanced context with range class
*/
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
// Only apply movement coloring for distance measurements in meters
if (context?.cost?.units === "m" || context?.distance?.units === "m") {
const movement = this.token?.actor?.system?.combatValues?.movement?.total;
if (movement) {
const total = Number(context.cost?.total || context.distance?.total || 0);
// DS4 movement rules:
// - Normal movement: up to movement value
// - Dash: up to 2x movement value (requires action)
// - Beyond 2x: impossible in single turn
if (total > 2 * movement) {
context.rangeClass = "out-of-range";
} else if (total <= movement) {
context.rangeClass = "move-range";
} else {
context.rangeClass = "dash-range";
}
}
// DS4 movement rules:
// - Normal movement: up to movement value
// - Dash: up to 2x movement value (requires action)
// - Beyond 2x: impossible in single turn
if (total > 2 * movement) {
context.rangeClass = "out-of-range";
} else if (total <= movement) {
context.rangeClass = "move-range";
} else {
context.rangeClass = "dash-range";
}
return context;
}
}
return context;
}
}

View file

@ -212,7 +212,10 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
if (checkModifierSelect) {
checkModifierSelect.addEventListener("change", (event) => {
if (event.currentTarget.value === "custom" && checkModifierCustomFormGroup?.classList.contains("ds4-hidden")) {
if (
event.currentTarget.value === "custom" &&
checkModifierCustomFormGroup?.classList.contains("ds4-hidden")
) {
checkModifierCustomFormGroup.classList.remove("ds4-hidden");
app.setPosition({ height: "auto" });
} else if (checkModifierCustomFormGroup && !checkModifierCustomFormGroup.classList.contains("ds4-hidden")) {

View file

@ -466,30 +466,33 @@ export class DS4Actor extends Actor {
const traitIdentifier = "attribute-trait-selection-trait";
return foundry.applications.api.DialogV2.prompt({
window: { title: getGame().i18n.localize("DS4.DialogAttributeTraitSelection") },
content: await foundry.applications.handlebars.renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
selects: [
{
label: getGame().i18n.localize("DS4.Attribute"),
identifier: attributeIdentifier,
options: Object.fromEntries(
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
attribute,
`${translation} (${this.system.attributes[attribute].total})`,
]),
),
},
{
label: getGame().i18n.localize("DS4.Trait"),
identifier: traitIdentifier,
options: Object.fromEntries(
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
trait,
`${translation} (${this.system.traits[trait].total})`,
]),
),
},
],
}),
content: await foundry.applications.handlebars.renderTemplate(
"systems/ds4/templates/dialogs/simple-select-form.hbs",
{
selects: [
{
label: getGame().i18n.localize("DS4.Attribute"),
identifier: attributeIdentifier,
options: Object.fromEntries(
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
attribute,
`${translation} (${this.system.attributes[attribute].total})`,
]),
),
},
{
label: getGame().i18n.localize("DS4.Trait"),
identifier: traitIdentifier,
options: Object.fromEntries(
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
trait,
`${translation} (${this.system.traits[trait].total})`,
]),
),
},
],
},
),
ok: {
label: getGame().i18n.localize("DS4.GenericOkButton"),
callback: (_event, button) => {

View file

@ -86,18 +86,21 @@ export class DS4Weapon extends DS4Item {
const identifier = `attack-type-selection-${foundry.utils.randomID()}`;
return foundry.applications.api.DialogV2.prompt({
window: { title: getGame().i18n.localize("DS4.DialogAttackTypeSelection") },
content: await foundry.applications.handlebars.renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
selects: [
{
label: getGame().i18n.localize("DS4.AttackType"),
identifier,
options: { melee, ranged },
},
],
}),
content: await foundry.applications.handlebars.renderTemplate(
"systems/ds4/templates/dialogs/simple-select-form.hbs",
{
selects: [
{
label: getGame().i18n.localize("DS4.AttackType"),
identifier,
options: { melee, ranged },
},
],
},
),
ok: {
label: getGame().i18n.localize("DS4.GenericOkButton"),
callback: (_event, button, _dialog) => {
callback: (_event, button) => {
const selectedAttackType = button.form.elements[identifier].value;
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
throw new Error(

View file

@ -14,6 +14,11 @@ const helpers = {
isEmpty: (input: Array<unknown> | null | undefined): boolean => (input?.length ?? 0) === 0,
capitalize: (str: string): string => {
if (typeof str !== "string") return "";
return str.charAt(0).toUpperCase() + str.slice(1);
},
toRomanNumerals,
};

View file

@ -9,8 +9,6 @@ import { registerForReadyHook } from "./ready";
import { registerForRenderHooks } from "./render";
import { registerForSetupHook } from "./setup";
export function registerForHooks(): void {
registerForHotbarDropHook();
registerForPreCreateItemHook();

View file

@ -21,12 +21,12 @@ export function registerForRenderHooks() {
*/
function selectTargetInputOnFocus(app, element) {
// V13: element is always a plain DOM element
if (!element || typeof element.querySelectorAll !== 'function') {
if (!element || typeof element.querySelectorAll !== "function") {
return;
}
const inputs = element.querySelectorAll("input");
inputs.forEach(input => {
inputs.forEach((input) => {
input.addEventListener("focus", (ev) => {
ev.currentTarget.select();
});

View file

@ -30,7 +30,10 @@ export function enforce(value, message) {
* @returns {Canvas}
*/
export function getCanvas() {
enforce(canvas instanceof foundry.canvas.Canvas && canvas.ready, getGame().i18n.localize("DS4.ErrorCanvasIsNotInitialized"));
enforce(
canvas instanceof foundry.canvas.Canvas && canvas.ready,
getGame().i18n.localize("DS4.ErrorCanvasIsNotInitialized"),
);
return canvas;
}

View file

@ -12,7 +12,6 @@ SPDX-License-Identifier: MIT
{{> systems/ds4/templates/sheets/actor/components/creature-properties.hbs}}
{{/systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
{{!-- Sheet Tab Navigation --}}
<nav class="ds4-sheet-tab-nav" data-group="primary">
<a class="ds4-sheet-tab-nav__item" data-action="changeTab" data-tab="values">{{localize 'DS4.HeadingValues'}}</a>

View file

@ -9,7 +9,6 @@ SPDX-License-Identifier: MIT
{{#> systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
{{/systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
{{!-- Sheet Body --}}
<section class="ds4-sheet-body">
{{#if (eq data.type 'character')}}

View file

@ -40,10 +40,8 @@ titleKey=titleKey}}
titleKey=titleKey}}
{{/inline}}
{{!-- ======================================================================== --}}
<div class="ds4-sheet-tab tab spells" data-group="primary" data-tab="spells">
{{#unless (isEmpty itemsByType.spell)}}
<ol class="ds4-embedded-document-list ds4-embedded-document-list--spell item-list">

View file

@ -5,10 +5,10 @@ SPDX-License-Identifier: MIT
--}}
<div class="ds4-sheet-tab tab effects" data-group="primary" data-tab="effects">
{{#unless (isEmpty data.effects)}}
{{#unless (isEmpty enrichedEffects)}}
<ol class="ds4-embedded-document-list ds4-embedded-document-list--item-effect effect-list">
{{> systems/ds4/templates/sheets/item/components/effect-list-header.hbs}}
{{#each data.effects as |effectData id| }}
{{#each enrichedEffects as |effectData id| }}
{{> systems/ds4/templates/sheets/item/components/effect-list-entry.hbs effectData=effectData}}
{{/each}}
</ol>

View file

@ -13,7 +13,7 @@ SPDX-License-Identifier: MIT
}}
{{#if @root/editable}}
<div class="ds4-add-button">
<a class="ds4-add-button__link" title="{{localize title}}" data-action="create{{documentType}}" {{#if type}}data-type="{{type}}"
<a class="ds4-add-button__link" title="{{localize title}}" data-action="{{concat 'create' (capitalize documentType)}}" {{#if type}}data-type="{{type}}"
{{/if}}>
<i class="fas fa-plus"></i>
{{localize "DS4.UserInteractionAdd"}}

View file

@ -14,9 +14,9 @@ SPDX-License-Identifier: MIT
--}}
<div class="ds4-control-button-group">
{{#if @root/editable}}
<a class="ds4-control-button-group__button" data-action="edit{{documentType}}" data-document-type="{{documentType}}"
<a class="ds4-control-button-group__button" data-action="{{concat 'edit' (capitalize documentType)}}" data-document-type="{{documentType}}"
title="{{localize editTitle}}"><i class="fas fa-edit"></i></a>
<a class="ds4-control-button-group__button" data-action="delete{{documentType}}" data-document-type="{{documentType}}"
<a class="ds4-control-button-group__button" data-action="{{concat 'delete' (capitalize documentType)}}" data-document-type="{{documentType}}"
title="{{localize deleteTitle}}"><i class="fas fa-trash"></i></a>
{{/if}}
</div>