From cb03788acf8c7eaf588763b558740a354248d99d Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 11:04:24 +0200 Subject: [PATCH 01/10] small readme update --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 22be0f3..05da54c 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# LWCTaskChecklist \ No newline at end of file +# LWCTaskChecklist + +Need to update this + +![Example of LWC](img/demo.png) From 649b5e765284e73cc8b8e4697575be6c74100336 Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 11:05:01 +0200 Subject: [PATCH 02/10] added image preview --- img/demo.png | Bin 0 -> 6193 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/demo.png diff --git a/img/demo.png b/img/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..625c5b3a82a55d8202c1a819fcf2ada9835db9fd GIT binary patch literal 6193 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 ZOHY&|*Sd9?y8}xgT}^!rvijw_{{dPg+~NQL literal 0 HcmV?d00001 From f6ce93e65f088d3f54e603dfc9adb8f784406a58 Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 11:05:10 +0200 Subject: [PATCH 03/10] added apex classes --- .../classes/TaskChecklistPanelController.cls | 62 +++++++++++++++++++ .../TaskChecklistPanelController.cls-meta.xml | 5 ++ .../TaskChecklistPanelControllerTest.cls | 4 ++ ...kChecklistPanelControllerTest.cls-meta.xml | 5 ++ .../TaskChecklistPanelLWCController.cls | 31 ++++++++++ ...skChecklistPanelLWCController.cls-meta.xml | 5 ++ 6 files changed, 112 insertions(+) create mode 100644 force-app/main/default/classes/TaskChecklistPanelController.cls create mode 100644 force-app/main/default/classes/TaskChecklistPanelController.cls-meta.xml create mode 100644 force-app/main/default/classes/TaskChecklistPanelControllerTest.cls create mode 100644 force-app/main/default/classes/TaskChecklistPanelControllerTest.cls-meta.xml create mode 100644 force-app/main/default/classes/TaskChecklistPanelLWCController.cls create mode 100644 force-app/main/default/classes/TaskChecklistPanelLWCController.cls-meta.xml diff --git a/force-app/main/default/classes/TaskChecklistPanelController.cls b/force-app/main/default/classes/TaskChecklistPanelController.cls new file mode 100644 index 0000000..11c9a0b --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelController.cls @@ -0,0 +1,62 @@ +/** + * + */ +public with sharing class TaskChecklistPanelController { + public class TaskChecklistPanelControllerException extends Exception { + } + + /** + * + */ + public static List getTasksByCaseId(Id caseId) { + Case caseInfo = [ + SELECT + Id, + ( + SELECT Id, Subject, IsCompleted__c, CompletedDateTime, Type + FROM Tasks + WHERE Type = 'Checklist_Item' + ORDER BY Subject ASC + ) + FROM Case + WHERE Id = :caseId + ]; + + return caseInfo.Tasks; + } + + /** + * + */ + public static List updateTaskStatusById( + String caseId, + Set idsToUpdate + ) { + List toUpdate = new List(); + for (String taskId : idsToUpdate) { + toUpdate.add(new Task(Id = taskId, Status = 'Completed')); + } + + List updateResults = Database.update( + toUpdate, + true + ); + + String errorString = ''; + Boolean hasErrors = false; + for (Database.SaveResult sr : updateResults) { + if (!sr.isSuccess()) { + hasErrors = true; + for (Database.Error de : sr.getErrors()) { + errorString += de.getMessage() + '\n'; + } + } + } + + if (hasErrors) { + throw new TaskChecklistPanelControllerException(errorString); + } + + return getTasksByCaseId(caseId); + } +} diff --git a/force-app/main/default/classes/TaskChecklistPanelController.cls-meta.xml b/force-app/main/default/classes/TaskChecklistPanelController.cls-meta.xml new file mode 100644 index 0000000..5f399c3 --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelController.cls-meta.xml @@ -0,0 +1,5 @@ + + + 63.0 + Active + diff --git a/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls b/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls new file mode 100644 index 0000000..76fd03a --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls @@ -0,0 +1,4 @@ +@isTest +private class TaskChecklistPanelControllerTest { + // Placeholder +} diff --git a/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls-meta.xml b/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls-meta.xml new file mode 100644 index 0000000..5f399c3 --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelControllerTest.cls-meta.xml @@ -0,0 +1,5 @@ + + + 63.0 + Active + diff --git a/force-app/main/default/classes/TaskChecklistPanelLWCController.cls b/force-app/main/default/classes/TaskChecklistPanelLWCController.cls new file mode 100644 index 0000000..fbaa7fc --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelLWCController.cls @@ -0,0 +1,31 @@ +/** + * + */ +public with sharing class TaskChecklistPanelLWCController { + /** + * + */ + @AuraEnabled + public static List updateTaskStatuses(String caseId, String taskIds) { + try { + return TaskChecklistPanelController.updateTaskStatusById( + caseId, + (Set) JSON.deserialize(taskIds, Set.class) + ); + } catch (Exception e) { + throw new AuraHandledException(e.getMessage()); + } + } + + /** + * + */ + @AuraEnabled + public static List getTasksForChecklist(Id caseId) { + try { + return TaskChecklistPanelController.getTasksByCaseId(caseId); + } catch (Exception e) { + throw new AuraHandledException(e.getMessage()); + } + } +} diff --git a/force-app/main/default/classes/TaskChecklistPanelLWCController.cls-meta.xml b/force-app/main/default/classes/TaskChecklistPanelLWCController.cls-meta.xml new file mode 100644 index 0000000..5f399c3 --- /dev/null +++ b/force-app/main/default/classes/TaskChecklistPanelLWCController.cls-meta.xml @@ -0,0 +1,5 @@ + + + 63.0 + Active + From 79a40bbb3e360865e08d2e851cc1392cc3e94321 Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 11:05:19 +0200 Subject: [PATCH 04/10] added lwc --- .../taskChecklistPanel/taskChecklistPanel.css | 9 +++ .../taskChecklistPanel.html | 41 ++++++++++ .../taskChecklistPanel/taskChecklistPanel.js | 74 +++++++++++++++++++ .../taskChecklistPanel.js-meta.xml | 8 ++ 4 files changed, 132 insertions(+) create mode 100644 force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.css create mode 100644 force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html create mode 100644 force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js create mode 100644 force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js-meta.xml diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.css b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.css new file mode 100644 index 0000000..ec3e046 --- /dev/null +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.css @@ -0,0 +1,9 @@ +.clearfix::after { + content: ""; + clear: both; + display: table; +} + +.checklist-border { + border-radius: 3px; +} diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html new file mode 100644 index 0000000..ca18b2c --- /dev/null +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html @@ -0,0 +1,41 @@ + diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js new file mode 100644 index 0000000..f06bf7f --- /dev/null +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js @@ -0,0 +1,74 @@ +import { LightningElement, api, track } from "lwc"; +import getChecklistData from "@salesforce/apex/ChecklistController.getTasksForChecklist"; +import updateChecklist from "@salesforce/apex/ChecklistController.updateTaskStatuses"; + +export default class TaskChecklistPanel extends LightningElement { + // Case record Id + @api recordId; + + @track taskList; + @track progress = 0; + @track isSubmitBtnDisabled = false; + + taskIdsToUpdate = []; + + connectedCallback() { + getChecklistData({ caseId: this.recordId }) + .then((data) => { + this.taskList = data; + this.calculateProgress(); + }) + .catch((error) => { + console.error("Error fetching data:", error); + }); + } + + handleCheckboxChange(event) { + const checkbox = event.target; + + if (this.taskIdsToUpdate.includes(checkbox.name) && !checkbox.checked) { + this.taskIdsToUpdate.pop(checkbox.name); + } else if ( + !this.taskIdsToUpdate.includes(checkbox.name) && + checkbox.checked + ) { + this.taskIdsToUpdate.push(checkbox.name); + } + } + + calculateProgress() { + let totalTasksCompleted = 0; + for (const task of this.taskList) { + if (task.IsCompleted__c) { + totalTasksCompleted++; + } + } + + this.progress = (totalTasksCompleted / this.taskList.length) * 100; + } + + handleUpdateTaskStatuses() { + // Nothing is selected, so don't do anything + if (this.taskIdsToUpdate.length === 0) { + return; + } + + this.isSubmitBtnDisabled = true; + + updateChecklist({ + caseId: this.recordId, + taskIds: JSON.stringify(this.taskIdsToUpdate), + }) + .then((result) => { + this.taskList = result; + this.calculateProgress(); + // We did the things, enable the Submit button and empty the update list + this.isSubmitBtnDisabled = false; + this.taskIdsToUpdate = []; + }) + .catch((error) => { + console.error("Error updating and fetching data:", error); + this.isSubmitBtnDisabled = false; + }); + } +} diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js-meta.xml b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js-meta.xml new file mode 100644 index 0000000..c9afdbd --- /dev/null +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js-meta.xml @@ -0,0 +1,8 @@ + + + 63.0 + true + + lightning__RecordPage + + \ No newline at end of file From 5effcb32cb7c4c318d28f1001dae7e4a3398d19f Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 11:05:28 +0200 Subject: [PATCH 05/10] added package.xml --- manifest/package.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 manifest/package.xml diff --git a/manifest/package.xml b/manifest/package.xml new file mode 100644 index 0000000..a542b74 --- /dev/null +++ b/manifest/package.xml @@ -0,0 +1,14 @@ + + + + TaskChecklistPanelController + TaskChecklistPanelLWCController + TaskChecklistPanelControllerTest + ApexClass + + + taskChecklistPanel + LightningComponentBundle + + 63.0 + From 74c8131d7699d07bf75488affb4e2fccb18fc48c Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 12:07:12 +0200 Subject: [PATCH 06/10] changes to updating taskIdsToUpdate stack --- .../taskChecklistPanel/taskChecklistPanel.js | 67 ++++++++++++++++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js index f06bf7f..e5ed08d 100644 --- a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js @@ -6,12 +6,15 @@ export default class TaskChecklistPanel extends LightningElement { // Case record Id @api recordId; - @track taskList; + @track taskList = []; @track progress = 0; @track isSubmitBtnDisabled = false; taskIdsToUpdate = []; + /** + * + */ connectedCallback() { getChecklistData({ caseId: this.recordId }) .then((data) => { @@ -23,19 +26,37 @@ export default class TaskChecklistPanel extends LightningElement { }); } - handleCheckboxChange(event) { - const checkbox = event.target; - - if (this.taskIdsToUpdate.includes(checkbox.name) && !checkbox.checked) { - this.taskIdsToUpdate.pop(checkbox.name); - } else if ( - !this.taskIdsToUpdate.includes(checkbox.name) && - checkbox.checked - ) { - this.taskIdsToUpdate.push(checkbox.name); + /** + * + */ + handleUpdateTaskStatuses() { + // Nothing is selected, so don't do anything + if (this.taskIdsToUpdate.length === 0) { + return; } + + this.isSubmitBtnDisabled = true; + + updateChecklist({ + caseId: this.recordId, + taskIds: JSON.stringify(this.taskIdsToUpdate), + }) + .then((result) => { + this.taskList = result; + this.calculateProgress(); + // We did the things, enable the Submit button and empty the update list + this.isSubmitBtnDisabled = false; + this.taskIdsToUpdate = []; + }) + .catch((error) => { + console.error("Error updating and fetching data:", error); + this.isSubmitBtnDisabled = false; + }); } + /** + * + */ calculateProgress() { let totalTasksCompleted = 0; for (const task of this.taskList) { @@ -47,6 +68,30 @@ export default class TaskChecklistPanel extends LightningElement { this.progress = (totalTasksCompleted / this.taskList.length) * 100; } + /** + * + * @param {*} event + */ + handleCheckboxChange(event) { + const checkbox = event.target; + + if (this.taskIdsToUpdate.includes(checkbox.name) && !checkbox.checked) { + // Remove TaskId from list + this.taskIdsToUpdate = this.taskIdsToUpdate.filter( + (taskId) => taskId !== checkbox.name + ); + } else if ( + !this.taskIdsToUpdate.includes(checkbox.name) && + checkbox.checked + ) { + // Add TaskId to list + this.taskIdsToUpdate.push(checkbox.name); + } + } + + /** + * + */ handleUpdateTaskStatuses() { // Nothing is selected, so don't do anything if (this.taskIdsToUpdate.length === 0) { From c05c4102aa2fd831c5b4d434bcc1f1633c24af11 Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 12:35:53 +0200 Subject: [PATCH 07/10] fixed data handling in js, new label for checklist items --- .../taskChecklistPanel.html | 2 +- .../taskChecklistPanel/taskChecklistPanel.js | 53 +++++++------------ 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html index ca18b2c..be6be54 100644 --- a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.html @@ -21,7 +21,7 @@
{ - this.taskList = data; + this.processData(data); this.calculateProgress(); }) .catch((error) => { @@ -26,6 +26,21 @@ export default class TaskChecklistPanel extends LightningElement { }); } + /** + * + */ + processData(data) { + this.taskList = data; + + // If Task is completed, show the completion date from formula field + for (const task of this.taskList) { + task.Label = task.Subject; + if (task.IsCompleted__c) { + task.Label += " (" + task.CompletedDateFormula__c + ")"; + } + } + } + /** * */ @@ -41,8 +56,8 @@ export default class TaskChecklistPanel extends LightningElement { caseId: this.recordId, taskIds: JSON.stringify(this.taskIdsToUpdate), }) - .then((result) => { - this.taskList = result; + .then((data) => { + this.processData(data); this.calculateProgress(); // We did the things, enable the Submit button and empty the update list this.isSubmitBtnDisabled = false; @@ -88,32 +103,4 @@ export default class TaskChecklistPanel extends LightningElement { this.taskIdsToUpdate.push(checkbox.name); } } - - /** - * - */ - handleUpdateTaskStatuses() { - // Nothing is selected, so don't do anything - if (this.taskIdsToUpdate.length === 0) { - return; - } - - this.isSubmitBtnDisabled = true; - - updateChecklist({ - caseId: this.recordId, - taskIds: JSON.stringify(this.taskIdsToUpdate), - }) - .then((result) => { - this.taskList = result; - this.calculateProgress(); - // We did the things, enable the Submit button and empty the update list - this.isSubmitBtnDisabled = false; - this.taskIdsToUpdate = []; - }) - .catch((error) => { - console.error("Error updating and fetching data:", error); - this.isSubmitBtnDisabled = false; - }); - } } From f84a1d7705c292a06b49a5c11d66f31a481b7ede Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 13:00:56 +0200 Subject: [PATCH 08/10] updated js based on feedback --- .../taskChecklistPanel/taskChecklistPanel.js | 71 +++++++++---------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js index 364e323..2057e13 100644 --- a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js @@ -19,7 +19,6 @@ export default class TaskChecklistPanel extends LightningElement { getChecklistData({ caseId: this.recordId }) .then((data) => { this.processData(data); - this.calculateProgress(); }) .catch((error) => { console.error("Error fetching data:", error); @@ -39,6 +38,40 @@ export default class TaskChecklistPanel extends LightningElement { task.Label += " (" + task.CompletedDateFormula__c + ")"; } } + + this.calculateProgress(); + } + + /** + * + */ + calculateProgress() { + const totalTasksCompleted = this.taskList.filter( + (task) => task.IsCompleted__c + ).length; + + this.progress = + this.taskList.length === 0 + ? 0 + : totalTasksCompleted / this.taskList.length; + } + + /** + * + * @param {*} event + */ + handleCheckboxChange(event) { + const checkbox = event.target; + + if (!checkbox.checked) { + // Remove TaskId from list + this.taskIdsToUpdate = this.taskIdsToUpdate.filter( + (taskId) => taskId !== checkbox.name + ); + } else { + // Add TaskId to list + this.taskIdsToUpdate.push(checkbox.name); + } } /** @@ -58,7 +91,6 @@ export default class TaskChecklistPanel extends LightningElement { }) .then((data) => { this.processData(data); - this.calculateProgress(); // We did the things, enable the Submit button and empty the update list this.isSubmitBtnDisabled = false; this.taskIdsToUpdate = []; @@ -68,39 +100,4 @@ export default class TaskChecklistPanel extends LightningElement { this.isSubmitBtnDisabled = false; }); } - - /** - * - */ - calculateProgress() { - let totalTasksCompleted = 0; - for (const task of this.taskList) { - if (task.IsCompleted__c) { - totalTasksCompleted++; - } - } - - this.progress = (totalTasksCompleted / this.taskList.length) * 100; - } - - /** - * - * @param {*} event - */ - handleCheckboxChange(event) { - const checkbox = event.target; - - if (this.taskIdsToUpdate.includes(checkbox.name) && !checkbox.checked) { - // Remove TaskId from list - this.taskIdsToUpdate = this.taskIdsToUpdate.filter( - (taskId) => taskId !== checkbox.name - ); - } else if ( - !this.taskIdsToUpdate.includes(checkbox.name) && - checkbox.checked - ) { - // Add TaskId to list - this.taskIdsToUpdate.push(checkbox.name); - } - } } From 2bbef2904fd0904c99fb1033d85768dda5a09557 Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Fri, 9 May 2025 17:40:32 +0200 Subject: [PATCH 09/10] further tidy up of js --- .../taskChecklistPanel/taskChecklistPanel.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js index 2057e13..67bb2bc 100644 --- a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js @@ -34,6 +34,8 @@ export default class TaskChecklistPanel extends LightningElement { // If Task is completed, show the completion date from formula field for (const task of this.taskList) { task.Label = task.Subject; + + // Add completed date to label, can look silly with longer Subject string lengths if (task.IsCompleted__c) { task.Label += " (" + task.CompletedDateFormula__c + ")"; } @@ -53,7 +55,7 @@ export default class TaskChecklistPanel extends LightningElement { this.progress = this.taskList.length === 0 ? 0 - : totalTasksCompleted / this.taskList.length; + : (totalTasksCompleted / this.taskList.length) * 100; } /** @@ -63,15 +65,16 @@ export default class TaskChecklistPanel extends LightningElement { handleCheckboxChange(event) { const checkbox = event.target; - if (!checkbox.checked) { - // Remove TaskId from list - this.taskIdsToUpdate = this.taskIdsToUpdate.filter( - (taskId) => taskId !== checkbox.name - ); - } else { + if (checkbox.checked) { // Add TaskId to list this.taskIdsToUpdate.push(checkbox.name); + return; } + + // Remove TaskId from list + this.taskIdsToUpdate = this.taskIdsToUpdate.filter( + (taskId) => taskId !== checkbox.name + ); } /** From 9ceccd0e5b36b0c609f0abe2e9179559c222f43a Mon Sep 17 00:00:00 2001 From: Jason Auger Date: Sat, 10 May 2025 15:37:26 +0200 Subject: [PATCH 10/10] updated js comments --- .../taskChecklistPanel/taskChecklistPanel.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js index 67bb2bc..13a25c1 100644 --- a/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js +++ b/force-app/main/default/lwc/taskChecklistPanel/taskChecklistPanel.js @@ -3,17 +3,16 @@ import getChecklistData from "@salesforce/apex/TaskChecklistPanelLWCController.g import updateChecklist from "@salesforce/apex/TaskChecklistPanelLWCController.updateTaskStatuses"; export default class TaskChecklistPanel extends LightningElement { - // Case record Id - @api recordId; + @api recordId; // Case record Id - @track taskList = []; - @track progress = 0; - @track isSubmitBtnDisabled = false; + @track taskList = []; // List of Tasks to be passed to the template for-loop + @track progress = 0; // Value to be fed to the progress bar + @track isSubmitBtnDisabled = false; // Used to disable the submit button while data is updated taskIdsToUpdate = []; /** - * + * On load, get our lists of Tasks realted to the Case */ connectedCallback() { getChecklistData({ caseId: this.recordId }) @@ -26,7 +25,8 @@ export default class TaskChecklistPanel extends LightningElement { } /** - * + * Process data as it comes in. Update Labels with the completed date if completed + * Updates the progress bar */ processData(data) { this.taskList = data; @@ -45,7 +45,7 @@ export default class TaskChecklistPanel extends LightningElement { } /** - * + * Calcaulates the value to assign to the progress bar */ calculateProgress() { const totalTasksCompleted = this.taskList.filter( @@ -59,7 +59,9 @@ export default class TaskChecklistPanel extends LightningElement { } /** - * + * Called from a lightning-input: checkbox. If the box is now checked, adds the 'name' value (Task.Id) + * to the taskIdsToUpdate stack. If the box is now unchecked, removes the 'name' value (Task.Id) from + * the stack * @param {*} event */ handleCheckboxChange(event) { @@ -78,7 +80,8 @@ export default class TaskChecklistPanel extends LightningElement { } /** - * + * If there are values to update, submit them to be set to Completed + * then repopulate our data */ handleUpdateTaskStatuses() { // Nothing is selected, so don't do anything