Skip to content

Commit 50ceb06

Browse files
authored
Merge pull request #5 from lemerv/develop
Column Summaries feature and other fixes
2 parents 2979cac + e64c84f commit 50ceb06

26 files changed

+268829
-1289
lines changed

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
.sf
99
.vscode
1010

11-
coverage/
11+
coverage/
12+
repomix-output.xml

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Kanban Explorer is a Lightning Web Component that transforms your Salesforce rec
2020
- **Context-aware** - works on record pages, app pages, and home pages
2121
- **Multiple data modes** - parent mode (single select and multi select), parentless mode, and record page mode
2222
- **Flexible customization** - configurable fields, filters, search, and sorting
23+
- **Column summaries** - configure up to 3 column summaries, such as SUMs, AVGs, COUNTs, and more
2324
- **Visual goodies** - add icons and emojis to cards
2425

2526
## Quick Start
@@ -72,6 +73,7 @@ Kanban Explorer is adaptable:
7273
- **Date Formatting**: Custom date/time display formats
7374
- **Field Labels**: Toggle field labels on/off for cleaner interfaces
7475
- **Card Counts**: Display record counts per column
76+
- **Column summaries**: Show up to 3 per-column metrics (SUM, AVG, MIN, MAX, COUNT_TRUE, COUNT_FALSE) for numeric, date, and checkbox fields
7577

7678
### 🔒 Safe and Secure
7779

