Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions module/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@ export class EntitySheetHelper {

/* -------------------------------------------- */

/**
* Toggle whether a list of attributes are collapsed or expanded
* @param {object} element The element containing the group list
* @param {boolean=} collapsed Force the group collapsed to true or false
*/
static toggleAttributeCollapse(el, collapsed) {
const cb = el.querySelector('.attribute-collapsed');
const i = el.querySelector('a.attribute-control > i');
if(cb.checked = collapsed !== undefined ? collapsed : !cb.checked){
i.classList.remove('fa-caret-down')
i.classList.add('fa-caret-right')
el.parentElement.querySelector('section.attributes-group').style.display = 'none';
} else {
i.classList.remove('fa-caret-right')
i.classList.add('fa-caret-down')
el.parentElement.querySelector('section.attributes-group').style.display = 'block';
}
}

/* -------------------------------------------- */

/**
* Listen for click events on an attribute control to modify the composition of attributes in the sheet
* @param {MouseEvent} event The originating left click event
Expand All @@ -140,6 +161,8 @@ export class EntitySheetHelper {
return EntitySheetHelper.createAttribute(event, this);
case "delete":
return EntitySheetHelper.deleteAttribute(event, this);
case "collapse":
return EntitySheetHelper.collapseAttributes(event, this);
}
}

Expand All @@ -158,6 +181,8 @@ export class EntitySheetHelper {
return EntitySheetHelper.createAttributeGroup(event, this);
case "delete-group":
return EntitySheetHelper.deleteAttributeGroup(event, this);
case "collapse":
return EntitySheetHelper.collapseAttributes(event, this);
}
}

Expand Down Expand Up @@ -273,6 +298,9 @@ export class EntitySheetHelper {
const groups = app.object.system.groups;
const form = app.form;

// force group attributes not to be collapsed
EntitySheetHelper.toggleAttributeCollapse(a.parentElement, false);

// Determine the new attribute key for ungrouped attributes.
let objKeys = Object.keys(attrs).filter(k => !Object.keys(groups).includes(k));
let nk = Object.keys(attrs).length + 1;
Expand Down Expand Up @@ -351,6 +379,19 @@ export class EntitySheetHelper {

/* -------------------------------------------- */

/**
* Collapse or expand attributes.
* @param {MouseEvent} event The originating left click event
* @param {Object} app The form application object.
*/
static async collapseAttributes(event, app) {
const a = event.currentTarget;
EntitySheetHelper.toggleAttributeCollapse(a.parentElement);
await app._onSubmit(event);
}

/* -------------------------------------------- */

/**
* Create new attribute groups.
* @param {MouseEvent} event The originating left click event
Expand Down Expand Up @@ -418,7 +459,8 @@ export class EntitySheetHelper {
let groupKeys = [];

// Handle the free-form attributes list
const formAttrs = foundry.utils.expandObject(formData)?.system?.attributes || {};
const expanded = foundry.utils.expandObject(formData);
const formAttrs = expanded?.system?.attributes || {};
const attributes = Object.values(formAttrs).reduce((obj, v) => {
let attrs = [];
let group = null;
Expand Down Expand Up @@ -464,8 +506,11 @@ export class EntitySheetHelper {
}
}

// Copy across collapsed flag for attributes
formAttrs.attributes_collapsed = expanded?.attributes_collapsed;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All variables should be camel-case i.e. attributesCollapsed

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry habitual snake case, hard to shake. :)


// Re-combine formData
formData = Object.entries(formData).filter(e => !e[0].startsWith("system.attributes")).reduce((obj, e) => {
formData = Object.entries(formData).filter(e => !e[0].startsWith("system.attributes.")).reduce((obj, e) => {
obj[e[0]] = e[1];
return obj;
}, {_id: document.id, "system.attributes": attributes});
Expand Down
12 changes: 12 additions & 0 deletions styles/simple.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
/* Items List */
/* Attributes */
}
.worldbuilding a.fa-caret-right,
.worldbuilding a.fa-caret-down {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should give these a more targeted selector so they don't affect other uses of these icons. Something like .attribute-control.collapse

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that shouldn't have been included at all it was from an earlier iteration which didn't use the "fas" class which is now providing the defaults for those values.

font-weight: 900;
font-size: smaller;
}
.worldbuilding .window-content {
height: 100%;
padding: 5px;
Expand Down Expand Up @@ -215,6 +220,10 @@
border-radius: 2px;
padding: 2px 5px;
}
.worldbuilding .attributes-header .attribute-control:first-child,
.worldbuilding .group-header .attribute-control:first-child {
flex: none;
}
.worldbuilding .group-key,
.worldbuilding .group-label {
font-weight: bold;
Expand All @@ -235,6 +244,9 @@
flex: 0 0 116px;
margin: 0 5px;
}
.worldbuilding .attribute-collapsed {
display: none;
}
.worldbuilding.sheet.actor {
min-width: 560px;
min-height: 420px;
Expand Down
2 changes: 2 additions & 0 deletions template.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"min": 0,
"max": 5
},
"attributes_collapsed": false,
"attributes": {},
"groups": {}
}
Expand All @@ -25,6 +26,7 @@
"description": "",
"quantity": 1,
"weight": 0,
"attributes_collapsed": false,
"attributes": {},
"groups": {}
}
Expand Down
4 changes: 3 additions & 1 deletion templates/actor-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,17 @@ <h4 class="item-name">{{item.name}}</h4>
{{!-- Attributes Tab --}}
<div class="tab attributes" data-group="primary" data-tab="attributes">
<header class="attributes-header flexrow">
<a class="attribute-control" data-action="collapse"><i class="fas {{#if systemData.attributes_collapsed}}fa-caret-right{{else}}fa-caret-down{{/if}}"></i></a>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the motivation to collapse specific attribute groups, but I don't understand the collapse button in the main attributes header. I think I would prefer to keep functionality to collapse groups, but not support collapsing the overall attributes list. Thoughts?