config/project-scratch-def.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
"FieldAuditTrail"
1212
],
1313
"settings": {
14+
"userSettings": {
15+
"language": "en_US",
16+
"locale": "en_AU",
17+
"timeZone": "Australia/Sydney"
18+
},
1419
"communitiesSettings": {
1520
"enableNetworksEnabled": true
1621
},

docs/admin-guide.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- [Card Record Configuration](#card-record-configuration)
55
- [Parent Record Configuration](#parent-record-configuration)
66
- [Card Sort, Filter, and Search Configuration](#card-sort-filter-and-search-configuration)
7+
- [Column Summaries Configuration](#column-summaries-configuration)
78
- [Other Configuration Fields](#other-configuration-fields)
89
- [Best Practices](#best-practices)
910
- [Common Configuration Patterns](#common-configuration-patterns)
@@ -229,6 +230,25 @@ Use these configuration fields to control _which_ Parent records are available i
229230
- **Example**: `Subject,Description,CaseNumber,Account.Name`
230231
- **Tip**: Search works for a field that isn't actually displayed on the board
231232

233+
## Column Summaries Configuration
234+
235+
### Column Summaries Definition <!-- omit from toc -->
236+
237+
- **Property**: `Column Summaries Definition`
238+
- **Purpose**: Define up to three summaries that appear in each column header.
239+
- **Format**: `[FieldApiName|SUMMARY_TYPE|Label]` entries separated by semicolons
240+
- **Summary Types**: `SUM`, `AVG`, `MIN`, `MAX`, `COUNT_TRUE`, `COUNT_FALSE`
241+
- **Examples**:
242+
- `[Amount|SUM|Total Amount];[Amount|AVG|Avg Amount]`
243+
- `[CloseDate|MIN|Earliest Close];[CloseDate|MAX|Latest Close]`
244+
- `[IsEscalated|COUNT_TRUE|Escalated];[IsEscalated|COUNT_FALSE|Not Escalated]`
245+
- **Notes**:
246+
- `SUM`/`AVG` require numeric fields (Number, Currency, Percent, Integer, Double)
247+
- `MIN`/`MAX` allow numeric or Date/DateTime fields
248+
- `COUNT_TRUE`/`COUNT_FALSE` require Checkbox fields
249+
- If a currency summary contains multiple currencies in the same column, the summary value is blocked and shows `Mixed currencies`, and a warning banner is displayed
250+
- Invalid definitions are ignored and surfaced as a non-blocking warning
251+
232252
## Other Configuration Fields
233253

234254
#### Empty Group Label <!-- omit from toc -->
@@ -243,9 +263,11 @@ Use these configuration fields to control _which_ Parent records are available i
243263
- **Purpose**: Custom date/time display format
244264
- **Format**: Java SimpleDateFormat pattern
245265
- **Examples**:
246-
- `dd/MM/yyyy h:mm a` (default)
266+
- `dd/MM/yyyy h:mm a`
247267
- `MM-dd-yy HH:mm`
248268
- `EEEE, MMMM d, yyyy`
269+
- **Notes**:
270+
- Leave blank to use the running user's Salesforce locale settings
249271

250272
#### Debug Logging <!-- omit from toc -->
251273

force-app/main/default/lwc/lresDateTimeUtils/__tests__/lresDateTimeUtils.test.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ describe("lresDateTimeUtils", () => {
4040
expect(result).toBe("2023-12-25 14:30:45");
4141
});
4242

43+
test("should drop time tokens for date-only fields", () => {
44+
const result = formatValueWithPattern(TEST_DATE_ONLY_STRING, {
45+
pattern: "yyyy-MM-dd HH:mm:ss",
46+
dateOnly: true
47+
});
48+
expect(result).toBe("2023-12-25");
49+
});
50+
51+
test("should append time tokens for datetime fields when missing", () => {
52+
const result = formatValueWithPattern(TEST_DATE, {
53+
pattern: "yyyy-MM-dd"
54+
});
55+
expect(result).toBe("2023-12-25 2:30 PM");
56+
});
57+
4358
test("should format date string with date-only pattern", () => {
4459
const result = formatValueWithPattern(TEST_DATE_ONLY_STRING, {
4560
pattern: "MM/dd/yyyy",
@@ -69,11 +84,12 @@ describe("lresDateTimeUtils", () => {
6984
expect(result).toBeNull();
7085
});
7186

72-
test("should return null for invalid pattern", () => {
87+
test("should fall back to locale formatting when pattern is missing", () => {
7388
const result = formatValueWithPattern(TEST_DATE, {
7489
pattern: null
7590
});
76-
expect(result).toBeNull();
91+
expect(result).toBeDefined();
92+
expect(typeof result).toBe("string");
7793
});
7894

7995
test("should handle custom locale and timezone", () => {
@@ -91,7 +107,7 @@ describe("lresDateTimeUtils", () => {
91107
pattern: "yyyy-MM-dd HH:mm:ss",
92108
dateOnly: true
93109
});
94-
expect(result).toBe("2023-12-25 00:00:00");
110+
expect(result).toBe("2023-12-25");
95111
});
96112

97113
test("should use pattern token cache", () => {
@@ -100,8 +116,8 @@ describe("lresDateTimeUtils", () => {
100116
pattern: "yyyy-MM-dd",
101117
patternTokenCache: cache
102118
});
103-
expect(result).toBe("2023-12-25");
104-
expect(cache.size).toBe(1);
119+
expect(result).toBe("2023-12-25 2:30 PM");
120+
expect(cache.size).toBe(2);
105121
});
106122
});
107123

@@ -565,7 +581,7 @@ describe("lresDateTimeUtils", () => {
565581
const result = formatValueWithPattern(leapYearDate, {
566582
pattern: "yyyy-MM-dd"
567583
});
568-
expect(result).toBe("2024-02-29");
584+
expect(result).toBe("2024-02-29 12:00 PM");
569585
});
570586

571587
test("should handle end of year date", () => {
@@ -637,7 +653,7 @@ describe("lresDateTimeUtils", () => {
637653
const result = formatValueWithPattern(TEST_DATE, {
638654
pattern: "MMM dd, yyyy"
639655
});
640-
expect(result).toBe("Dec 25, 2023");
656+
expect(result).toBe("Dec 25, 2023 2:30 PM");
641657
});
642658

643659
test("should format for API requests", () => {

0 commit comments

Comments
 (0)