Copy link
Copy Markdown
Author

@abc-mikey abc-mikey Mar 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motivation is the same as for groups to provide a way of hiding the details of a set of attributes to make working with the values of a sheet easier for players. Maybe some groups are rarely changed or only for accounting purposes, players should be able to collapse them to make find the attributes they are interested in easier, or to give more control over how the attributes sheet is presented to them.

I though it best not to make any assumptions about how people were organizing their attributes and make every list of attributes collapsible including the main attributes. It is only collapsing those attributes which are not part of a group, the rest of the sheet, i.e. all the groups, would still be presented.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you thinking that the main attributes should always be shown, or do you think that the role expand button in the top attribute bar is confusing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having an expand/collaspe toggle to the left of "Attribute Key" in the main table header is confusing to me.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I would still be in favour of having the top level attributes be collapsible.

Could we maybe give them a special group header just without any value for the group? And allow that to be collapsible?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ambiguity in my mind is not knowing whether the top-level collapse will collapse the entire tab (ungrouped attributes and groups) or whether it would just hide ungrouped attributes. I presume the implementation is the later, but I think the UX is muddy.

I'm not sure I have much bandwidth for iteration at the moment, so I think your best shot is to remove this top-level collapse and we can focus on getting the rest of this functionality merged, then we could revisit what to do for ungrouped attributes in a follow-up PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Giving the to level attributes their own group header would remove that ambiguity, but I'm happy to just leave the top level attributes as uncollapsible for now.

<span class="attribute-key">{{localize "SIMPLE.AttributeKey"}}</span>
<span class="attribute-value">{{localize "SIMPLE.AttributeValue"}}</span>
<span class="attribute-label">{{localize "SIMPLE.AttributeLabel"}}</span>
<span class="attribute-dtype">{{localize "SIMPLE.AttributeDtype"}}</span>
<a class="attribute-control" data-action="create" data-group="{{group}}"><i class="fas fa-plus"></i></a>
<input class="attribute-collapsed" type="checkbox" name="system.attributes_collapsed" {{#if systemData.attributes_collapsed}}checked{{/if}} />
</header>

{{!-- Render the attribute list partial. --}}
{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=systemData.ungroupedAttributes dtypes=dtypes}}
{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=systemData.ungroupedAttributes dtypes=dtypes collapsed=systemData.attributes_collapsed}}

{{!-- Render the grouped attributes partial and control. --}}
<div class="groups">
Expand Down
4 changes: 3 additions & 1 deletion templates/item-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@ <h1 class="charname">
{{!-- Attributes Tab --}}
<div class="tab attributes" data-group="primary" data-tab="attributes">
<header class="attributes-header flexrow">
<a class="attribute-control" data-action="collapse"><i class="fas {{#if systemData.attributes_collapsed}}fa-caret-right{{else}}fa-caret-down{{/if}}"></i></a>
<span class="attribute-key">{{localize "SIMPLE.AttributeKey"}}</span>
<span class="attribute-value">{{localize "SIMPLE.AttributeValue"}}</span>
<span class="attribute-label">{{localize "SIMPLE.AttributeLabel"}}</span>
<span class="attribute-dtype">{{localize "SIMPLE.AttributeDtype"}}</span>
<a class="attribute-control" data-action="create" data-group="{{group}}"><i class="fas fa-plus"></i></a>
<input class="attribute-collapsed" type="checkbox" name="system.attributes_collapsed" {{#if systemData.attributes_collapsed}}checked{{/if}} />
</header>

{{!-- Render the attribute list partial. --}}
{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=systemData.ungroupedAttributes dtypes=dtypes}}
{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=systemData.ungroupedAttributes dtypes=dtypes collapsed=systemData.attributes_collapsed}}

{{!-- Render the grouped attributes partial and control. --}}
<div class="groups">
Expand Down
2 changes: 1 addition & 1 deletion templates/parts/sheet-attributes.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="attributes-group">
<section class="attributes-group" style="display: {{#if collapsed}}none{{else}}block{{/if}}">
<ol class="attributes-list">
{{#each attributes as |attr key|}}
<li class="attribute flexrow" data-attribute="{{#if attr.group}}{{attr.group}}.{{/if}}{{key}}">
Expand Down
4 changes: 3 additions & 1 deletion templates/parts/sheet-groups.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{{#each groups as |group groupKey|}}
<li class="group" data-group="{{groupKey}}">
<div class="group-header flexrow">
<a class="attribute-control" data-action="collapse"><i class="fas {{#if group.collapsed}}fa-caret-right{{else}}fa-caret-down{{/if}}"></i></a>
<input class="group-key" type="text" readonly name="system.groups.{{groupKey}}.key" value="{{groupKey}}" />
<input class="group-label" type="text" name="system.groups.{{groupKey}}.label" value="{{group.label}}" placeholder="Group Label" />
<select class="group-dtype" name="system.groups.{{groupKey}}.dtype">
Expand All @@ -13,9 +14,10 @@
</select>
<a class="attribute-control" data-action="create" data-group="{{groupKey}}" data-dtype="{{group.dtype}}"><i class="fas fa-plus"></i></a>
<a class="group-control" data-action="delete-group"><i class="fas fa-trash"></i></a>
<input class="attribute-collapsed" type="checkbox" name="system.groups.{{groupKey}}.collapsed" {{#if group.collapsed}}checked{{/if}} />
</div>

{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=group.attributes group=groupKey dtypes=../dtypes}}
{{> "systems/worldbuilding/templates/parts/sheet-attributes.html" attributes=group.attributes group=groupKey dtypes=../dtypes collapsed=group.collapsed}}
</li>
{{/each}}
</ol>