From a1e4524b6b6db2dc1ab5a51cede2f9d21dee88e6 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 14:27:04 -0400 Subject: [PATCH 01/38] Version # CHange --- flow_screen_components/datatable/README.md | 7 +++++++ .../default/lwc/ers_datatableUtils/ers_datatableUtils.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index 88d20cabf..f4514b725 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -72,6 +72,13 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th --- # Release Notes +## 06/xx/24 - Eric Smith - Version 4.2.1 +**Updates:** +- TBD + +**Bug Fixes:** +- TBD + ## 04/06/24 - Eric Smith - Version 4.2.0 **Updates:** - Added optional pagination diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index 0d38a2368..fe5116927 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -33,7 +33,7 @@ console.log("DATATABLE isCommunity, isFlowBuilder:", isCommunity, isFlowBuilder) const getConstants = () => { return { - VERSION_NUMBER : '4.2.0', // Current Source Code Version # + VERSION_NUMBER : '4.2.1', // Current Source Code Version # MAXROWCOUNT : 2000, // Limit the total number of records to be handled by this component ROUNDWIDTH : 5, // Used to round off the column widths during Config Mode to nearest value WIZROWCOUNT : 6, // Number of records to display in the Column Wizard datatable From 92649221bb7d3dac40e5e9562f2ab5c578de3e59 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 14:37:41 -0400 Subject: [PATCH 02/38] Fix hyperlink bug --- flow_screen_components/datatable/README.md | 2 +- .../main/default/lwc/ers_datatableUtils/ers_datatableUtils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index f4514b725..47c8e3981 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -77,7 +77,7 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th - TBD **Bug Fixes:** -- TBD +- Fixed bug where hyperlinks would open the flow rather than the referenced record ## 04/06/24 - Eric Smith - Version 4.2.0 **Updates:** diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index fe5116927..1347e5c05 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -23,7 +23,7 @@ if (baseURL.includes('--c.visualforce.') || baseURL.includes('--c.vf.')) { / myDomain = myDomain.split('/s/')[0] + '/s/'; // v3.4.5 Remove everything after the /s/ (non-home pages) isCommunity = true; } -if (myDomain.includes('flow/runtime')) { // Running in Flow Builder || Flow Builder (Enhanced Domain) +if (myDomain.includes('flow/runtime') || myDomain.includes('/flow/')) { // Running in Flow Builder || Flow Builder (Enhanced Domain) myDomain = baseURL; isCommunity = false; isFlowBuilder = true; From f61ea2c68d484faba6e4993a873bb9b44d6c285b Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 14:41:32 -0400 Subject: [PATCH 03/38] Column Filter Hang Bug --- flow_screen_components/datatable/README.md | 3 ++- .../force-app/main/default/lwc/datatable/datatable.js | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index 47c8e3981..be2f7d4d0 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -77,7 +77,8 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th - TBD **Bug Fixes:** -- Fixed bug where hyperlinks would open the flow rather than the referenced record +- Fixed bug where hyperlinks would open the flow rather than the referenced record +- Fixed bug where a column filter would hang if there was no filter on the first column ## 04/06/24 - Eric Smith - Version 4.2.0 **Updates:** diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index a4d2ebf3a..766ff5a0a 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -2418,7 +2418,9 @@ export default class Datatable extends LightningElement { this.isFiltered = true; this.filterColumns[col].actions.find(a => a.name == 'clear_'+col).disabled = false; } else { - this.filterColumns[col].actions.find(a => a.name == 'clear_'+col).disabled = true; + if (this.filterColumns[col].actions && this.filterColumns[col].actions != null) { // *** v4.2.1 fix *** + this.filterColumns[col].actions.find(a => a.name == 'clear_'+col).disabled = true; + } } } if (match) { From aa80d65383429e007847234f7fadc91bf24bf91a Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 14:50:08 -0400 Subject: [PATCH 04/38] _pageCurrentNumber fix --- .../force-app/main/default/lwc/datatable/datatable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 766ff5a0a..587fd4a78 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -549,11 +549,11 @@ export default class Datatable extends LightningElement { } get isFirstPage() { - return (this.pageCurrentNumber === 1); + return (this._pageCurrentNumber === 1); } get isLastpage() { - return (this.pageCurrentNumber === this.pageTotalCount); + return (this._pageCurrentNumber === this.pageTotalCount); } get isOnlyOnePage() { From 158841de12fe514bee6ffb1eeba9ec7c66ec5fd4 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 15:08:32 -0400 Subject: [PATCH 05/38] Hide Next/Last if page#>=#pages --- .../datatable/force-app/main/default/lwc/datatable/datatable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 587fd4a78..60041328e 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -553,7 +553,7 @@ export default class Datatable extends LightningElement { } get isLastpage() { - return (this._pageCurrentNumber === this.pageTotalCount); + return (this._pageCurrentNumber >= this.pageTotalCount); } get isOnlyOnePage() { From 493886e5e5c0ae7d18e879077f8cdc68af3e4762 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 16:00:43 -0400 Subject: [PATCH 06/38] Change def recs/page from 9 to 10 --- .../main/default/lwc/ers_datatableUtils/ers_datatableUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index 1347e5c05..6bfcb8cc2 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -45,7 +45,7 @@ const getConstants = () => { CB_ATTRIB_PREFIX : 'cb_', // Used with fsc_flowCheckbox component MIN_SEARCH_TERM_SIZE : 2, // Set the minimum number of characters required to start searching SEARCH_WAIT_TIME : 300, // Set the delay to start searching while user is typing a search term - RECORDS_PER_PAGE : 9, // Default number of records per page for pagination + RECORDS_PER_PAGE : 10, // Default number of records per page for pagination } } From da7588e1d0aeab08493b9abb438e682b6af6b9f2 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 17:37:57 -0400 Subject: [PATCH 07/38] Default option to hide record details from console & debug logs --- .../classes/ers_DatatableController.cls | 28 +++--- .../default/classes/ers_QueryNRecords.cls | 14 ++- .../main/default/lwc/datatable/datatable.js | 88 ++++++++++--------- .../ers_customLightningDatatable.js | 10 ++- .../lwc/ers_datatableCPE/ers_datatableCPE.js | 46 +++++----- .../ers_datatableUtils/ers_datatableUtils.js | 8 +- 6 files changed, 111 insertions(+), 83 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/classes/ers_DatatableController.cls b/flow_screen_components/datatable/force-app/main/default/classes/ers_DatatableController.cls index e3ffe408b..5477056c8 100644 --- a/flow_screen_components/datatable/force-app/main/default/classes/ers_DatatableController.cls +++ b/flow_screen_components/datatable/force-app/main/default/classes/ers_DatatableController.cls @@ -54,6 +54,8 @@ public with sharing class ers_DatatableController { @TestVisible private static Boolean isMultiCurrencyOrganization = UserInfo.isMultiCurrencyOrganization(); + private static Boolean SHOW_DEBUG_INFO = false; + private static String DEBUG_INFO_PREFIX = 'DATATABLE: '; /** * this is just a convenient way to return multiple unique pieces of data to the component @@ -98,7 +100,9 @@ public with sharing class ers_DatatableController { cpeRR.objectLabel = objDescribe.getLabel(); cpeRR.objectPluralLabel = objDescribe.getLabelPlural(); cpeRR.objectIconName = getIconName(objName); - System.debug(LoggingLevel.INFO, 'cpeRR - ' + JSON.serializePretty(cpeRR)); + if (SHOW_DEBUG_INFO) { + System.debug(LoggingLevel.INFO, 'cpeRR - ' + JSON.serializePretty(cpeRR)); + } return JSON.serialize(cpeRR); } @@ -108,9 +112,11 @@ public with sharing class ers_DatatableController { String fieldNames, Boolean suppressCurrencyConversion ) { - System.debug(LoggingLevel.INFO, 'records-' + records); - System.debug(LoggingLevel.INFO, 'fieldNames-' + fieldNames); - System.debug(LoggingLevel.INFO, 'suppressCurrencyConversion-' + suppressCurrencyConversion); + if (SHOW_DEBUG_INFO) { + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'records-' + records); + } + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'fieldNames-' + fieldNames); + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'suppressCurrencyConversion-' + suppressCurrencyConversion); ReturnResults curRR = new ReturnResults(); if (records.isEmpty()) { // throw new MyApexException ('The datatable record collection is empty'); @@ -151,7 +157,9 @@ public with sharing class ers_DatatableController { curRR.objectName = objName; } curRR.timezoneOffset = getTimezoneOffset().format(); - System.debug(LoggingLevel.INFO, 'curRR - ' + JSON.serializePretty(curRR)); + if (SHOW_DEBUG_INFO) { + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'curRR - ' + JSON.serializePretty(curRR)); + } return JSON.serialize(curRR); } @@ -183,7 +191,7 @@ public with sharing class ers_DatatableController { List numberFields = new List(); Map> picklistFieldLabels = new Map>(); String objectLinkField = getNameUniqueField(objName); // Name (link) Field for the Datatable SObject - System.debug(LoggingLevel.INFO, '*** OBJ/LINK' + objName + '/' + objectLinkField); + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + '*** OBJ/LINK' + objName + '/' + objectLinkField); Map fieldMap = objDescribe.fields.getMap(); @@ -272,7 +280,7 @@ public with sharing class ers_DatatableController { picklistFieldLabels.put(dfr.getName(), valueLabelPair); } when else { - System.debug('No field type match'); + System.debug(DEBUG_INFO_PREFIX + 'No field type match: ' + dfr.getType().name()); } } } @@ -345,7 +353,7 @@ public with sharing class ers_DatatableController { SObject[] recs = Database.query( 'SELECT Id, ' + nameField + ' FROM ' + obj + ' WHERE Id IN :ids' ); //NOPMD - System.debug(LoggingLevel.INFO, 'Name Field: ' + obj + ' - ' + nameField); + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'Name Field: ' + obj + ' - ' + nameField); Map somap = new Map(); for (SObject so : recs) { somap.put((Id) so.get('Id'), so); @@ -586,7 +594,7 @@ public with sharing class ers_DatatableController { // Thanks to Satya.2020 (https://developer.salesforce.com/forums/?id=9062I000000IQ3eQAG) @TestVisible private static String getIconName(String sObjectName) { - System.debug(LoggingLevel.INFO, 'Getting Icon for: ' + sObjectName); + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'Getting Icon for: ' + sObjectName); String iconName; List tabSetDesc = Schema.describeTabs(); List tabDesc = new List(); @@ -613,7 +621,7 @@ public with sharing class ers_DatatableController { break; } } - System.debug(LoggingLevel.INFO, 'iconName: ' + iconName); + System.debug(LoggingLevel.INFO, DEBUG_INFO_PREFIX + 'iconName: ' + iconName); return iconName; } } \ No newline at end of file diff --git a/flow_screen_components/datatable/force-app/main/default/classes/ers_QueryNRecords.cls b/flow_screen_components/datatable/force-app/main/default/classes/ers_QueryNRecords.cls index 98a1d4931..42af3fed6 100644 --- a/flow_screen_components/datatable/force-app/main/default/classes/ers_QueryNRecords.cls +++ b/flow_screen_components/datatable/force-app/main/default/classes/ers_QueryNRecords.cls @@ -9,6 +9,10 @@ */ @SuppressWarnings('PMD.ClassNamingConventions') public inherited sharing class ers_QueryNRecords { + + private static Boolean SHOW_DEBUG_INFO = false; + private static String DEBUG_INFO_PREFIX = 'DATATABLE: '; + /** * Class definition for throwing custom exceptions */ @@ -34,10 +38,12 @@ public inherited sharing class ers_QueryNRecords { queryParam.objectApiName + ' LIMIT ' + queryParam.numberOfRecords; - System.debug('QUERY: ' + query); + System.debug(DEBUG_INFO_PREFIX + 'QUERY: ' + query); try { sObject[] recordList = database.query(query); //NOPMD - System.debug(recordList); + if (SHOW_DEBUG_INFO) { + System.debug(DEBUG_INFO_PREFIX + 'Record List:' + recordList); + } // Make sure there are the requested # of records if (!recordList.isEmpty() && recordList.size() < 10) { @@ -45,7 +51,7 @@ public inherited sharing class ers_QueryNRecords { recordList.add(recordList[0]); } } - System.debug('Number of Records: ' + recordList.size()); + System.debug(DEBUG_INFO_PREFIX + 'Number of Records: ' + recordList.size()); // Include null fields in the serialized result List> records = new List>(); @@ -77,7 +83,7 @@ public inherited sharing class ers_QueryNRecords { // qr.recordString = JSON.serialize(recordList); result.add(qr); } catch (Exception e) { - System.debug('ers_QueryNRecords Error: ' + e); + System.debug(DEBUG_INFO_PREFIX + 'ers_QueryNRecords Error: ' + e); throw e; } } diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 60041328e..1e9c7c216 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -36,7 +36,7 @@ import ShowingPagePrefix from '@salesforce/label/c.ers_ShowingPagePrefix'; import ShowingPageMiddle from '@salesforce/label/c.ers_ShowingPageMiddle'; import ShowingPageSuffix from '@salesforce/label/c.ers_ShowingPageSuffix'; -const CONSTANTS = getConstants(); // From ers_datatableUtils : VERSION_NUMBER, MAXROWCOUNT, ROUNDWIDTH, MYDOMAIN, ISCOMMUNITY, ISFLOWBUILDER, MIN_SEARCH_TERM_SIZE, SEARCH_WAIT_TIME, RECORDS_PER_PAGE +const CONSTANTS = getConstants(); // From ers_datatableUtils : VERSION_NUMBER, MAXROWCOUNT, ROUNDWIDTH, MYDOMAIN, ISCOMMUNITY, ISFLOWBUILDER, MIN_SEARCH_TERM_SIZE, SEARCH_WAIT_TIME, RECORDS_PER_PAGE, SHOW_DEBUG_INFO, DEBUG_INFO_PREFIX const MYDOMAIN = CONSTANTS.MYDOMAIN; const ISCOMMUNITY = CONSTANTS.ISCOMMUNITY; @@ -45,6 +45,8 @@ const CB_TRUE = CONSTANTS.CB_TRUE; const MIN_SEARCH_TERM_SIZE = CONSTANTS.MIN_SEARCH_TERM_SIZE; const SEARCH_WAIT_TIME = CONSTANTS.SEARCH_WAIT_TIME; const RECORDS_PER_PAGE = CONSTANTS.RECORDS_PER_PAGE; +const SHOW_DEBUG_INFO = CONSTANTS.SHOW_DEBUG_INFO; +const DEBUG_INFO_PREFIX = CONSTANTS.DEBUG_INFO_PREFIX; export default class Datatable extends LightningElement { @@ -680,7 +682,7 @@ export default class Datatable extends LightningElement { } else if (error) { // An error is expected here if the running user does not have Read access to the datatable SObject // All picklist values will be used instead of just those specified by the supplied Record Type Id - console.log('getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); + console.log(DEBUG_INFO_PREFIX+'getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); } if (data != undefined || error != undefined) { // Update row data for lookup, time, picklist and percent fields @@ -731,8 +733,8 @@ export default class Datatable extends LightningElement { // Display the component version number in the console log const logStyleText = 'color: green; font-size: 16px'; const logStyleNumber = 'color: red; font-size: 16px'; - console.log("%cdatatable VERSION_NUMBER: %c"+CONSTANTS.VERSION_NUMBER, logStyleText, logStyleNumber); - console.log('MYDOMAIN', MYDOMAIN); + console.log("%cDATATABLE VERSION_NUMBER: %c"+CONSTANTS.VERSION_NUMBER, logStyleText, logStyleNumber); + console.log(DEBUG_INFO_PREFIX+'MYDOMAIN', MYDOMAIN); // Picklist field processing if (!this.recordTypeId) this.recordTypeId = this.masterRecordTypeId; @@ -751,21 +753,22 @@ export default class Datatable extends LightningElement { this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); - console.log("Config Mode Input columnAlignments:", this.columnAlignments); - console.log("Config Mode Input columnEdits:", this.columnEdits); - console.log("Config Mode Input columnFilters:", this.columnFilters); - console.log("Config Mode Input columnIcons:", this.columnIcons); - console.log("Config Mode Input columnLabels:", this.columnLabels); - console.log("Config Mode Input columnWidths:", this.columnWidths); - console.log("Config Mode Input columnWraps:", this.columnWraps); - console.log("Config Mode Input columnFlexes:", this.columnFlexes); - console.log("Config Mode Input columnFields:", this.columnFields); - console.log("Config Mode Input columnCellAttribs:", this.columnCellAttribs); - console.log("Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); - console.log("Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnAlignments:", this.columnAlignments); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnEdits:", this.columnEdits); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFilters:", this.columnFilters); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnIcons:", this.columnIcons); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnLabels:", this.columnLabels); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnWidths:", this.columnWidths); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnWraps:", this.columnWraps); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFlexes:", this.columnFlexes); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFields:", this.columnFields); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); + console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); // this.not_suppressNameFieldLink = false; } - console.log('tableDataString - ',this._tableDataString, this.isUserDefinedObject); + + console.log(DEBUG_INFO_PREFIX+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***', this.isUserDefinedObject); if (this.isUserDefinedObject) { this.assignApexDefinedRecords(); @@ -779,8 +782,9 @@ export default class Datatable extends LightningElement { // Pagination Initiation this.initiatePagination(); - console.log('this._tableData',this._tableData); - if(!this._tableData) { + console.log(DEBUG_INFO_PREFIX+'this._tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); + + if (!this._tableData) { this.isUpdateTable = false; this._tableData = []; } @@ -796,7 +800,7 @@ export default class Datatable extends LightningElement { // Get array of column field API names this.columnArray = (this.columnFields.length > 0) ? this.columnFields.replace(/\s/g, '').split(',') : []; this.columnFieldParameter = this.columnArray.join(', '); - console.log('columnArray - ',this.columnArray); + console.log(DEBUG_INFO_PREFIX+'columnArray - ',this.columnArray); // JSON Version - Build basicColumns default values if (this.isUserDefinedObject) { @@ -978,7 +982,7 @@ export default class Datatable extends LightningElement { if (!this.allowOverflow) { this.tableHeightAttribute = 'height:' + this.tableHeight; } - console.log('tableHeightAttribute',this.tableHeightAttribute); + console.log(DEBUG_INFO_PREFIX+'tableHeightAttribute',this.tableHeightAttribute); // Set table border display //this.borderClass = (this.tableBorder == true) ? 'slds-box' : ''; commented out to remove padding. replaced with below @@ -993,7 +997,7 @@ export default class Datatable extends LightningElement { // Set other initial values here this.wizColumnFields = this.columnFields; - console.log('Processing Datatable'); + console.log(DEBUG_INFO_PREFIX+'Processing Datatable'); this.processDatatable(); this.isUpdateTable = true; // Added in v4.1.1 so Datatable will show records from Datafetcher upon initialization @@ -1005,7 +1009,7 @@ export default class Datatable extends LightningElement { assignApexDefinedRecords() { // JSON input attributes - console.log('tableDataString - ',this._tableDataString); + console.log(DEBUG_INFO_PREFIX+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***'); if (!this._tableDataString || this._tableDataString?.length == 0) { this._tableDataString = '[{"'+this.keyField+'":"(empty table)"}]'; this.columnFields = this.keyField; @@ -1013,7 +1017,7 @@ export default class Datatable extends LightningElement { this.columnScales = []; } this._tableData = JSON.parse(this._tableDataString); - console.log('tableData - ',this._tableData); + console.log(DEBUG_INFO_PREFIX+'tableData - ',(SHOW_DEBUG_INFO) ? this._tableData : '***'); this.preSelectedRows = (this.preSelectedRowsString.length > 0) ? JSON.parse(this.preSelectedRowsString) : []; } @@ -1125,7 +1129,7 @@ export default class Datatable extends LightningElement { } let fieldList = (this.columnFields.length > 0) ? this.columnFields.replace(/\s/g, '') : ''; // Remove spaces - console.log('Passing data to Apex Controller', data); + console.log(DEBUG_INFO_PREFIX+'Passing data to Apex Controller', (SHOW_DEBUG_INFO) ? data : '***'); getReturnResults({ records: data, fieldNames: fieldList, suppressCurrencyConversion: this.suppressCurrencyConversion }) .then(result => { let returnResults = JSON.parse(result); @@ -1137,17 +1141,17 @@ export default class Datatable extends LightningElement { this.numberFieldArray = (returnResults.numberFieldList.length > 0) ? returnResults.numberFieldList.toString().split(',') : []; this.timeFieldArray = (returnResults.timeFieldList.length > 0) ? returnResults.timeFieldList.toString().split(',') : []; this.datetimeFieldArray = (returnResults.datetimeFieldList.length > 0) ? returnResults.datetimeFieldList.toString().split(',') : []; - console.log("Datetime Fields ~ returnResults.datetimeFieldList.toString()", returnResults.datetimeFieldList.toString()); + console.log(DEBUG_INFO_PREFIX+"Datetime Fields ~ returnResults.datetimeFieldList.toString()", returnResults.datetimeFieldList.toString()); this.picklistFieldArray = (returnResults.picklistFieldList.length > 0) ? returnResults.picklistFieldList.toString().split(',') : []; this.picklistReplaceValues = (this.picklistFieldArray.length > 0); // Flag value dependent on if there are any picklists in the datatable field list this.apex_picklistFieldMap = returnResults.picklistFieldMap; - console.log("Picklist Fields ~ this.apex_picklistFieldMap", this.apex_picklistFieldMap); + console.log(DEBUG_INFO_PREFIX+"Picklist Fields ~ this.apex_picklistFieldMap", this.apex_picklistFieldMap); this.dateFieldArray = (returnResults.dateFieldList.length > 0) ? returnResults.dateFieldList.toString().split(',') : []; this.objectNameLookup = returnResults.objectName; this.objectLinkField = returnResults.objectLinkField; this.lookupFieldArray = JSON.parse('[' + returnResults.lookupFieldData + ']'); this.timezoneOffset = returnResults.timezoneOffset.replace(/[^\d-]/g, ''); // Numeric characters and - only - console.log("Timezone Offset ~ this.timezoneOffset", this.timezoneOffset); + console.log(DEBUG_INFO_PREFIX+"Timezone Offset ~ this.timezoneOffset", this.timezoneOffset); // Check for differences in picklist API Values vs Labels if (this.picklistReplaceValues) { @@ -1165,7 +1169,7 @@ export default class Datatable extends LightningElement { // Basic column info (label, fieldName, type) taken from the Schema in Apex this.dtableColumnFieldDescriptorString = '[' + returnResults.dtableColumnFieldDescriptorString + ']'; this.basicColumns = JSON.parse(this.dtableColumnFieldDescriptorString); - console.log('dtableColumnFieldDescriptorString',this.dtableColumnFieldDescriptorString, this.basicColumns); + console.log(DEBUG_INFO_PREFIX+'dtableColumnFieldDescriptorString',this.dtableColumnFieldDescriptorString, this.basicColumns); this.noEditFieldArray = (returnResults.noEditFieldList.length > 0) ? returnResults.noEditFieldList.toString().split(',') : []; // *** Moved to @wire *** @@ -1182,7 +1186,7 @@ export default class Datatable extends LightningElement { }) // Handle any errors from the Apex Class .catch(error => { - console.log('getReturnResults error is: ' + JSON.stringify(error)); + console.log(DEBUG_INFO_PREFIX+'getReturnResults error is: ' + JSON.stringify(error)); if (error.body) { this.errorApex = 'Apex Action error: ' + error.body.message; alert(this.errorApex + '\n'); // Present the error to the user @@ -1196,7 +1200,7 @@ export default class Datatable extends LightningElement { updateDataRows() { // Process Incoming Data Collection - console.log('Processing updateDataRows') + console.log(DEBUG_INFO_PREFIX+'Processing updateDataRows') let data = (this.recordData) ? JSON.parse(JSON.stringify([...this.recordData].slice(0,this.collectionSize))) : []; let lookupFields = this.lookups; let lufield = ''; @@ -1316,15 +1320,15 @@ export default class Datatable extends LightningElement { this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only - console.log('selectedRows',this.selectedRows); - console.log('keyField:',this.keyField); - console.log('tableData',this._tableData); - console.log('mydata:',this._mydata); + console.log(DEBUG_INFO_PREFIX+'selectedRows',(SHOW_DEBUG_INFO) ? this.selectedRows : '***'); + console.log(DEBUG_INFO_PREFIX+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); + console.log(DEBUG_INFO_PREFIX+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); + console.log(DEBUG_INFO_PREFIX+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); } updateColumns() { // Parse column definitions - console.log('Processing updateColumns') + console.log(DEBUG_INFO_PREFIX+'Processing updateColumns') this.cols = []; let columnNumber = 0; let lufield = ''; @@ -1598,7 +1602,7 @@ export default class Datatable extends LightningElement { wrapText: (wrapAttrib) ? wrapAttrib.wrap : false, flex: (flexAttrib) ? flexAttrib.flex : false }); - console.log('this.cols',this.cols); + console.log(DEBUG_INFO_PREFIX+'this.cols',this.cols); // Update Other Attributes attribute overrides by column this.parseAttributes('other',this.otherAttribs,columnNumber); @@ -1825,7 +1829,7 @@ export default class Datatable extends LightningElement { } } catch(err) { - console.log("Date not in ISO format", date, field[date]); + console.log(DEBUG_INFO_PREFIX+"Date not in ISO format", date, field[date]); } } }); @@ -1953,7 +1957,7 @@ export default class Datatable extends LightningElement { updateColumnSorting(event) { // Handle column sorting - console.log('Sort:',event.detail.fieldName,event.detail.sortDirection); + console.log(DEBUG_INFO_PREFIX+'Sort:',event.detail.fieldName,event.detail.sortDirection); this.sortedBy = event.detail.fieldName; this.sortDirection = event.detail.sortDirection; this.isUpdateTable = false; @@ -2659,7 +2663,7 @@ export default class Datatable extends LightningElement { @api validate() { - console.log("validate and exit"); + console.log(DEBUG_INFO_PREFIX+"validate and exit"); // Finalize Selected Records for Output let sdata = []; @@ -2708,8 +2712,8 @@ export default class Datatable extends LightningElement { this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); } - console.log('outputSelectedRows', this.outputSelectedRows.length, this.outputSelectedRows); - console.log('outputEditedRows',this.outputEditedRows.length, this.outputEditedRows); + console.log(DEBUG_INFO_PREFIX+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); + console.log(DEBUG_INFO_PREFIX+'outputEditedRows',this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); // Validation logic to pass back to the Flow if(!this.isRequired || this.numberOfRowsSelected > 0) { diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_customLightningDatatable/ers_customLightningDatatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_customLightningDatatable/ers_customLightningDatatable.js index 063839f87..34a04155e 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_customLightningDatatable/ers_customLightningDatatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_customLightningDatatable/ers_customLightningDatatable.js @@ -3,6 +3,12 @@ import ers_richTextColumnType from "./ers_richTextColumnType.html"; import ers_comboboxColumnType from "./ers_comboboxColumnType.html"; import stylesheet from '@salesforce/resourceUrl/ers_customLightningDatatableStyles'; import {loadStyle} from "lightning/platformResourceLoader"; +import { getConstants } from 'c/ers_datatableUtils'; + +const CONSTANTS = getConstants(); // From ers_datatableUtils : SHOW_DEBUG_INFO, DEBUG_INFO_PREFIX + +const SHOW_DEBUG_INFO = CONSTANTS.SHOW_DEBUG_INFO; +const DEBUG_INFO_PREFIX = CONSTANTS.DEBUG_INFO_PREFIX; /** * Custom component that extends LightningDatatable @@ -15,9 +21,9 @@ export default class ers_customLightningDatatable extends LightningDatatable { Promise.all([ loadStyle(this, stylesheet) ]).then(() => { - console.log("Loaded style sheet"); + console.log(DEBUG_INFO_PREFIX+"Loaded style sheet"); }).catch(error => { - console.error('Error loading stylesheet', error); + console.error(DEBUG_INFO_PREFIX+'Error loading stylesheet', error); }); } diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js index 7d39d8aa9..db9437526 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js @@ -17,11 +17,13 @@ import {LightningElement, track, api} from 'lwc'; import getCPEReturnResults from '@salesforce/apex/ers_DatatableController.getCPEReturnResults'; import { getConstants } from 'c/ers_datatableUtils'; -const CONSTANTS = getConstants(); // From ers_datatableUtils : VERSION_NUMBER, MAXROWCOUNT, ROUNDWIDTH, MYDOMAIN, ISCOMMUNITY, WIZROWCOUNT +const CONSTANTS = getConstants(); // From ers_datatableUtils : VERSION_NUMBER, MAXROWCOUNT, ROUNDWIDTH, MYDOMAIN, ISCOMMUNITY, WIZROWCOUNT, SHOW_DEBUG_INFO, DEBUG_INFO_PREFIX const CB_TRUE = CONSTANTS.CB_TRUE; const CB_FALSE = CONSTANTS.CB_FALSE; const CB_PREFIX = CONSTANTS.CB_ATTRIB_PREFIX; const RECORDS_PER_PAGE = CONSTANTS.RECORDS_PER_PAGE; +const SHOW_DEBUG_INFO = CONSTANTS.SHOW_DEBUG_INFO; +const DEBUG_INFO_PREFIX = CONSTANTS.DEBUG_INFO_PREFIX; const defaults = { tableBorder: true, @@ -744,11 +746,11 @@ export default class ers_datatableCPE extends LightningElement { } initializeValues() { - console.log('ers_datatableCPE - initializeValues'); + console.log(DEBUG_INFO_PREFIX+'ers_datatableCPE - initializeValues'); this.isCheckboxColumnHidden = false; this._inputVariables.forEach(curInputParam => { if (curInputParam.name && curInputParam.value != null) { - console.log('Init:', curInputParam.name, curInputParam.valueDataType, curInputParam.value); + console.log(DEBUG_INFO_PREFIX+'Init:', curInputParam.name, curInputParam.valueDataType, curInputParam.value); if (curInputParam.name && this.inputValues[curInputParam.name] != null) { try { @@ -801,14 +803,14 @@ export default class ers_datatableCPE extends LightningElement { } handleDefaultAttributes() { - console.log('handle default attributes'); + console.log(DEBUG_INFO_PREFIX+'handle default attributes'); if (this.inputValues.recordsPerPage.value == null) { this.inputValues.recordsPerPage.value = RECORDS_PER_PAGE.toString(); } } handleBuildHelpInfo() { - console.log('build help info'); + console.log(DEBUG_INFO_PREFIX+'build help info'); this.helpSections.forEach(section => { this.sectionEntries[section.name].info = []; section.attributes.forEach(attribute => { @@ -822,11 +824,11 @@ export default class ers_datatableCPE extends LightningElement { } handleDynamicTypeMapping(event) { - console.log('handling a dynamic type mapping'); - console.log('event is ' + JSON.stringify(event)); + console.log(DEBUG_INFO_PREFIX+'handling a dynamic type mapping'); + console.log(DEBUG_INFO_PREFIX+'event is ' + JSON.stringify(event)); let typeValue = event.detail.objectType; const typeName = this._elementType === "Screen" ? 'T' : 'T__record'; - console.log('typeValue is: ' + typeValue); + console.log(DEBUG_INFO_PREFIX+'typeValue is: ' + typeValue); const dynamicTypeMapping = new CustomEvent('configuration_editor_generic_type_mapping_changed', { composed: true, cancelable: false, @@ -852,7 +854,7 @@ export default class ers_datatableCPE extends LightningElement { } handleGetObjectDetails(objName) { - console.log('Passing object name to Apex Controller', objName); + console.log(DEBUG_INFO_PREFIX+'Passing object name to Apex Controller', objName); getCPEReturnResults({ objName: objName }) .then(result => { let returnResults = JSON.parse(result); @@ -861,11 +863,11 @@ export default class ers_datatableCPE extends LightningElement { this.objectLabel = returnResults.objectLabel; this.objectPluralLabel = returnResults.objectPluralLabel; this.objectIconName = returnResults.objectIconName; - console.log(`Return Values for ${objName}, Label: ${this.objectLabel}, Plural: ${this.objectPluralLabel}, Icon: ${this.objectIconName}`); + console.log(`${DEBUG_INFO_PREFIX}Return Values for ${objName}, Label: ${this.objectLabel}, Plural: ${this.objectPluralLabel}, Icon: ${this.objectIconName}`); }) // Handle any errors from the Apex Class .catch(error => { - console.log('getCPEReturnResults error is: ' + JSON.stringify(error)); + console.log(DEBUG_INFO_PREFIX+'getCPEReturnResults error is: ' + JSON.stringify(error)); if (error.body) { this.errorApex = 'Apex Action error: ' + error.body.message; alert(this.errorApex + '\n'); // Present the error to the user @@ -1075,7 +1077,7 @@ export default class ers_datatableCPE extends LightningElement { } }); this.dispatchEvent(valueChangedEvent); - console.log('dispatchFlowValueChangeEvent', id, newValue, newValueDataType); + console.log(DEBUG_INFO_PREFIX+'dispatchFlowValueChangeEvent', id, newValue, newValueDataType); if (!newValue) { this.inputValues[id].value = newValue; // You need to force any cleared values back to inputValues } @@ -1099,7 +1101,7 @@ export default class ers_datatableCPE extends LightningElement { updateFlowParam(name, value, ifEmpty=null, noEncode=false) { // Set parameter values to pass to Wizard Flow - console.log('updateFlowParam:', name, value); + console.log(DEBUG_INFO_PREFIX+'updateFlowParam:', name, value); let currentValue = this.flowParams.find(param => param.name === name).value; if (value != currentValue) { if (noEncode) { @@ -1135,15 +1137,15 @@ export default class ers_datatableCPE extends LightningElement { // These are values coming back from the Wizard Flow handleFlowStatusChange(event) { - console.log('=== handleFlowStatusChange -', event.detail.status, '==='); + console.log(DEBUG_INFO_PREFIX+'=== handleFlowStatusChange -', event.detail.status, '==='); if (event.detail.status === "ERROR") { - console.log('Flow Error: ',JSON.stringify(event)); + console.log(DEBUG_INFO_PREFIX+'Flow Error: ',JSON.stringify(event)); } else { this.isFlowLoaded = true; event.detail.outputVariables.forEach(attribute => { let name = attribute.name; let value = attribute.value; - console.log('Output from Wizard Flow: ', name, value); + console.log(DEBUG_INFO_PREFIX+'Output from Wizard Flow: ', name, value); if (name == 'vSelectionMethod') { this.vSelectionMethod = value; @@ -1240,15 +1242,15 @@ export default class ers_datatableCPE extends LightningElement { } handleWizardCancel() { - console.log('handleWizardCancel'); + console.log(DEBUG_INFO_PREFIX+'handleWizardCancel'); } handleWizardRestart() { - console.log('handleWizardRestart'); + console.log(DEBUG_INFO_PREFIX+'handleWizardRestart'); } handleWizardNext() { - console.log('handleWizardNext'); + console.log(DEBUG_INFO_PREFIX+'handleWizardNext'); this.dispatchFlowActionEvent('next'); } @@ -1279,7 +1281,7 @@ export default class ers_datatableCPE extends LightningElement { handleKeyDown(event) { var keycode = event.code; if(keycode == 'Escape'){ - console.log('CPE ESC Key Pressed'); + console.log(DEBUG_INFO_PREFIX+'CPE ESC Key Pressed'); this.openModal = false; event.preventDefault(); event.stopImmediatePropagation(); @@ -1313,7 +1315,7 @@ export default class ers_datatableCPE extends LightningElement { allComboboxes.forEach(curCombobox => { if (!curCombobox.reportValidity()) { resultErrors.push('error'); - console.log('ComboBox Error:', error); + console.log(DEBUG_INFO_PREFIX+'ComboBox Error:', error); } }); } @@ -1328,7 +1330,7 @@ export default class ers_datatableCPE extends LightningElement { this.inputValues[key].isError = true; this.inputValues[key].errorMessage = errorString; this.inputValues[key].class += ' slds-has-error'; - console.log('CPE generated error:', key, isError, errorString); + console.log(DEBUG_INFO_PREFIX+'CPE generated error:', key, isError, errorString); } else { this.inputValues[key].isError = false; } diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index 6bfcb8cc2..52c426425 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -4,7 +4,7 @@ const reverse = str => str.split('').reverse().join(''); // Reverse all the characters in a string const baseURL = window.location.hostname || 'LWR'; // LWR Experience does not support window.xxx -console.log("DATATABLE environment baseURL", baseURL); +console.log("DATATABLE: environment baseURL", baseURL); var myDomain; var isCommunity = false; @@ -28,8 +28,8 @@ if (myDomain.includes('flow/runtime') || myDomain.includes('/flow/')) { // R isCommunity = false; isFlowBuilder = true; } -console.log("DATATABLE myDomain:", myDomain); -console.log("DATATABLE isCommunity, isFlowBuilder:", isCommunity, isFlowBuilder); +console.log("DATATABLE: myDomain:", myDomain); +console.log("DATATABLE: isCommunity, isFlowBuilder:", isCommunity, isFlowBuilder); const getConstants = () => { return { @@ -46,6 +46,8 @@ const getConstants = () => { MIN_SEARCH_TERM_SIZE : 2, // Set the minimum number of characters required to start searching SEARCH_WAIT_TIME : 300, // Set the delay to start searching while user is typing a search term RECORDS_PER_PAGE : 10, // Default number of records per page for pagination + SHOW_DEBUG_INFO : true, // Set to true to show sensitive debug info in the console and debug logs + DEBUG_INFO_PREFIX : 'DATATABLE: ' // Prefix to be used for debug info in the console } } From 8d6a44f3fcafee8fc4d20acf4b7158d10282f2b3 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 10 Jun 2024 17:41:41 -0400 Subject: [PATCH 08/38] SHOW_DEBUG_INFO reference in README --- flow_screen_components/datatable/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index be2f7d4d0..afbfffbae 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -74,7 +74,8 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th ## 06/xx/24 - Eric Smith - Version 4.2.1 **Updates:** -- TBD +- Implemented a default setting (SHOW_DEBUG_INFO = false) to hide record details from console and debug logs +- Source code changes in ers_datatableUtils.js, ers_DatatableController.cls & ers_QueryNRecords.cls **Bug Fixes:** - Fixed bug where hyperlinks would open the flow rather than the referenced record From 588a42f5021554d6e9e3f4a8420f633b39c060b1 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Wed, 26 Jun 2024 15:23:28 -0400 Subject: [PATCH 09/38] Display Remove Row icon column --- .../main/default/lwc/datatable/datatable.js | 40 ++++++++++++++++++- .../ers_customLightningDatatableStyles.css | 5 +++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 1e9c7c216..74dfe3d66 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -349,6 +349,11 @@ export default class Datatable extends LightningElement { @api scaleAttrib = []; @api typeAttrib = []; + // Remove Row Action Attributes + // 🚀🚀🚀 + @api removeLabel = 'Remove'; + @api removeIcon = 'utility:delete'; + // Configuration Wizard Only - Input Attributes @api objectName; @@ -1602,7 +1607,7 @@ export default class Datatable extends LightningElement { wrapText: (wrapAttrib) ? wrapAttrib.wrap : false, flex: (flexAttrib) ? flexAttrib.flex : false }); - console.log(DEBUG_INFO_PREFIX+'this.cols',this.cols); + // Update Other Attributes attribute overrides by column this.parseAttributes('other',this.otherAttribs,columnNumber); @@ -1611,8 +1616,37 @@ export default class Datatable extends LightningElement { columnNumber += 1; }); - this.columns = this.cols; + this.addRemoveRowAction(); // 🚀🚀🚀 + this.columns = this.cols; + console.log(DEBUG_INFO_PREFIX+'this.columns',this.columns); + + } + + addRemoveRowAction() { + // Add a special column with for a remove row action + this.cols.push({ + type: "button-icon", + label: null, + typeAttributes: { + name: "removeRow", + alternativeText: this.removeLabel, + iconName: this.removeIcon, + tooltip: this.removeLabel, + variant: "border", + size: "medium" + }, + cellAttributes: { + class: "remove-icon" + }, + editable: false, + actions: null, + sortable: false, + hideDefaultActions: true, + initialWidth: 50, + wrapText: false, + flex: false + }); } updatePreSelectedRows() { @@ -1689,8 +1723,10 @@ export default class Datatable extends LightningElement { handleRowAction(event) { // Process the row actions here const action = event.detail.action; +console.log("🚀 ~ handleRowAction ~ action:", action.name); const row = JSON.parse(JSON.stringify(event.detail.row)); const keyValue = row[this.keyField]; +console.log("🚀 ~ handleRowAction ~ keyValue:", keyValue); this.mydata = this._mydata.map(rowData => { if (rowData[this.keyField] === keyValue) { switch (action.name) { diff --git a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css index 91f403b88..eabf0282b 100644 --- a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css +++ b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css @@ -80,4 +80,9 @@ c-datatable c-ers_custom-lightning-datatable .dt-outer-container lightning-primi border-right: var(--lwc-borderWidthThin,1px) solid var(--lwc-colorBorder,rgb(229, 229, 229)); /* border-bottom: var(--lwc-borderWidthThin,1px) solid var(--lwc-colorBorder,rgb(229, 229, 229)); */ margin-left: -1px; +} + +/* v4.2.1 Remove Row Icon styling */ +.remove-icon { + --slds-c-icon-color-foreground: red; } \ No newline at end of file From 783d025d8e841e6dba753b5a30f22c38e4540aea Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 27 Jun 2024 18:14:28 -0400 Subject: [PATCH 10/38] Remove Row Processing --- .../main/default/lwc/datatable/datatable.js | 82 +++++++++++++++---- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 74dfe3d66..5f254794b 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -351,8 +351,8 @@ export default class Datatable extends LightningElement { // Remove Row Action Attributes // 🚀🚀🚀 - @api removeLabel = 'Remove'; - @api removeIcon = 'utility:delete'; + @api removeLabel = 'Remove Row'; + @api removeIcon = 'utility:close'; // Configuration Wizard Only - Input Attributes @api objectName; @@ -1616,7 +1616,7 @@ export default class Datatable extends LightningElement { columnNumber += 1; }); - this.addRemoveRowAction(); // 🚀🚀🚀 + if (!this.isConfigMode) this.addRemoveRowAction(); // 🚀🚀🚀 this.columns = this.cols; console.log(DEBUG_INFO_PREFIX+'this.columns',this.columns); @@ -1722,22 +1722,68 @@ export default class Datatable extends LightningElement { handleRowAction(event) { // Process the row actions here - const action = event.detail.action; -console.log("🚀 ~ handleRowAction ~ action:", action.name); + const action = event.detail.action.name; const row = JSON.parse(JSON.stringify(event.detail.row)); const keyValue = row[this.keyField]; -console.log("🚀 ~ handleRowAction ~ keyValue:", keyValue); - this.mydata = this._mydata.map(rowData => { - if (rowData[this.keyField] === keyValue) { - switch (action.name) { - // case 'action': goes here - // - // break; - default: + console.log(DEBUG_INFO_PREFIX+"handleRowAction ~ action, keyValue:", action, (SHOW_DEBUG_INFO) ? keyValue : '***'); + + switch (action) { + case 'removeRow': + // remove record from collection + this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + + // handle editedrows + this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; + this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; + this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); + this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + + if (this.mydata.length == 0) { // Last record was removed from the datatable + // clear last selected row + this.outputSelectedRows = []; + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); + this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + this.updateNumberOfRowsSelected(this.outputSelectedRows); + // refresh table + this.tableData = []; } + break; + default: + } + + // this.mydata = this._mydata.map(rowData => { + // if (rowData[this.keyField] === keyValue) { + // switch (action.name) { + // // case 'action': goes here + // // + // // break; + // default: + // } + // } + // return rowData; + // }); + } + + removeRowFromCollection(collection, keyValue) { + const index = this.findRowIndexById(collection, keyValue); + let result = collection; + if (index !== -1) { + result = collection.slice(0, index).concat(collection.slice(index +1)); + } + return result; + } + + findRowIndexById(collection, id) { + let idx = -1; + collection.some((row, index) => { + if (row[this.keyField] === id) { + idx = index; + return true; } - return rowData; + return false; }); + return idx; } //handle change on combobox @@ -2499,11 +2545,11 @@ console.log("🚀 ~ handleRowAction ~ keyValue:", keyValue); let match = false; for (let col = 0; col < cols.length; col++) { let fieldName = cols[col].fieldName; - if (fieldName.endsWith('_lookup')) { + if (fieldName?.endsWith('_lookup')) { fieldName = fieldName.slice(0,fieldName.lastIndexOf('_lookup')) + '_name'; } - - if (cols[col].type != 'boolean' && (!row[fieldName] || row[fieldName] == null)) { // No match because the field is empty + + if (cols[col].type != 'boolean' && (!row[fieldName] || row[fieldName] == null)) { // No match because the field is boolean or empty or it's a row action continue; } @@ -2749,7 +2795,7 @@ console.log("🚀 ~ handleRowAction ~ keyValue:", keyValue); } console.log(DEBUG_INFO_PREFIX+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); - console.log(DEBUG_INFO_PREFIX+'outputEditedRows',this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); + console.log(DEBUG_INFO_PREFIX+'outputEditedRows', this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); // Validation logic to pass back to the Flow if(!this.isRequired || this.numberOfRowsSelected > 0) { From ec7b979d52e5cedcf76e6de44d87a40af4b8ff24 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 1 Jul 2024 16:32:29 -0400 Subject: [PATCH 11/38] =?UTF-8?q?Selected=20working=20with=20Remove=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flow_screen_components/datatable/README.md | 4 +- .../main/default/lwc/datatable/datatable.html | 4 +- .../main/default/lwc/datatable/datatable.js | 128 ++++++++++++++++-- 3 files changed, 122 insertions(+), 14 deletions(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index afbfffbae..4352b015c 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -72,8 +72,10 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th --- # Release Notes -## 06/xx/24 - Eric Smith - Version 4.2.1 +## 07/xx/24 - Eric Smith - Version 4.2.1 **Updates:** +- New Feature: Add a Remove Row action as the first or last column in a Datatable. +- New outputs include a collection and a count of the removed rows. - Implemented a default setting (SHOW_DEBUG_INFO = false) to hide record details from console and debug logs - Source code changes in ers_datatableUtils.js, ers_DatatableController.cls & ers_QueryNRecords.cls diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.html b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.html index 926293ae2..922fee1cb 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.html +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.html @@ -161,7 +161,7 @@

Interact with this sample datatable to conf sorted-by={sortedBy} sorted-direction={sortDirection} max-row-selection={maxRowSelection} - selected-rows={selectedRows} + selected-rows={visibleSelectedRowIds} show-row-number-column={showRowNumbers} hide-checkbox-column={hideCheckboxColumn} suppress-bottom-bar={suppressBottomBar} @@ -259,7 +259,7 @@

Interact with this sample datatable to conf sorted-by={sortedBy} sorted-direction={sortDirection} max-row-selection={maxRowSelection} - selected-rows={selectedRows} + selected-rows={visibleSelectedRowIds} show-row-number-column={showRowNumbers} hide-checkbox-column={hideCheckboxColumn} suppress-bottom-bar={suppressBottomBar} diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 5f254794b..3279d7a40 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -101,6 +101,10 @@ export default class Datatable extends LightningElement { @api outputEditedRows = []; @api tableIcon; + // Remove Row Action Attributes + @api outputRemovedRows = []; + @api numberOfRowsRemoved = 0; + // v4.2.0 Make Table Header Label reactive // @api tableLabel; @api @@ -392,7 +396,6 @@ export default class Datatable extends LightningElement { @api columnWidthValues; @track columns = []; // @track mydata = []; - @track selectedRows = []; @track roundValueLabel; @track columnWidthsLabel; @track isAllEdit = false; @@ -405,6 +408,28 @@ export default class Datatable extends LightningElement { // +' border-top: var(--lwc-borderWidthThin,1px) solid var(--lwc-colorBorder,rgb(229, 229, 229));' // + ' border-right: var(--lwc-borderWidthThin,1px) solid var(--lwc-colorBorder,rgb(229, 229, 229)); margin: -1px;'; + // Handle Selected Rows retention + @api allSelectedRows; // Obsolete - No longer used but can't be removed + @api visibleSelectedRows; // Obsolete - No longer used but can't be removed + + @api + get allSelectedRowIds() { + return this._allSelectedRowIds; + } + set allSelectedRowIds(value) { + this._allSelectedRowIds = value; + } + _allSelectedRowIds = []; + + @api + get visibleSelectedRowIds() { + return this._visibleSelectedRowIds; + } + set visibleSelectedRowIds(value) { + this._visibleSelectedRowIds = value; + } + _visibleSelectedRowIds = []; + // Handle Lookup Field Variables @api lookupId; @api objectNameLookup; @@ -629,13 +654,27 @@ export default class Datatable extends LightningElement { } handlePagination() { +console.log("🚀 ~ handlePagination ~ this.isPagination:", this.isPagination); if (this.isPagination) { let firstRecord = (this._pageCurrentNumber - 1) * this._recordCountPerPage; let lastRecord = Math.min( (this._pageCurrentNumber * this._recordCountPerPage), this.recordCountTotal ); this.paginatedData = this._mydata.slice(firstRecord,lastRecord); + let sids = []; + this._allSelectedRowIds.forEach(srowid => { +console.log("🚀 ~ handlePagination ~ srowid:", srowid); + const selRow = this._paginatedData.find(d => d[this.keyField] === srowid); +console.log("🚀 ~ handlePagination ~ this._paginatedData:", this._paginatedData); +console.log("🚀 ~ handlePagination ~ selRow, srowid:", selRow, srowid); + sids.push(srowid); + }); + this.visibleSelectedRowIds = [...sids]; +console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", [...sids], this.visibleSelectedRowIds); } else { this.paginatedData = [...this._mydata]; + this.visibleSelectedRowIds = this._allSelectedRowIds; } +console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelectedRowIds); +console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibleSelectedRowIds); } // End Pagination Methods @@ -1325,7 +1364,7 @@ export default class Datatable extends LightningElement { this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only - console.log(DEBUG_INFO_PREFIX+'selectedRows',(SHOW_DEBUG_INFO) ? this.selectedRows : '***'); + console.log(DEBUG_INFO_PREFIX+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this._allSelectedRowIds : '***'); console.log(DEBUG_INFO_PREFIX+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); console.log(DEBUG_INFO_PREFIX+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); console.log(DEBUG_INFO_PREFIX+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); @@ -1666,7 +1705,9 @@ export default class Datatable extends LightningElement { selected.forEach(record => { selectedKeys.push(record[this.keyField]); }); - this.selectedRows = selectedKeys; + this.allSelectedRowIds = selectedKeys; +console.log("🚀 ~ updatePreSelectedRows ~ this.allSelectedRowIds:", this.allSelectedRowIds); + this.visibleSelectedRowIds = selectedKeys; this.preSelectedRows = []; this.dispatchEvent(new FlowAttributeChangeEvent('preSelectedRows', this.preSelectedRows)); } @@ -1728,7 +1769,14 @@ export default class Datatable extends LightningElement { console.log(DEBUG_INFO_PREFIX+"handleRowAction ~ action, keyValue:", action, (SHOW_DEBUG_INFO) ? keyValue : '***'); switch (action) { + case 'removeRow': + + // Add to removed row collection and update counter + this.outputRemovedRows = [...this.outputRemovedRows, row]; + this.numberOfRowsRemoved ++; +console.log("🚀 ~ handleRowAction ~ this.numberOfRowsRemoved, this.outputRemovedRows:", this.numberOfRowsRemoved, this.outputRemovedRows); + // remove record from collection this.mydata = this.removeRowFromCollection(this._mydata, keyValue); @@ -1741,14 +1789,18 @@ export default class Datatable extends LightningElement { if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row this.outputSelectedRows = []; - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); - this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + if (!this.isUserDefinedObject) { + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); + } else { + this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + } this.updateNumberOfRowsSelected(this.outputSelectedRows); // refresh table this.tableData = []; } break; + default: } @@ -1967,14 +2019,67 @@ export default class Datatable extends LightningElement { // Only used with row selection // Update values to be passed back to the Flow let currentSelectedRows = event.detail.selectedRows; - this.updateNumberOfRowsSelected(currentSelectedRows); +console.log("🚀 ~ handleRowSelection ~ currentSelectedRows:", currentSelectedRows); + let otherSelectedRowIds = []; + let currentSelectedRowIds = []; + let allSelectedRecs = []; + let index = -1; + currentSelectedRows.forEach(selrow => { +console.log("🚀 ~ handleRowSelection ~ selrow:", selrow); +console.log("🚀 ~ handleRowSelection ~ allSelectedRecs, allSelectedRecs.length:", allSelectedRecs, allSelectedRecs.length); + const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); +console.log("🚀 ~ handleRowSelection ~ prevsel:", prevsel); + if (!prevsel) { + this._allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; + } + }) + this._allSelectedRowIds.forEach(srowid => { +console.log("🚀 ~ handleRowSelection ~ srowid:", srowid); +console.log("🚀 ~ handleRowSelection ~ this._paginatedData:", this._paginatedData); + const found = this.findRowIndexById(this._paginatedData, srowid) != -1; +console.log("🚀 ~ handleRowSelection ~ found:", found); + if (!found) { +console.log("🚀 ~ handleRowSelection ~ this.outputRemovedRows:", this.outputRemovedRows); + if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { + otherSelectedRowIds.push(srowid); + index = this.findRowIndexById(this._paginatedData, srowid); + allSelectedRecs.push(this._paginatedData[index]); +console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-PUSH:", allSelectedRecs); + } else { // Selected row was removed + index = this.findRowIndexById(this._paginatedData, srowid); + allSelectedRecs.pop(this._paginatedData[index]); +console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-POP:", allSelectedRecs); + } + } else { + const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; +console.log("🚀 ~ handleRowSelection ~ stillSelected:", stillSelected); + if (stillSelected) { + currentSelectedRowIds.push(srowid); + index = this.findRowIndexById(currentSelectedRows, srowid); + allSelectedRecs.push(currentSelectedRows[index]); + } + } + }); + + this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; +console.log("🚀 ~ handleRowSelection ~ this.allSelectedRowIds:", this.allSelectedRowIds); +console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !allSelectedRecs,allSelectedRecs); +// this.outputSelectedRows = (!allSelectedRecs) ? this.outputSelectedRows.splice(0, this.outputSelectedRows.length) : [...allSelectedRecs]; + this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; + +console.log("🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); + +//🚀 this.updateNumberOfRowsSelected(currentSelectedRows); + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); + this.updateNumberOfRowsSelected(this.outputSelectedRows); this.setIsInvalidFlag(false); if(this.isRequired && this.numberOfRowsSelected == 0) { this.setIsInvalidFlag(true); } // this.isUpdateTable = false; // Commented out in v4.1.1 - this.outputSelectedRows = [...currentSelectedRows]; - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); +//🚀 this.outputSelectedRows = [...currentSelectedRows]; +// this.outputSelectedRows = [...this.allSelectedRowIds]; +// this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); } @@ -1995,8 +2100,9 @@ export default class Datatable extends LightningElement { handleClearSelection() { this.showClearButton = false; - this.selectedRows = []; - this.outputSelectedRows = this.selectedRows; + this.allSelectedRowIds = []; + this.visibleSelectedRowIds = []; + this.outputSelectedRows = []; this.outputSelectedRowsString = ''; this.updateNumberOfRowsSelected(this.outputSelectedRows); this.isUpdateTable = false; From e9b6a533edda61ac951e0a8f641755ece707a985 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 2 Jul 2024 10:03:03 -0400 Subject: [PATCH 12/38] Too Large to Deploy - Selected output fails w/ pagination --- .../main/default/lwc/datatable/datatable.js | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 3279d7a40..5fdf70907 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1692,6 +1692,7 @@ console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibl // Handle pre-selected records if(!this.outputSelectedRows || this.outputSelectedRows.length === 0) { this.outputSelectedRows = this.preSelectedRows.slice(0, this.maxNumberOfRows); +// console.log("🚀🚀 ~ updatePreSelectedRows ~ this.outputSelectedRows :", this.outputSelectedRows ); this.updateNumberOfRowsSelected(this.outputSelectedRows); if (this.isUserDefinedObject) { @@ -1777,18 +1778,25 @@ console.log("🚀 ~ updatePreSelectedRows ~ this.allSelectedRowIds:", this.allSe this.numberOfRowsRemoved ++; console.log("🚀 ~ handleRowAction ~ this.numberOfRowsRemoved, this.outputRemovedRows:", this.numberOfRowsRemoved, this.outputRemovedRows); - // remove record from collection - this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + // handle selected rows + const index = this._allSelectedRowIds.indexOf(keyValue); + if (index != -1) { + this._allSelectedRowIds.splice(index, 1); + } - // handle editedrows + // handle edited rows this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + // remove record from collection + this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row this.outputSelectedRows = []; +// console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.outputSelectedRows); if (!this.isUserDefinedObject) { this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); } else { @@ -2026,7 +2034,7 @@ console.log("🚀 ~ handleRowSelection ~ currentSelectedRows:", currentSelectedR let index = -1; currentSelectedRows.forEach(selrow => { console.log("🚀 ~ handleRowSelection ~ selrow:", selrow); -console.log("🚀 ~ handleRowSelection ~ allSelectedRecs, allSelectedRecs.length:", allSelectedRecs, allSelectedRecs.length); +// console.log("🚀 ~ handleRowSelection ~ allSelectedRecs, allSelectedRecs.length:", allSelectedRecs, allSelectedRecs.length); const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); console.log("🚀 ~ handleRowSelection ~ prevsel:", prevsel); if (!prevsel) { @@ -2046,8 +2054,10 @@ console.log("🚀 ~ handleRowSelection ~ this.outputRemovedRows:", this.outputRe allSelectedRecs.push(this._paginatedData[index]); console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-PUSH:", allSelectedRecs); } else { // Selected row was removed - index = this.findRowIndexById(this._paginatedData, srowid); - allSelectedRecs.pop(this._paginatedData[index]); +// index = this.findRowIndexById(this._paginatedData, srowid); +// allSelectedRecs.pop(this._paginatedData[index]); + index = this.findRowIndexById(allSelectedRecs, srowid); + allSelectedRecs.splice(index, 1); console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-POP:", allSelectedRecs); } } else { @@ -2066,8 +2076,7 @@ console.log("🚀 ~ handleRowSelection ~ this.allSelectedRowIds:", this.allSelec console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !allSelectedRecs,allSelectedRecs); // this.outputSelectedRows = (!allSelectedRecs) ? this.outputSelectedRows.splice(0, this.outputSelectedRows.length) : [...allSelectedRecs]; this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; - -console.log("🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); +// console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); //🚀 this.updateNumberOfRowsSelected(currentSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); @@ -2103,6 +2112,7 @@ console.log("🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputS this.allSelectedRowIds = []; this.visibleSelectedRowIds = []; this.outputSelectedRows = []; +// console.log("🚀🚀 ~ handleClearSelection ~ this.outputSelectedRows:", this.outputSelectedRows); this.outputSelectedRowsString = ''; this.updateNumberOfRowsSelected(this.outputSelectedRows); this.isUpdateTable = false; @@ -2855,12 +2865,16 @@ console.log("🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputS // Finalize Selected Records for Output let sdata = []; +// console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.outputSelectedRows.forEach(srow => { - const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); - sdata.push(selData); + if (srow) { + const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); + sdata.push(selData); + } }); this.isUpdateTable = false; this.outputSelectedRows = [...sdata]; // Set output attribute values +// console.log("🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); // Winter '23 Patch 12 fix From ea8e7a6fd741622d5a0f54f1454a3ba6b42a76c9 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 2 Jul 2024 10:08:34 -0400 Subject: [PATCH 13/38] Remove all extra debuggin to get size below 131072 --- .../main/default/lwc/datatable/datatable.js | 41 ++++--------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 5fdf70907..3f6fae6eb 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -354,7 +354,6 @@ export default class Datatable extends LightningElement { @api typeAttrib = []; // Remove Row Action Attributes - // 🚀🚀🚀 @api removeLabel = 'Remove Row'; @api removeIcon = 'utility:close'; @@ -654,27 +653,20 @@ export default class Datatable extends LightningElement { } handlePagination() { -console.log("🚀 ~ handlePagination ~ this.isPagination:", this.isPagination); if (this.isPagination) { let firstRecord = (this._pageCurrentNumber - 1) * this._recordCountPerPage; let lastRecord = Math.min( (this._pageCurrentNumber * this._recordCountPerPage), this.recordCountTotal ); this.paginatedData = this._mydata.slice(firstRecord,lastRecord); let sids = []; this._allSelectedRowIds.forEach(srowid => { -console.log("🚀 ~ handlePagination ~ srowid:", srowid); const selRow = this._paginatedData.find(d => d[this.keyField] === srowid); -console.log("🚀 ~ handlePagination ~ this._paginatedData:", this._paginatedData); -console.log("🚀 ~ handlePagination ~ selRow, srowid:", selRow, srowid); sids.push(srowid); }); this.visibleSelectedRowIds = [...sids]; -console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", [...sids], this.visibleSelectedRowIds); } else { this.paginatedData = [...this._mydata]; this.visibleSelectedRowIds = this._allSelectedRowIds; } -console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelectedRowIds); -console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibleSelectedRowIds); } // End Pagination Methods @@ -1655,7 +1647,7 @@ console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibl columnNumber += 1; }); - if (!this.isConfigMode) this.addRemoveRowAction(); // 🚀🚀🚀 +if (!this.isConfigMode) this.addRemoveRowAction(); this.columns = this.cols; console.log(DEBUG_INFO_PREFIX+'this.columns',this.columns); @@ -1692,7 +1684,7 @@ console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibl // Handle pre-selected records if(!this.outputSelectedRows || this.outputSelectedRows.length === 0) { this.outputSelectedRows = this.preSelectedRows.slice(0, this.maxNumberOfRows); -// console.log("🚀🚀 ~ updatePreSelectedRows ~ this.outputSelectedRows :", this.outputSelectedRows ); +console.log("🚀🚀 ~ updatePreSelectedRows ~ this.outputSelectedRows :", this.outputSelectedRows ); this.updateNumberOfRowsSelected(this.outputSelectedRows); if (this.isUserDefinedObject) { @@ -1707,7 +1699,6 @@ console.log("🚀 ~ handlePagination ~ this.visibleSelectedRowIds:", this.visibl selectedKeys.push(record[this.keyField]); }); this.allSelectedRowIds = selectedKeys; -console.log("🚀 ~ updatePreSelectedRows ~ this.allSelectedRowIds:", this.allSelectedRowIds); this.visibleSelectedRowIds = selectedKeys; this.preSelectedRows = []; this.dispatchEvent(new FlowAttributeChangeEvent('preSelectedRows', this.preSelectedRows)); @@ -1776,7 +1767,6 @@ console.log("🚀 ~ updatePreSelectedRows ~ this.allSelectedRowIds:", this.allSe // Add to removed row collection and update counter this.outputRemovedRows = [...this.outputRemovedRows, row]; this.numberOfRowsRemoved ++; -console.log("🚀 ~ handleRowAction ~ this.numberOfRowsRemoved, this.outputRemovedRows:", this.numberOfRowsRemoved, this.outputRemovedRows); // handle selected rows const index = this._allSelectedRowIds.indexOf(keyValue); @@ -1796,7 +1786,7 @@ console.log("🚀 ~ handleRowAction ~ this.numberOfRowsRemoved, this.outputRemov if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row this.outputSelectedRows = []; -// console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.outputSelectedRows); +console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.outputSelectedRows); if (!this.isUserDefinedObject) { this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); } else { @@ -2027,42 +2017,31 @@ console.log("🚀 ~ handleRowAction ~ this.numberOfRowsRemoved, this.outputRemov // Only used with row selection // Update values to be passed back to the Flow let currentSelectedRows = event.detail.selectedRows; -console.log("🚀 ~ handleRowSelection ~ currentSelectedRows:", currentSelectedRows); let otherSelectedRowIds = []; let currentSelectedRowIds = []; let allSelectedRecs = []; let index = -1; currentSelectedRows.forEach(selrow => { -console.log("🚀 ~ handleRowSelection ~ selrow:", selrow); -// console.log("🚀 ~ handleRowSelection ~ allSelectedRecs, allSelectedRecs.length:", allSelectedRecs, allSelectedRecs.length); const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); -console.log("🚀 ~ handleRowSelection ~ prevsel:", prevsel); if (!prevsel) { this._allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; } }) this._allSelectedRowIds.forEach(srowid => { -console.log("🚀 ~ handleRowSelection ~ srowid:", srowid); -console.log("🚀 ~ handleRowSelection ~ this._paginatedData:", this._paginatedData); const found = this.findRowIndexById(this._paginatedData, srowid) != -1; -console.log("🚀 ~ handleRowSelection ~ found:", found); if (!found) { -console.log("🚀 ~ handleRowSelection ~ this.outputRemovedRows:", this.outputRemovedRows); if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { otherSelectedRowIds.push(srowid); index = this.findRowIndexById(this._paginatedData, srowid); allSelectedRecs.push(this._paginatedData[index]); -console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-PUSH:", allSelectedRecs); } else { // Selected row was removed // index = this.findRowIndexById(this._paginatedData, srowid); // allSelectedRecs.pop(this._paginatedData[index]); index = this.findRowIndexById(allSelectedRecs, srowid); allSelectedRecs.splice(index, 1); -console.log("🚀 ~ handleRowSelection ~ allSelectedRecs-POP:", allSelectedRecs); } } else { const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; -console.log("🚀 ~ handleRowSelection ~ stillSelected:", stillSelected); if (stillSelected) { currentSelectedRowIds.push(srowid); index = this.findRowIndexById(currentSelectedRows, srowid); @@ -2072,13 +2051,10 @@ console.log("🚀 ~ handleRowSelection ~ stillSelected:", stillSelected); }); this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; -console.log("🚀 ~ handleRowSelection ~ this.allSelectedRowIds:", this.allSelectedRowIds); -console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !allSelectedRecs,allSelectedRecs); // this.outputSelectedRows = (!allSelectedRecs) ? this.outputSelectedRows.splice(0, this.outputSelectedRows.length) : [...allSelectedRecs]; this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; -// console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); +console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); -//🚀 this.updateNumberOfRowsSelected(currentSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); this.setIsInvalidFlag(false); @@ -2086,9 +2062,6 @@ console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !a this.setIsInvalidFlag(true); } // this.isUpdateTable = false; // Commented out in v4.1.1 -//🚀 this.outputSelectedRows = [...currentSelectedRows]; -// this.outputSelectedRows = [...this.allSelectedRowIds]; -// this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); } @@ -2112,7 +2085,7 @@ console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !a this.allSelectedRowIds = []; this.visibleSelectedRowIds = []; this.outputSelectedRows = []; -// console.log("🚀🚀 ~ handleClearSelection ~ this.outputSelectedRows:", this.outputSelectedRows); +console.log("🚀🚀 ~ handleClearSelection ~ this.outputSelectedRows:", this.outputSelectedRows); this.outputSelectedRowsString = ''; this.updateNumberOfRowsSelected(this.outputSelectedRows); this.isUpdateTable = false; @@ -2865,7 +2838,7 @@ console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !a // Finalize Selected Records for Output let sdata = []; -// console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); +console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.outputSelectedRows.forEach(srow => { if (srow) { const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); @@ -2874,7 +2847,7 @@ console.log("🚀 ~ handleRowSelection ~ !allSelectedRecs, allSelectedRecs:", !a }); this.isUpdateTable = false; this.outputSelectedRows = [...sdata]; // Set output attribute values -// console.log("🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); +console.log("🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); // Winter '23 Patch 12 fix From e75461d1c9e030b300d16efc1faef1cfe8eb72c4 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 2 Jul 2024 11:44:15 -0400 Subject: [PATCH 14/38] Working Select/Remove/Paginate --- .../force-app/main/default/lwc/datatable/datatable.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 3f6fae6eb..244ad4da4 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -2032,8 +2032,8 @@ console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.output if (!found) { if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { otherSelectedRowIds.push(srowid); - index = this.findRowIndexById(this._paginatedData, srowid); - allSelectedRecs.push(this._paginatedData[index]); + index = this.findRowIndexById(this._mydata, srowid); + allSelectedRecs.push(this._mydata[index]); } else { // Selected row was removed // index = this.findRowIndexById(this._paginatedData, srowid); // allSelectedRecs.pop(this._paginatedData[index]); @@ -2850,7 +2850,7 @@ console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSel console.log("🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); // Winter '23 Patch 12 fix - + /* // Validate Edited Rows let errorMessage = ''; this.outputEditedRows.forEach(erow => { From 57348b3b6dbd97720f1fa012e944c7bf9c4430eb Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 2 Jul 2024 11:54:31 -0400 Subject: [PATCH 15/38] Removed debug console logs --- .../main/default/lwc/datatable/datatable.js | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 244ad4da4..e1470bc50 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1684,7 +1684,6 @@ if (!this.isConfigMode) this.addRemoveRowAction(); // Handle pre-selected records if(!this.outputSelectedRows || this.outputSelectedRows.length === 0) { this.outputSelectedRows = this.preSelectedRows.slice(0, this.maxNumberOfRows); -console.log("🚀🚀 ~ updatePreSelectedRows ~ this.outputSelectedRows :", this.outputSelectedRows ); this.updateNumberOfRowsSelected(this.outputSelectedRows); if (this.isUserDefinedObject) { @@ -1786,7 +1785,6 @@ console.log("🚀🚀 ~ updatePreSelectedRows ~ this.outputSelectedRows :", this if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row this.outputSelectedRows = []; -console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.outputSelectedRows); if (!this.isUserDefinedObject) { this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); } else { @@ -2035,8 +2033,6 @@ console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.output index = this.findRowIndexById(this._mydata, srowid); allSelectedRecs.push(this._mydata[index]); } else { // Selected row was removed -// index = this.findRowIndexById(this._paginatedData, srowid); -// allSelectedRecs.pop(this._paginatedData[index]); index = this.findRowIndexById(allSelectedRecs, srowid); allSelectedRecs.splice(index, 1); } @@ -2051,9 +2047,7 @@ console.log("🚀🚀 ~ handleRowAction ~ this.outputSelectedRows:", this.output }); this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; -// this.outputSelectedRows = (!allSelectedRecs) ? this.outputSelectedRows.splice(0, this.outputSelectedRows.length) : [...allSelectedRecs]; this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; -console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); @@ -2062,8 +2056,10 @@ console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.out this.setIsInvalidFlag(true); } // this.isUpdateTable = false; // Commented out in v4.1.1 - this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + if (this.isUserDefinedObject) { + this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + } } updateNumberOfRowsSelected(currentSelectedRows) { @@ -2085,12 +2081,13 @@ console.log("🚀🚀 ~ handleRowSelection ~ this.outputSelectedRows:", this.out this.allSelectedRowIds = []; this.visibleSelectedRowIds = []; this.outputSelectedRows = []; -console.log("🚀🚀 ~ handleClearSelection ~ this.outputSelectedRows:", this.outputSelectedRows); - this.outputSelectedRowsString = ''; this.updateNumberOfRowsSelected(this.outputSelectedRows); this.isUpdateTable = false; this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + if (this.isUserDefinedObject) { + this.outputSelectedRowsString = ''; + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + } } handleClearFilterButton() { @@ -2838,7 +2835,6 @@ console.log("🚀🚀 ~ handleClearSelection ~ this.outputSelectedRows:", this.o // Finalize Selected Records for Output let sdata = []; -console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.outputSelectedRows.forEach(srow => { if (srow) { const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); @@ -2847,7 +2843,6 @@ console.log("🚀🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSel }); this.isUpdateTable = false; this.outputSelectedRows = [...sdata]; // Set output attribute values -console.log("🚀🚀 ~ validate ~ this.outputSelectedRows:", this.outputSelectedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); // Winter '23 Patch 12 fix From 217ad41ac561ef8d950e018a7286a70e9f56b318 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Wed, 3 Jul 2024 15:13:39 -0400 Subject: [PATCH 16/38] Undo Fix removed row reappearing if clicked too soon --- .../main/default/lwc/datatable/datatable.js | 79 +++++++++++-------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index e1470bc50..2c3f20f21 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -510,6 +510,7 @@ export default class Datatable extends LightningElement { @track columnFlexParameter; @track columnEditParameter; @track columnFilterParameter; + isProcessed = false; get collectionSize() { let max = Math.min(CONSTANTS.MAXROWCOUNT, this.maxNumberOfRows); @@ -656,9 +657,9 @@ export default class Datatable extends LightningElement { if (this.isPagination) { let firstRecord = (this._pageCurrentNumber - 1) * this._recordCountPerPage; let lastRecord = Math.min( (this._pageCurrentNumber * this._recordCountPerPage), this.recordCountTotal ); - this.paginatedData = this._mydata.slice(firstRecord,lastRecord); + this.paginatedData = this.mydata.slice(firstRecord,lastRecord); let sids = []; - this._allSelectedRowIds.forEach(srowid => { + this.allSelectedRowIds.forEach(srowid => { const selRow = this._paginatedData.find(d => d[this.keyField] === srowid); sids.push(srowid); }); @@ -720,13 +721,14 @@ export default class Datatable extends LightningElement { // All picklist values will be used instead of just those specified by the supplied Record Type Id console.log(DEBUG_INFO_PREFIX+'getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); } - if (data != undefined || error != undefined) { + if (!this.isProcessed && (data != undefined || error != undefined)) { // Update row data for lookup, time, picklist and percent fields this.updateDataRows(); // Custom column processing this.updateColumns(); // Extract Keys for Pre-Selected Rows this.updatePreSelectedRows(); + this.isProcessed = true; // Added in v4.2.1 so @wire won't run processing twice (remove row could occur before 2nd run through finished) } } @@ -772,6 +774,8 @@ export default class Datatable extends LightningElement { console.log("%cDATATABLE VERSION_NUMBER: %c"+CONSTANTS.VERSION_NUMBER, logStyleText, logStyleNumber); console.log(DEBUG_INFO_PREFIX+'MYDOMAIN', MYDOMAIN); + this.isProcessed = false; + // Picklist field processing if (!this.recordTypeId) this.recordTypeId = this.masterRecordTypeId; @@ -1356,7 +1360,7 @@ export default class Datatable extends LightningElement { this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only - console.log(DEBUG_INFO_PREFIX+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this._allSelectedRowIds : '***'); + console.log(DEBUG_INFO_PREFIX+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); console.log(DEBUG_INFO_PREFIX+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); console.log(DEBUG_INFO_PREFIX+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); console.log(DEBUG_INFO_PREFIX+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); @@ -2019,35 +2023,46 @@ if (!this.isConfigMode) this.addRemoveRowAction(); let currentSelectedRowIds = []; let allSelectedRecs = []; let index = -1; - currentSelectedRows.forEach(selrow => { - const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); - if (!prevsel) { - this._allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; - } - }) - this._allSelectedRowIds.forEach(srowid => { - const found = this.findRowIndexById(this._paginatedData, srowid) != -1; - if (!found) { - if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { - otherSelectedRowIds.push(srowid); - index = this.findRowIndexById(this._mydata, srowid); - allSelectedRecs.push(this._mydata[index]); - } else { // Selected row was removed - index = this.findRowIndexById(allSelectedRecs, srowid); - allSelectedRecs.splice(index, 1); + this.isWorking = true; + new Promise((resolve, reject) => { + setTimeout(() => { + + currentSelectedRows.forEach(selrow => { + const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); + if (!prevsel) { + this.allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; } - } else { - const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; - if (stillSelected) { - currentSelectedRowIds.push(srowid); - index = this.findRowIndexById(currentSelectedRows, srowid); - allSelectedRecs.push(currentSelectedRows[index]); - } - } - }); - - this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; - this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; + }) + this._allSelectedRowIds.forEach(srowid => { + const found = this.findRowIndexById(this._paginatedData, srowid) != -1; + if (!found) { + if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { + otherSelectedRowIds.push(srowid); + index = this.findRowIndexById(this._mydata, srowid); + allSelectedRecs.push(this._mydata[index]); + } else { // Selected row was removed + index = this.findRowIndexById(allSelectedRecs, srowid); + allSelectedRecs.splice(index, 1); + } + } else { + const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; + if (stillSelected) { + currentSelectedRowIds.push(srowid); + index = this.findRowIndexById(currentSelectedRows, srowid); + allSelectedRecs.push(currentSelectedRows[index]); + } + } + }); + + this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; + this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; + + resolve(); + }, 0); + }) + .then( + () => this.isWorking = false + ); this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); From ca40fbba9a2aa29a2f44b83b4935f992ca3890a7 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Wed, 3 Jul 2024 15:14:20 -0400 Subject: [PATCH 17/38] try again --- .../force-app/main/default/lwc/datatable/datatable.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 2c3f20f21..833982e52 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -510,7 +510,6 @@ export default class Datatable extends LightningElement { @track columnFlexParameter; @track columnEditParameter; @track columnFilterParameter; - isProcessed = false; get collectionSize() { let max = Math.min(CONSTANTS.MAXROWCOUNT, this.maxNumberOfRows); @@ -721,14 +720,13 @@ export default class Datatable extends LightningElement { // All picklist values will be used instead of just those specified by the supplied Record Type Id console.log(DEBUG_INFO_PREFIX+'getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); } - if (!this.isProcessed && (data != undefined || error != undefined)) { + if (data != undefined || error != undefined) { // Update row data for lookup, time, picklist and percent fields this.updateDataRows(); // Custom column processing this.updateColumns(); // Extract Keys for Pre-Selected Rows this.updatePreSelectedRows(); - this.isProcessed = true; // Added in v4.2.1 so @wire won't run processing twice (remove row could occur before 2nd run through finished) } } @@ -774,8 +772,6 @@ export default class Datatable extends LightningElement { console.log("%cDATATABLE VERSION_NUMBER: %c"+CONSTANTS.VERSION_NUMBER, logStyleText, logStyleNumber); console.log(DEBUG_INFO_PREFIX+'MYDOMAIN', MYDOMAIN); - this.isProcessed = false; - // Picklist field processing if (!this.recordTypeId) this.recordTypeId = this.masterRecordTypeId; From ceeed78abc2f1f7a04188b83e4206f8f9cff9de1 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 4 Jul 2024 14:29:20 -0400 Subject: [PATCH 18/38] Remove processCount delay for Remove Row Action --- .../main/default/lwc/datatable/datatable.js | 73 +++++++++---------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 833982e52..541762a84 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -130,6 +130,7 @@ export default class Datatable extends LightningElement { if (Array.isArray(data)) { this._tableData = data; if(this.columnFields) { +console.log("🚀 ~ settableData ~ this.processDatatable:", data); this.processDatatable(); } } else { @@ -333,6 +334,7 @@ export default class Datatable extends LightningElement { this._tableDataString = value; if (this.columnFields) { this.assignApexDefinedRecords(); +console.log("🚀 ~ settableDataString ~ this.processDatatable:", value); this.processDatatable(); } } else { @@ -658,6 +660,7 @@ export default class Datatable extends LightningElement { let lastRecord = Math.min( (this._pageCurrentNumber * this._recordCountPerPage), this.recordCountTotal ); this.paginatedData = this.mydata.slice(firstRecord,lastRecord); let sids = []; +console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelectedRowIds); this.allSelectedRowIds.forEach(srowid => { const selRow = this._paginatedData.find(d => d[this.keyField] === srowid); sids.push(srowid); @@ -1647,7 +1650,7 @@ export default class Datatable extends LightningElement { columnNumber += 1; }); -if (!this.isConfigMode) this.addRemoveRowAction(); +if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.columns = this.cols; console.log(DEBUG_INFO_PREFIX+'this.columns',this.columns); @@ -1780,7 +1783,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); // remove record from collection - this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + this.mydata = this.removeRowFromCollection(this._mydata, keyValue); if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row @@ -2019,46 +2022,36 @@ if (!this.isConfigMode) this.addRemoveRowAction(); let currentSelectedRowIds = []; let allSelectedRecs = []; let index = -1; - this.isWorking = true; - new Promise((resolve, reject) => { - setTimeout(() => { - - currentSelectedRows.forEach(selrow => { - const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); - if (!prevsel) { - this.allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; - } - }) - this._allSelectedRowIds.forEach(srowid => { - const found = this.findRowIndexById(this._paginatedData, srowid) != -1; - if (!found) { - if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { - otherSelectedRowIds.push(srowid); - index = this.findRowIndexById(this._mydata, srowid); - allSelectedRecs.push(this._mydata[index]); - } else { // Selected row was removed - index = this.findRowIndexById(allSelectedRecs, srowid); - allSelectedRecs.splice(index, 1); - } - } else { - const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; - if (stillSelected) { - currentSelectedRowIds.push(srowid); - index = this.findRowIndexById(currentSelectedRows, srowid); - allSelectedRecs.push(currentSelectedRows[index]); - } - } - }); - - this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; - this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; - resolve(); - }, 0); + currentSelectedRows.forEach(selrow => { + const prevsel = this._allSelectedRowIds.some(id => id === selrow[this.keyField]); + if (!prevsel) { + this.allSelectedRowIds = [...this._allSelectedRowIds, selrow[this.keyField]]; + } }) - .then( - () => this.isWorking = false - ); + this._allSelectedRowIds.forEach(srowid => { + const found = this.findRowIndexById(this._paginatedData, srowid) != -1; + if (!found) { + if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { + otherSelectedRowIds.push(srowid); + index = this.findRowIndexById(this._mydata, srowid); + allSelectedRecs.push(this._mydata[index]); + } else { // Selected row was removed + index = this.findRowIndexById(allSelectedRecs, srowid); + allSelectedRecs.splice(index, 1); + } + } else { + const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; + if (stillSelected) { + currentSelectedRowIds.push(srowid); + index = this.findRowIndexById(currentSelectedRows, srowid); + allSelectedRecs.push(currentSelectedRows[index]); + } + } + }); + + this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; + this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); From 15a15649ff811f2950fa213f3eca896b148da220 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 4 Jul 2024 14:43:02 -0400 Subject: [PATCH 19/38] Console Log prefix differentiation --- .../main/default/lwc/datatable/datatable.js | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 541762a84..f17e9f0d8 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -105,6 +105,11 @@ export default class Datatable extends LightningElement { @api outputRemovedRows = []; @api numberOfRowsRemoved = 0; + // Console Log differentiation + get consoleLogPrefix() { + return `${DEBUG_INFO_PREFIX}(${this._tableLabel}) `; + } + // v4.2.0 Make Table Header Label reactive // @api tableLabel; @api @@ -130,7 +135,6 @@ export default class Datatable extends LightningElement { if (Array.isArray(data)) { this._tableData = data; if(this.columnFields) { -console.log("🚀 ~ settableData ~ this.processDatatable:", data); this.processDatatable(); } } else { @@ -334,7 +338,6 @@ console.log("🚀 ~ settableData ~ this.processDatatable:", data); this._tableDataString = value; if (this.columnFields) { this.assignApexDefinedRecords(); -console.log("🚀 ~ settableDataString ~ this.processDatatable:", value); this.processDatatable(); } } else { @@ -660,7 +663,6 @@ console.log("🚀 ~ settableDataString ~ this.processDatatable:", value); let lastRecord = Math.min( (this._pageCurrentNumber * this._recordCountPerPage), this.recordCountTotal ); this.paginatedData = this.mydata.slice(firstRecord,lastRecord); let sids = []; -console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelectedRowIds); this.allSelectedRowIds.forEach(srowid => { const selRow = this._paginatedData.find(d => d[this.keyField] === srowid); sids.push(srowid); @@ -721,7 +723,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte } else if (error) { // An error is expected here if the running user does not have Read access to the datatable SObject // All picklist values will be used instead of just those specified by the supplied Record Type Id - console.log(DEBUG_INFO_PREFIX+'getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); + console.log(this.consoleLogPrefix+'getPicklistValuesByRecordType wire service returned error: ' + JSON.stringify(error)); } if (data != undefined || error != undefined) { // Update row data for lookup, time, picklist and percent fields @@ -773,7 +775,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte const logStyleText = 'color: green; font-size: 16px'; const logStyleNumber = 'color: red; font-size: 16px'; console.log("%cDATATABLE VERSION_NUMBER: %c"+CONSTANTS.VERSION_NUMBER, logStyleText, logStyleNumber); - console.log(DEBUG_INFO_PREFIX+'MYDOMAIN', MYDOMAIN); + console.log(this.consoleLogPrefix+'MYDOMAIN', MYDOMAIN); // Picklist field processing if (!this.recordTypeId) this.recordTypeId = this.masterRecordTypeId; @@ -792,22 +794,22 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnAlignments:", this.columnAlignments); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnEdits:", this.columnEdits); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFilters:", this.columnFilters); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnIcons:", this.columnIcons); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnLabels:", this.columnLabels); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnWidths:", this.columnWidths); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnWraps:", this.columnWraps); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFlexes:", this.columnFlexes); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnFields:", this.columnFields); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); - console.log(DEBUG_INFO_PREFIX+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnAlignments:", this.columnAlignments); + console.log(this.consoleLogPrefix+"Config Mode Input columnEdits:", this.columnEdits); + console.log(this.consoleLogPrefix+"Config Mode Input columnFilters:", this.columnFilters); + console.log(this.consoleLogPrefix+"Config Mode Input columnIcons:", this.columnIcons); + console.log(this.consoleLogPrefix+"Config Mode Input columnLabels:", this.columnLabels); + console.log(this.consoleLogPrefix+"Config Mode Input columnWidths:", this.columnWidths); + console.log(this.consoleLogPrefix+"Config Mode Input columnWraps:", this.columnWraps); + console.log(this.consoleLogPrefix+"Config Mode Input columnFlexes:", this.columnFlexes); + console.log(this.consoleLogPrefix+"Config Mode Input columnFields:", this.columnFields); + console.log(this.consoleLogPrefix+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); // this.not_suppressNameFieldLink = false; } - console.log(DEBUG_INFO_PREFIX+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***', this.isUserDefinedObject); + console.log(this.consoleLogPrefix+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***', this.isUserDefinedObject); if (this.isUserDefinedObject) { this.assignApexDefinedRecords(); @@ -821,7 +823,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte // Pagination Initiation this.initiatePagination(); - console.log(DEBUG_INFO_PREFIX+'this._tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); + console.log(this.consoleLogPrefix+'this._tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); if (!this._tableData) { this.isUpdateTable = false; @@ -839,7 +841,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte // Get array of column field API names this.columnArray = (this.columnFields.length > 0) ? this.columnFields.replace(/\s/g, '').split(',') : []; this.columnFieldParameter = this.columnArray.join(', '); - console.log(DEBUG_INFO_PREFIX+'columnArray - ',this.columnArray); + console.log(this.consoleLogPrefix+'columnArray - ',this.columnArray); // JSON Version - Build basicColumns default values if (this.isUserDefinedObject) { @@ -1021,7 +1023,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte if (!this.allowOverflow) { this.tableHeightAttribute = 'height:' + this.tableHeight; } - console.log(DEBUG_INFO_PREFIX+'tableHeightAttribute',this.tableHeightAttribute); + console.log(this.consoleLogPrefix+'tableHeightAttribute',this.tableHeightAttribute); // Set table border display //this.borderClass = (this.tableBorder == true) ? 'slds-box' : ''; commented out to remove padding. replaced with below @@ -1036,7 +1038,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte // Set other initial values here this.wizColumnFields = this.columnFields; - console.log(DEBUG_INFO_PREFIX+'Processing Datatable'); + console.log(this.consoleLogPrefix+'Processing Datatable'); this.processDatatable(); this.isUpdateTable = true; // Added in v4.1.1 so Datatable will show records from Datafetcher upon initialization @@ -1048,7 +1050,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte assignApexDefinedRecords() { // JSON input attributes - console.log(DEBUG_INFO_PREFIX+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***'); + console.log(this.consoleLogPrefix+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***'); if (!this._tableDataString || this._tableDataString?.length == 0) { this._tableDataString = '[{"'+this.keyField+'":"(empty table)"}]'; this.columnFields = this.keyField; @@ -1056,7 +1058,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte this.columnScales = []; } this._tableData = JSON.parse(this._tableDataString); - console.log(DEBUG_INFO_PREFIX+'tableData - ',(SHOW_DEBUG_INFO) ? this._tableData : '***'); + console.log(this.consoleLogPrefix+'tableData - ',(SHOW_DEBUG_INFO) ? this._tableData : '***'); this.preSelectedRows = (this.preSelectedRowsString.length > 0) ? JSON.parse(this.preSelectedRowsString) : []; } @@ -1168,7 +1170,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte } let fieldList = (this.columnFields.length > 0) ? this.columnFields.replace(/\s/g, '') : ''; // Remove spaces - console.log(DEBUG_INFO_PREFIX+'Passing data to Apex Controller', (SHOW_DEBUG_INFO) ? data : '***'); + console.log(this.consoleLogPrefix+'Passing data to Apex Controller', (SHOW_DEBUG_INFO) ? data : '***'); getReturnResults({ records: data, fieldNames: fieldList, suppressCurrencyConversion: this.suppressCurrencyConversion }) .then(result => { let returnResults = JSON.parse(result); @@ -1180,17 +1182,17 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte this.numberFieldArray = (returnResults.numberFieldList.length > 0) ? returnResults.numberFieldList.toString().split(',') : []; this.timeFieldArray = (returnResults.timeFieldList.length > 0) ? returnResults.timeFieldList.toString().split(',') : []; this.datetimeFieldArray = (returnResults.datetimeFieldList.length > 0) ? returnResults.datetimeFieldList.toString().split(',') : []; - console.log(DEBUG_INFO_PREFIX+"Datetime Fields ~ returnResults.datetimeFieldList.toString()", returnResults.datetimeFieldList.toString()); + console.log(this.consoleLogPrefix+"Datetime Fields ~ returnResults.datetimeFieldList.toString()", returnResults.datetimeFieldList.toString()); this.picklistFieldArray = (returnResults.picklistFieldList.length > 0) ? returnResults.picklistFieldList.toString().split(',') : []; this.picklistReplaceValues = (this.picklistFieldArray.length > 0); // Flag value dependent on if there are any picklists in the datatable field list this.apex_picklistFieldMap = returnResults.picklistFieldMap; - console.log(DEBUG_INFO_PREFIX+"Picklist Fields ~ this.apex_picklistFieldMap", this.apex_picklistFieldMap); + console.log(this.consoleLogPrefix+"Picklist Fields ~ this.apex_picklistFieldMap", this.apex_picklistFieldMap); this.dateFieldArray = (returnResults.dateFieldList.length > 0) ? returnResults.dateFieldList.toString().split(',') : []; this.objectNameLookup = returnResults.objectName; this.objectLinkField = returnResults.objectLinkField; this.lookupFieldArray = JSON.parse('[' + returnResults.lookupFieldData + ']'); this.timezoneOffset = returnResults.timezoneOffset.replace(/[^\d-]/g, ''); // Numeric characters and - only - console.log(DEBUG_INFO_PREFIX+"Timezone Offset ~ this.timezoneOffset", this.timezoneOffset); + console.log(this.consoleLogPrefix+"Timezone Offset ~ this.timezoneOffset", this.timezoneOffset); // Check for differences in picklist API Values vs Labels if (this.picklistReplaceValues) { @@ -1208,7 +1210,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte // Basic column info (label, fieldName, type) taken from the Schema in Apex this.dtableColumnFieldDescriptorString = '[' + returnResults.dtableColumnFieldDescriptorString + ']'; this.basicColumns = JSON.parse(this.dtableColumnFieldDescriptorString); - console.log(DEBUG_INFO_PREFIX+'dtableColumnFieldDescriptorString',this.dtableColumnFieldDescriptorString, this.basicColumns); + console.log(this.consoleLogPrefix+'dtableColumnFieldDescriptorString',this.dtableColumnFieldDescriptorString, this.basicColumns); this.noEditFieldArray = (returnResults.noEditFieldList.length > 0) ? returnResults.noEditFieldList.toString().split(',') : []; // *** Moved to @wire *** @@ -1225,7 +1227,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte }) // Handle any errors from the Apex Class .catch(error => { - console.log(DEBUG_INFO_PREFIX+'getReturnResults error is: ' + JSON.stringify(error)); + console.log(this.consoleLogPrefix+'getReturnResults error is: ' + JSON.stringify(error)); if (error.body) { this.errorApex = 'Apex Action error: ' + error.body.message; alert(this.errorApex + '\n'); // Present the error to the user @@ -1239,7 +1241,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte updateDataRows() { // Process Incoming Data Collection - console.log(DEBUG_INFO_PREFIX+'Processing updateDataRows') + console.log(this.consoleLogPrefix+'Processing updateDataRows') let data = (this.recordData) ? JSON.parse(JSON.stringify([...this.recordData].slice(0,this.collectionSize))) : []; let lookupFields = this.lookups; let lufield = ''; @@ -1359,15 +1361,15 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only - console.log(DEBUG_INFO_PREFIX+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); - console.log(DEBUG_INFO_PREFIX+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); - console.log(DEBUG_INFO_PREFIX+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); - console.log(DEBUG_INFO_PREFIX+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); + console.log(this.consoleLogPrefix+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); + console.log(this.consoleLogPrefix+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); + console.log(this.consoleLogPrefix+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); + console.log(this.consoleLogPrefix+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); } updateColumns() { // Parse column definitions - console.log(DEBUG_INFO_PREFIX+'Processing updateColumns') + console.log(this.consoleLogPrefix+'Processing updateColumns') this.cols = []; let columnNumber = 0; let lufield = ''; @@ -1653,7 +1655,7 @@ console.log("🚀 ~ handlePagination ~ this.allSelectedRowIds:", this.allSelecte if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.columns = this.cols; - console.log(DEBUG_INFO_PREFIX+'this.columns',this.columns); + console.log(this.consoleLogPrefix+'this.columns',this.columns); } @@ -1760,7 +1762,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 const action = event.detail.action.name; const row = JSON.parse(JSON.stringify(event.detail.row)); const keyValue = row[this.keyField]; - console.log(DEBUG_INFO_PREFIX+"handleRowAction ~ action, keyValue:", action, (SHOW_DEBUG_INFO) ? keyValue : '***'); + console.log(this.consoleLogPrefix+"handleRowAction ~ action, keyValue:", action, (SHOW_DEBUG_INFO) ? keyValue : '***'); switch (action) { @@ -1962,7 +1964,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } } catch(err) { - console.log(DEBUG_INFO_PREFIX+"Date not in ISO format", date, field[date]); + console.log(this.consoleLogPrefix+"Date not in ISO format", date, field[date]); } } }); @@ -2129,7 +2131,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 updateColumnSorting(event) { // Handle column sorting - console.log(DEBUG_INFO_PREFIX+'Sort:',event.detail.fieldName,event.detail.sortDirection); + console.log(this.consoleLogPrefix+'Sort:',event.detail.fieldName,event.detail.sortDirection); this.sortedBy = event.detail.fieldName; this.sortDirection = event.detail.sortDirection; this.isUpdateTable = false; @@ -2835,7 +2837,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 @api validate() { - console.log(DEBUG_INFO_PREFIX+"validate and exit"); + console.log(this.consoleLogPrefix+"validate and exit"); // Finalize Selected Records for Output let sdata = []; @@ -2886,8 +2888,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); } - console.log(DEBUG_INFO_PREFIX+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); - console.log(DEBUG_INFO_PREFIX+'outputEditedRows', this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); + console.log(this.consoleLogPrefix+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); + console.log(this.consoleLogPrefix+'outputEditedRows', this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); // Validation logic to pass back to the Flow if(!this.isRequired || this.numberOfRowsSelected > 0) { From b1828d8fd83d226be3e51432eb5489903bb8a99e Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 4 Jul 2024 17:45:57 -0400 Subject: [PATCH 20/38] Add some missing setters --- .../main/default/lwc/datatable/datatable.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index f17e9f0d8..8063ab09b 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -178,6 +178,10 @@ export default class Datatable extends LightningElement { get showPagination() { return (this.cb_showPagination == CB_TRUE) ? true : false; } + set showPagination(value) { + this._showPagination = value; + } + _showPagination; @api cb_showPagination; @api recordsPerPage = RECORDS_PER_PAGE; @@ -186,12 +190,20 @@ export default class Datatable extends LightningElement { get showFirstLastButtons() { return (this.cb_showFirstLastButtons == CB_TRUE) ? true : false; } + set showFirstLastButtons(value) { + this._showFirstLastButtons = value; + } + _showFirstLastButtons; @api cb_showFirstLastButtons = CB_TRUE; @api get showRecordCount() { return (this.cb_showRecordCount == CB_TRUE) ? true : false; } + set showRecordCount(value) { + this._showRecordCount = value; + } + _showRecordCount; @api cb_showRecordCount; @api @@ -228,12 +240,20 @@ export default class Datatable extends LightningElement { get isDisplayHeader() { return (this.cb_isDisplayHeader == CB_TRUE) ? true : false; } + set isDisplayHeader(value) { + this._isDisplayHeader = value; + } + _isDisplayHeader; @api cb_isDisplayHeader; @api get isShowSearchBar() { return(this.cb_isShowSearchBar == CB_TRUE) ? true : false; } + set isShowSearchBar(value) { + this._isShowSearchBar = value; + } + _isShowSearchBar; @api cb_isShowSearchBar; searchTerm = ''; From 715c3faf095d26ac61ee8308a295f800888f5bed Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Fri, 5 Jul 2024 10:06:59 -0400 Subject: [PATCH 21/38] Working selected record retention --- .../main/default/lwc/datatable/datatable.js | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 8063ab09b..41bb1a804 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -2036,7 +2036,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } handleRowSelection(event) { - // TODO - Pagination - Persist previously selected rows that are not displayed on the currently visible page + // Added in v4.2.1 - Pagination - Persist previously selected rows that are not displayed on the currently visible page // Only used with row selection // Update values to be passed back to the Flow let currentSelectedRows = event.detail.selectedRows; @@ -2056,8 +2056,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 if (!found) { if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { otherSelectedRowIds.push(srowid); - index = this.findRowIndexById(this._mydata, srowid); - allSelectedRecs.push(this._mydata[index]); + index = this.findRowIndexById(this.savePreEditData, srowid); + allSelectedRecs.push(this.savePreEditData[index]); } else { // Selected row was removed index = this.findRowIndexById(allSelectedRecs, srowid); allSelectedRecs.splice(index, 1); @@ -2070,10 +2070,18 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 allSelectedRecs.push(currentSelectedRows[index]); } } - }); - + }); + this.allSelectedRowIds = [...currentSelectedRowIds, ...otherSelectedRowIds]; - this.outputSelectedRows = (!allSelectedRecs) ? [] : [...allSelectedRecs]; + this.outputSelectedRows = []; + if (allSelectedRecs) { // Keep selected rows in the same order as the original table + this.savePreEditData.forEach(rec => { // Check all records - mydata would just be the filtered records here + const isSelected = allSelectedRecs.some(srec => srec[this.keyField] === rec[this.keyField]); + if (isSelected) { + this.outputSelectedRows = [...this.outputSelectedRows, rec]; + } + }); + } this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); this.updateNumberOfRowsSelected(this.outputSelectedRows); From f85da92837031c504ab1608f7a6762626b03d77e Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jul 2024 12:35:29 -0400 Subject: [PATCH 22/38] Fix for Max Rows < Total Rows --- .../force-app/main/default/lwc/datatable/datatable.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 41bb1a804..2a6820cee 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1709,7 +1709,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 // Handle pre-selected records if(!this.outputSelectedRows || this.outputSelectedRows.length === 0) { this.outputSelectedRows = this.preSelectedRows.slice(0, this.maxNumberOfRows); - + this.updateNumberOfRowsSelected(this.outputSelectedRows); if (this.isUserDefinedObject) { this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); //JSON Version @@ -1717,7 +1717,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } else { this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); } - const selected = JSON.parse(JSON.stringify([...this.preSelectedRows])); + const selected = JSON.parse(JSON.stringify([...this.preSelectedRows.slice(0, this.maxNumberOfRows)])); let selectedKeys = []; selected.forEach(record => { selectedKeys.push(record[this.keyField]); @@ -2870,10 +2870,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 // Finalize Selected Records for Output let sdata = []; this.outputSelectedRows.forEach(srow => { - if (srow) { - const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); - sdata.push(selData); - } + const selData = this._tableData.find(d => d[this.keyField] == srow[this.keyField]); + sdata.push(selData); }); this.isUpdateTable = false; this.outputSelectedRows = [...sdata]; // Set output attribute values From f13046adbc6d7cd48730f28fb7e36235c39a469f Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jul 2024 12:37:50 -0400 Subject: [PATCH 23/38] Readme update --- flow_screen_components/datatable/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index 4352b015c..4546e6333 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -78,6 +78,7 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th - New outputs include a collection and a count of the removed rows. - Implemented a default setting (SHOW_DEBUG_INFO = false) to hide record details from console and debug logs - Source code changes in ers_datatableUtils.js, ers_DatatableController.cls & ers_QueryNRecords.cls +- Console.log statements are now identified with the Datatable's header label **Bug Fixes:** - Fixed bug where hyperlinks would open the flow rather than the referenced record From f0761e023352a2c6dfac866c108e96f64392c404 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jul 2024 12:55:37 -0400 Subject: [PATCH 24/38] Fix remove edited row before save --- .../force-app/main/default/lwc/datatable/datatable.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 2a6820cee..249640a56 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -104,6 +104,7 @@ export default class Datatable extends LightningElement { // Remove Row Action Attributes @api outputRemovedRows = []; @api numberOfRowsRemoved = 0; + @api outputRemainingRows = []; // Console Log differentiation get consoleLogPrefix() { @@ -1989,7 +1990,10 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } }); - this.outputEditedRows = [...this.outputEditedRows,eitem]; // Add to output attribute collection + const isRemovedBeforeSave = this.outputRemovedRows.some(rr => rr[this.keyField] === eitem[this.keyField]); + if (!isRemovedBeforeSave) { + this.outputEditedRows = [...this.outputEditedRows,eitem]; // Add to output attribute collection + } } return eitem; }); From f64c1bef0dc4441b2cd0510354c92de3d43e4643 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jul 2024 20:11:53 -0400 Subject: [PATCH 25/38] Move to Utils (columnValue, removeSpaces, convertFormat, convertType, convertTime) --- .../main/default/lwc/datatable/datatable.js | 368 +++++++----------- .../ers_datatableUtils/ers_datatableUtils.js | 77 +++- 2 files changed, 218 insertions(+), 227 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 249640a56..21176b02b 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -12,7 +12,7 @@ import { LightningElement, api, track, wire } from 'lwc'; import getReturnResults from '@salesforce/apex/ers_DatatableController.getReturnResults'; import { FlowAttributeChangeEvent, FlowNavigationNextEvent } from 'lightning/flowSupport'; import {getPicklistValuesByRecordType} from "lightning/uiObjectInfoApi"; -import { getConstants } from 'c/ers_datatableUtils'; +import { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime } from 'c/ers_datatableUtils'; // Translatable Custom Labels import CancelButton from '@salesforce/label/c.ers_CancelButton'; @@ -102,9 +102,12 @@ export default class Datatable extends LightningElement { @api tableIcon; // Remove Row Action Attributes + @api removeLabel = 'Remove Row'; + @api removeIcon = 'utility:close'; @api outputRemovedRows = []; @api numberOfRowsRemoved = 0; @api outputRemainingRows = []; + @api maxRemovedRows = 0; // Console Log differentiation get consoleLogPrefix() { @@ -217,6 +220,10 @@ export default class Datatable extends LightningElement { get suppressBottomBar() { return (this.cb_suppressBottomBar == CB_TRUE) ? true : false; } + set suppressBottomBar(value) { + this._suppressBottomBar = value; + } + _suppressBottomBar; @api cb_suppressBottomBar; @api @@ -294,22 +301,22 @@ export default class Datatable extends LightningElement { return JSON.stringify(this.tableData); } set serializedRecordData(value) { - if(this.isSerializedRecordData && this.isUpdateTable) { - if(value) { - this._tableData = JSON.parse(value); - } else { - this._tableData = []; - } - this.outputEditedRows = []; - this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); - this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); - this.outputEditedSerializedRows = ''; - this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); - setTimeout(function() { - this.connectedCallback(); - }.bind(this), 1000); - } - this.isUpdateTable = true; + // if(this.isSerializedRecordData && this.isUpdateTable) { + // if(value) { + // this._tableData = JSON.parse(value); + // } else { + // this._tableData = []; + // } + // this.outputEditedRows = []; + // this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); + // this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + // this.outputEditedSerializedRows = ''; + // this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); + // setTimeout(function() { + // this.connectedCallback(); + // }.bind(this), 1000); + // } + // this.isUpdateTable = true; } //NEW isUpdateTable = true; @@ -379,11 +386,7 @@ export default class Datatable extends LightningElement { @api scaleAttrib = []; @api typeAttrib = []; - // Remove Row Action Attributes - @api removeLabel = 'Remove Row'; - @api removeIcon = 'utility:close'; - - // Configuration Wizard Only - Input Attributes + // Configuration Wizard Only - Input Attributes @api objectName; // Configuration Wizard Only - Output Attributes @@ -803,30 +806,30 @@ export default class Datatable extends LightningElement { // Decode config mode attributes if (this.isConfigMode) { - this.columnAlignments = decodeURIComponent(this.columnAlignments); - this.columnEdits = decodeURIComponent(this.columnEdits); - this.columnFilters = decodeURIComponent(this.columnFilters); - this.columnIcons = decodeURIComponent(this.columnIcons); - this.columnLabels = decodeURIComponent(this.columnLabels); - this.columnWidths = decodeURIComponent(this.columnWidths); - this.columnWraps = decodeURIComponent(this.columnWraps); - this.columnFlexes = decodeURIComponent(this.columnFlexes); - this.columnFields = decodeURIComponent(this.columnFields); - this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); - this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); - this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); - console.log(this.consoleLogPrefix+"Config Mode Input columnAlignments:", this.columnAlignments); - console.log(this.consoleLogPrefix+"Config Mode Input columnEdits:", this.columnEdits); - console.log(this.consoleLogPrefix+"Config Mode Input columnFilters:", this.columnFilters); - console.log(this.consoleLogPrefix+"Config Mode Input columnIcons:", this.columnIcons); - console.log(this.consoleLogPrefix+"Config Mode Input columnLabels:", this.columnLabels); - console.log(this.consoleLogPrefix+"Config Mode Input columnWidths:", this.columnWidths); - console.log(this.consoleLogPrefix+"Config Mode Input columnWraps:", this.columnWraps); - console.log(this.consoleLogPrefix+"Config Mode Input columnFlexes:", this.columnFlexes); - console.log(this.consoleLogPrefix+"Config Mode Input columnFields:", this.columnFields); - console.log(this.consoleLogPrefix+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); - console.log(this.consoleLogPrefix+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); - console.log(this.consoleLogPrefix+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); + // this.columnAlignments = decodeURIComponent(this.columnAlignments); + // this.columnEdits = decodeURIComponent(this.columnEdits); + // this.columnFilters = decodeURIComponent(this.columnFilters); + // this.columnIcons = decodeURIComponent(this.columnIcons); + // this.columnLabels = decodeURIComponent(this.columnLabels); + // this.columnWidths = decodeURIComponent(this.columnWidths); + // this.columnWraps = decodeURIComponent(this.columnWraps); + // this.columnFlexes = decodeURIComponent(this.columnFlexes); + // this.columnFields = decodeURIComponent(this.columnFields); + // this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); + // this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); + // this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); + // console.log(this.consoleLogPrefix+"Config Mode Input columnAlignments:", this.columnAlignments); + // console.log(this.consoleLogPrefix+"Config Mode Input columnEdits:", this.columnEdits); + // console.log(this.consoleLogPrefix+"Config Mode Input columnFilters:", this.columnFilters); + // console.log(this.consoleLogPrefix+"Config Mode Input columnIcons:", this.columnIcons); + // console.log(this.consoleLogPrefix+"Config Mode Input columnLabels:", this.columnLabels); + // console.log(this.consoleLogPrefix+"Config Mode Input columnWidths:", this.columnWidths); + // console.log(this.consoleLogPrefix+"Config Mode Input columnWraps:", this.columnWraps); + // console.log(this.consoleLogPrefix+"Config Mode Input columnFlexes:", this.columnFlexes); + // console.log(this.consoleLogPrefix+"Config Mode Input columnFields:", this.columnFields); + // console.log(this.consoleLogPrefix+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); + // console.log(this.consoleLogPrefix+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); + // console.log(this.consoleLogPrefix+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); // this.not_suppressNameFieldLink = false; } @@ -882,7 +885,7 @@ export default class Datatable extends LightningElement { parseAlignments.forEach(align => { this.alignments.push({ column: this.columnReference(align), - alignment: this.columnValue(align) + alignment: columnValue(align) }); }); @@ -892,7 +895,7 @@ export default class Datatable extends LightningElement { this.attribCount = (parseEdits.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; this.editAttribType = 'none'; parseEdits.forEach(edit => { - let colEdit = (this.columnValue(edit).toLowerCase() == 'true') ? true : false; + let colEdit = (columnValue(edit).toLowerCase() == 'true') ? true : false; this.edits.push({ column: this.columnReference(edit), edit: colEdit @@ -910,7 +913,7 @@ export default class Datatable extends LightningElement { this.attribCount = (parseFilters.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; this.filterAttribType = 'none'; parseFilters.forEach(filter => { - let colFilter = (this.columnValue(filter).toLowerCase() == 'true') ? true : false; + let colFilter = (columnValue(filter).toLowerCase() == 'true') ? true : false; let col = this.columnReference(filter); this.filters.push({ column: col, @@ -933,42 +936,42 @@ export default class Datatable extends LightningElement { parseIcons.forEach(icon => { this.icons.push({ column: this.columnReference(icon), - icon: this.columnValue(icon) + icon: columnValue(icon) }); }); // Parse Column Label attribute - const parseLabels = (this.columnLabels.length > 0) ? this.removeSpaces(this.columnLabels).split(',') : []; + const parseLabels = (this.columnLabels.length > 0) ? removeSpaces(this.columnLabels).split(',') : []; this.attribCount = (parseLabels.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; parseLabels.forEach(label => { this.labels.push({ column: this.columnReference(label), - label: this.columnValue(label) + label: columnValue(label) }); }); if (this.isUserDefinedObject) { // JSON Version - Parse Column Scale attribute - const parseScales = (this.columnScales.length > 0) ? this.removeSpaces(this.columnScales).split(',') : []; + const parseScales = (this.columnScales.length > 0) ? removeSpaces(this.columnScales).split(',') : []; this.attribCount = (parseScales.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; parseScales.forEach(scale => { this.scales.push({ column: this.columnReference(scale), - scale: this.columnValue(scale) + scale: columnValue(scale) }); - this.basicColumns[this.columnReference(scale)].scale = this.columnValue(scale); + this.basicColumns[this.columnReference(scale)].scale = columnValue(scale); }); // JSON Version - Parse Column Type attribute - const parseTypes = (this.columnTypes.length > 0) ? this.removeSpaces(this.columnTypes).split(',') : []; + const parseTypes = (this.columnTypes.length > 0) ? removeSpaces(this.columnTypes).split(',') : []; this.attribCount = (parseTypes.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; parseTypes.forEach(type => { this.types.push({ column: this.columnReference(type), - type: this.columnValue(type) + type: columnValue(type) }); - this.basicColumns[this.columnReference(type)].type = this.columnValue(type); + this.basicColumns[this.columnReference(type)].type = columnValue(type); }); } @@ -978,7 +981,7 @@ export default class Datatable extends LightningElement { parseWidths.forEach(width => { this.widths.push({ column: this.columnReference(width), - width: parseInt(this.columnValue(width)) + width: parseInt(columnValue(width)) }); }); @@ -988,7 +991,7 @@ export default class Datatable extends LightningElement { this.attribCount = (parseFlexes.findIndex(f => f.search(':') != -1) != -1) ? 0 : 1; this.flexAttribType = 'none'; parseFlexes.forEach(flex => { - let colFlex = (this.columnValue(flex).toLowerCase() == 'true') ? true : false; + let colFlex = (columnValue(flex).toLowerCase() == 'true') ? true : false; this.flexes.push({ column: this.columnReference(flex), flex: colFlex @@ -1006,37 +1009,37 @@ export default class Datatable extends LightningElement { parseWraps.forEach(wrap => { this.wraps.push({ column: this.columnReference(wrap), - wrap: (this.columnValue(wrap).toLowerCase() == 'true') ? true : false + wrap: (columnValue(wrap).toLowerCase() == 'true') ? true : false }); }); // Parse Column CellAttribute attribute (Because multiple attributes use , these are separated by ;) - const parseCellAttribs = (this.columnCellAttribs.length > 0) ? this.removeSpaces(this.columnCellAttribs).split(';') : []; + const parseCellAttribs = (this.columnCellAttribs.length > 0) ? removeSpaces(this.columnCellAttribs).split(';') : []; this.attribCount = 0; // These attributes must specify a column number or field API name parseCellAttribs.forEach(cellAttrib => { this.cellAttribs.push({ column: this.columnReference(cellAttrib), - attribute: this.columnValue(cellAttrib) + attribute: columnValue(cellAttrib) }); }); // Parse Column Other Attributes attribute (Because multiple attributes use , these are separated by ;) - const parseOtherAttribs = (this.columnOtherAttribs.length > 0) ? this.removeSpaces(this.columnOtherAttribs).split(';') : []; + const parseOtherAttribs = (this.columnOtherAttribs.length > 0) ? removeSpaces(this.columnOtherAttribs).split(';') : []; this.attribCount = 0; // These attributes must specify a column number or field API name parseOtherAttribs.forEach(otherAttrib => { this.otherAttribs.push({ column: this.columnReference(otherAttrib), - attribute: this.columnValue(otherAttrib) + attribute: columnValue(otherAttrib) }); }); // Parse Column TypeAttribute attribute (Because multiple attributes use , these are separated by ;) - const parseTypeAttribs = (this.columnTypeAttribs.length > 0) ? this.removeSpaces(this.columnTypeAttribs).split(';') : []; + const parseTypeAttribs = (this.columnTypeAttribs.length > 0) ? removeSpaces(this.columnTypeAttribs).split(';') : []; this.attribCount = 0; // These attributes must specify a column number or field API name parseTypeAttribs.forEach(ta => { this.typeAttribs.push({ column: this.columnReference(ta), - attribute: this.columnValue(ta) + attribute: columnValue(ta) }); }); @@ -1082,39 +1085,6 @@ export default class Datatable extends LightningElement { console.log(this.consoleLogPrefix+'tableData - ',(SHOW_DEBUG_INFO) ? this._tableData : '***'); this.preSelectedRows = (this.preSelectedRowsString.length > 0) ? JSON.parse(this.preSelectedRowsString) : []; } - - removeSpaces(string) { - return string - .replace(/, | ,/g,',') - .replace(/: | :/g,':') - .replace(/{ | {/g,'{') - .replace(/} | }/g,'}') - .replace(/; | ;/g,';'); - } - - columnReference(attrib) { - // The column reference can be either the field API name or the column sequence number (1,2,3 ...) - // If no column reference is specified, the values are assigned to columns in order (There must be a value provided for each column) - // Return the actual column # (0,1,2 ...) - let colRef = 0; - if (this.attribCount == 0) { - let colDescriptor = attrib.split(':')[0]; - colRef = Number(colDescriptor)-1; - if (isNaN(colRef)) { - colRef = this.columnArray.indexOf(colDescriptor); - colRef = (colRef != -1) ? colRef : 999; // If no match for the field name, set to non-existent column # - } - } else { - colRef = this.attribCount-1; - this.attribCount += 1; - } - return colRef; - } - - columnValue(attrib) { - // Extract the value from the column attribute - return attrib.slice(attrib.search(':')+1); - } processDatatable() { if (this.isUserDefinedObject && !this.isConfigMode) { @@ -1382,10 +1352,12 @@ export default class Datatable extends LightningElement { this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only + // this.outputRemainingRows = [...this.editedData]; console.log(this.consoleLogPrefix+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); console.log(this.consoleLogPrefix+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); console.log(this.consoleLogPrefix+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); console.log(this.consoleLogPrefix+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); + // console.log(this.consoleLogPrefix+'outputRemainingRows:',(SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); } updateColumns() { @@ -1509,26 +1481,7 @@ export default class Datatable extends LightningElement { } if (this.isConfigMode) { - let wizardAlignLeft = (!alignmentAttrib) ? (this.convertType(type) != 'number') : (alignment == 'left'); - let wizardAlignCenter = (!alignmentAttrib) ? false : (alignment == 'center'); - let wizardAlignRight = (!alignmentAttrib) ? (this.convertType(type) == 'number') : (alignment == 'right'); - let wizardEdit = (!editAttrib) ? false : (editAttrib.edit || false); - let wizardFilter = filterAttrib.filter || false; - let wizardFlex = (!flexAttrib) ? false : (flexAttrib.flex || false); - filterAttrib.column = columnNumber; - filterAttrib.filter = true; - filterAttrib.actions = [ - {label: 'Align Left', checked: wizardAlignLeft, name: 'alignl_' + columnNumber, iconName: 'utility:left_align_text'}, - {label: 'Align Center', checked: wizardAlignCenter, name: 'alignc_' + columnNumber, iconName: 'utility:center_align_text'}, - {label: 'Align Right', checked: wizardAlignRight, name: 'alignr_' + columnNumber, iconName: 'utility:right_align_text'}, - {label: 'Select Icon', disabled: false, name: 'icon_' + columnNumber, iconName: 'utility:text'}, - {label: 'Change Label', disabled: false, name: 'label_' + columnNumber, iconName: 'utility:text'}, - {label: 'Cancel Change', disabled: true, name: 'clear_' + columnNumber, iconName: 'utility:clear'}, - {label: 'Allow Edit', checked: wizardEdit, name: 'aedit_' + columnNumber, iconName: 'utility:edit'}, - {label: 'Allow Filter', checked: wizardFilter, name: 'afilter_' + columnNumber, iconName: 'utility:filter'}, - {label: 'Flex Width', checked: wizardFlex, name: 'flex_' + columnNumber, iconName: 'utility:full_width_view'} - ]; - this.cellAttributes = { alignment: alignment }; +//🚀 } // Update Icon attribute overrides by column @@ -1730,12 +1683,31 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } } + columnReference(attrib) { + // The column reference can be either the field API name or the column sequence number (1,2,3 ...) + // If no column reference is specified, the values are assigned to columns in order (There must be a value provided for each column) + // Return the actual column # (0,1,2 ...) + let colRef = 0; + if (this.attribCount == 0) { + let colDescriptor = attrib.split(':')[0]; + colRef = Number(colDescriptor)-1; + if (isNaN(colRef)) { + colRef = this.columnArray.indexOf(colDescriptor); + colRef = (colRef != -1) ? colRef : 999; // If no match for the field name, set to non-existent column # + } + } else { + colRef = this.attribCount-1; + this.attribCount += 1; + } + return colRef; + } + parseAttributes(propertyType,inputAttributes,columnNumber) { // Parse regular and nested name:value attribute pairs let result = []; let fullAttrib = inputAttributes.find(i => i['column'] == columnNumber); if (fullAttrib) { - let attribSplit = this.removeSpaces(fullAttrib.attribute.slice(1,-1)).split(','); + let attribSplit = removeSpaces(fullAttrib.attribute.slice(1,-1)).split(','); attribSplit.forEach(ca => { let subAttribPos = ca.search('{'); if (subAttribPos != -1) { @@ -1789,54 +1761,57 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 case 'removeRow': - // Add to removed row collection and update counter - this.outputRemovedRows = [...this.outputRemovedRows, row]; - this.numberOfRowsRemoved ++; + // if (this.maxRemovedRows > 0 && this.numberOfRowsRemoved < this.maxRemovedRows) { - // handle selected rows - const index = this._allSelectedRowIds.indexOf(keyValue); - if (index != -1) { - this._allSelectedRowIds.splice(index, 1); - } - - // handle edited rows - this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; - this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; - this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); - this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + // Add to removed row collection and update counter + const removedRows = [...this.outputRemovedRows, row]; + this.outputRemovedRows = []; + this.savePreEditData.forEach(rec => { + const isRemoved = removedRows.some(rrec => rrec[this.keyField] === rec[this.keyField]); + if (isRemoved) { + this.outputRemovedRows = [...this.outputRemovedRows, rec] + } + }); + this.numberOfRowsRemoved ++; - // remove record from collection - this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + // handle selected rows + const index = this._allSelectedRowIds.indexOf(keyValue); + if (index != -1) { + this._allSelectedRowIds.splice(index, 1); + } - if (this.mydata.length == 0) { // Last record was removed from the datatable - // clear last selected row - this.outputSelectedRows = []; - if (!this.isUserDefinedObject) { - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); - } else { - this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); - this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + // handle edited & remaining rows + this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; + this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; + // this.outputRemainingRows = [...this.removeRowFromCollection(this.outputRemainingRows, keyValue)]; + this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); + this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + + // remove record from collection + this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + + if (this.mydata.length == 0) { // Last record was removed from the datatable + // clear last selected row + this.outputSelectedRows = []; + if (!this.isUserDefinedObject) { + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRows', this.outputSelectedRows)); + } else { + this.outputSelectedRowsString = JSON.stringify(this.outputSelectedRows); + this.dispatchEvent(new FlowAttributeChangeEvent('outputSelectedRowsString', this.outputSelectedRowsString)); + } + this.updateNumberOfRowsSelected(this.outputSelectedRows); + // refresh table + this.tableData = []; } - this.updateNumberOfRowsSelected(this.outputSelectedRows); - // refresh table - this.tableData = []; - } + + // } else { + + // } break; default: } - // this.mydata = this._mydata.map(rowData => { - // if (rowData[this.keyField] === keyValue) { - // switch (action.name) { - // // case 'action': goes here - // // - // // break; - // default: - // } - // } - // return rowData; - // }); } removeRowFromCollection(collection, keyValue) { @@ -1967,7 +1942,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 timefield.forEach(time => { if (!this.suppressBottomBar || (time == editField)) { if (field[time]) { - field[time] = this.convertTime(field[time]); + field[time] = convertTime(this, field[time]); } } }); @@ -2027,18 +2002,6 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.mydata = [...this.savePreEditData]; } - convertTime(dtValue) { - // Return a Salesforce formatted time value based a datetime value - const dtv = new Date(dtValue); - const hours = dtv.getHours() - (this.timezoneOffset / 2880000); - let timeString = ("00"+hours).slice(-2)+":"; - timeString += ("00"+dtv.getMinutes()).slice(-2)+":"; - timeString += ("00"+dtv.getSeconds()).slice(-2)+"."; - timeString += ("000"+dtv.getMilliseconds()).slice(-3); - timeString += "Z"; - return timeString; - } - handleRowSelection(event) { // Added in v4.2.1 - Pagination - Persist previously selected rows that are not displayed on the currently visible page // Only used with row selection @@ -2283,8 +2246,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.columnFilterValue = this.columnFilterValues[this.columnNumber]; this.columnFilterValue = (this.columnFilterValue) ? this.columnFilterValue : this.baseLabel; this.columnType = 'richtext'; - this.inputType = this.convertType(this.columnType); - this.inputFormat = (this.inputType == 'number') ? this.convertFormat(this.columnType) : null; + this.inputType = convertType(this.columnType); + this.inputFormat = (this.inputType == 'number') ? convertFormat(this.columnType) : null; this.handleOpenFilterInput(); break; @@ -2292,9 +2255,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.columnFilterValue = this.columnFilterValues[this.columnNumber]; this.columnFilterValue = (this.columnFilterValue) ? this.columnFilterValue : null; this.columnType = colDef.type; - this.inputType = this.convertType(this.columnType); + this.inputType = convertType(this.columnType); this.inputType = (this.inputType == 'url') ? 'text' : this.inputType; - this.inputFormat = (this.inputType == 'number') ? this.convertFormat(this.columnType) : null; + this.inputFormat = (this.inputType == 'number') ? convertFormat(this.columnType) : null; this.handleOpenFilterInput(); break; @@ -2329,53 +2292,6 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.columns = [...this.filterColumns]; } - convertType(colType) { - // Set Input Type based on column Data Type - switch(colType) { - case 'boolean': - return 'text'; - case 'date': - return 'date'; - case 'date-local': - return 'date'; - case 'datetime': - return 'datetime'; - case 'time': - return 'time'; - case 'email': - return 'email'; - case 'phone': - return 'tel'; - case 'url': - return 'url'; - case 'number': - return 'number'; - case 'currency': - return 'number'; - case 'percent': - return 'number'; - case 'number': - return 'number'; - case 'text': - return 'text'; - default: - return 'richtext'; - } - } - - convertFormat(colType) { - // Set Input Formatter value for different number types - switch(colType) { - case 'currency': - return 'currency'; - case 'percent': - // return 'percent-fixed'; // This would be to enter 35 to get 35% (0.35) - return 'percent'; - default: - return null; - } - } - handleResize(event) { // Save the current column widths and update the config parameter this.columnWidthValues = event.detail.columnWidths; @@ -2760,7 +2676,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 // Create the Alignment Label parameter for Config Mode let colString = ''; this.filterColumns.forEach(colDef => { - let configAlign = (this.convertType(colDef['type']) != 'number') ? 'left' : 'right'; + let configAlign = (convertType(colDef['type']) != 'number') ? 'left' : 'right'; let currentAlign = colDef['cellAttributes']['alignment']; if (currentAlign && (currentAlign != configAlign)) { colString = colString + ', ' + colDef['fieldName'] + ':' + colDef['cellAttributes']['alignment']; @@ -2920,6 +2836,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 console.log(this.consoleLogPrefix+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); console.log(this.consoleLogPrefix+'outputEditedRows', this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); + // console.log(this.consoleLogPrefix+'outputRemovedRows', this.outputRemovedRows.length, (SHOW_DEBUG_INFO) ? this.outputRemovedRows : '***'); + // console.log(this.consoleLogPrefix+'outputRemainingRows', this.outputRemainingRows.length, (SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); // Validation logic to pass back to the Flow if(!this.isRequired || this.numberOfRowsSelected > 0) { diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index 52c426425..872137341 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -1,5 +1,5 @@ /** -* @description a util class for storing Constants +* @description a util class for storing Constants & Functions */ const reverse = str => str.split('').reverse().join(''); // Reverse all the characters in a string @@ -51,4 +51,77 @@ const getConstants = () => { } } -export { getConstants }; \ No newline at end of file +const columnValue = (attrib) => { + // Extract the value from the column attribute + return attrib.slice(attrib.search(':')+1); +}; + +const removeSpaces = (string) => { + return string + .replace(/, | ,/g,',') + .replace(/: | :/g,':') + .replace(/{ | {/g,'{') + .replace(/} | }/g,'}') + .replace(/; | ;/g,';'); +} + +const convertFormat = (colType) => { + // Set Input Formatter value for different number types + switch(colType) { + case 'currency': + return 'currency'; + case 'percent': + // return 'percent-fixed'; // This would be to enter 35 to get 35% (0.35) + return 'percent'; + default: + return null; + } +} + +const convertType = (colType) => { + // Set Input Type based on column Data Type + switch(colType) { + case 'boolean': + return 'text'; + case 'date': + return 'date'; + case 'date-local': + return 'date'; + case 'datetime': + return 'datetime'; + case 'time': + return 'time'; + case 'email': + return 'email'; + case 'phone': + return 'tel'; + case 'url': + return 'url'; + case 'number': + return 'number'; + case 'currency': + return 'number'; + case 'percent': + return 'number'; + case 'number': + return 'number'; + case 'text': + return 'text'; + default: + return 'richtext'; + } +} + +const convertTime = (that, dtValue) => { + // Return a Salesforce formatted time value based a datetime value + const dtv = new Date(dtValue); + const hours = dtv.getHours() - (that.timezoneOffset / 2880000); + let timeString = ("00"+hours).slice(-2)+":"; + timeString += ("00"+dtv.getMinutes()).slice(-2)+":"; + timeString += ("00"+dtv.getSeconds()).slice(-2)+"."; + timeString += ("000"+dtv.getMilliseconds()).slice(-3); + timeString += "Z"; + return timeString; +} + +export { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime }; \ No newline at end of file From bdd636bac3788dd4868bcdf2183e81d0972bd8a5 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jul 2024 20:40:03 -0400 Subject: [PATCH 26/38] Remaining & Removed output attributes working --- .../main/default/lwc/datatable/datatable.js | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 21176b02b..f5bfb6759 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1352,12 +1352,12 @@ export default class Datatable extends LightningElement { this.mydata = [...data]; this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only - // this.outputRemainingRows = [...this.editedData]; + this.outputRemainingRows = [...this.editedData]; console.log(this.consoleLogPrefix+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); console.log(this.consoleLogPrefix+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); console.log(this.consoleLogPrefix+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); console.log(this.consoleLogPrefix+'mydata:',(SHOW_DEBUG_INFO) ? this._mydata : '***'); - // console.log(this.consoleLogPrefix+'outputRemainingRows:',(SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); + console.log(this.consoleLogPrefix+'outputRemainingRows:',(SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); } updateColumns() { @@ -1481,7 +1481,26 @@ export default class Datatable extends LightningElement { } if (this.isConfigMode) { -//🚀 + let wizardAlignLeft = (!alignmentAttrib) ? (this.convertType(type) != 'number') : (alignment == 'left'); + let wizardAlignCenter = (!alignmentAttrib) ? false : (alignment == 'center'); + let wizardAlignRight = (!alignmentAttrib) ? (this.convertType(type) == 'number') : (alignment == 'right'); + let wizardEdit = (!editAttrib) ? false : (editAttrib.edit || false); + let wizardFilter = filterAttrib.filter || false; + let wizardFlex = (!flexAttrib) ? false : (flexAttrib.flex || false); + filterAttrib.column = columnNumber; + filterAttrib.filter = true; + filterAttrib.actions = [ + {label: 'Align Left', checked: wizardAlignLeft, name: 'alignl_' + columnNumber, iconName: 'utility:left_align_text'}, + {label: 'Align Center', checked: wizardAlignCenter, name: 'alignc_' + columnNumber, iconName: 'utility:center_align_text'}, + {label: 'Align Right', checked: wizardAlignRight, name: 'alignr_' + columnNumber, iconName: 'utility:right_align_text'}, + {label: 'Select Icon', disabled: false, name: 'icon_' + columnNumber, iconName: 'utility:text'}, + {label: 'Change Label', disabled: false, name: 'label_' + columnNumber, iconName: 'utility:text'}, + {label: 'Cancel Change', disabled: true, name: 'clear_' + columnNumber, iconName: 'utility:clear'}, + {label: 'Allow Edit', checked: wizardEdit, name: 'aedit_' + columnNumber, iconName: 'utility:edit'}, + {label: 'Allow Filter', checked: wizardFilter, name: 'afilter_' + columnNumber, iconName: 'utility:filter'}, + {label: 'Flex Width', checked: wizardFlex, name: 'flex_' + columnNumber, iconName: 'utility:full_width_view'} + ]; + this.cellAttributes = { alignment: alignment }; } // Update Icon attribute overrides by column @@ -1761,17 +1780,10 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 case 'removeRow': - // if (this.maxRemovedRows > 0 && this.numberOfRowsRemoved < this.maxRemovedRows) { + if (this.maxRemovedRows == 0 || this.numberOfRowsRemoved < this.maxRemovedRows) { // Add to removed row collection and update counter - const removedRows = [...this.outputRemovedRows, row]; - this.outputRemovedRows = []; - this.savePreEditData.forEach(rec => { - const isRemoved = removedRows.some(rrec => rrec[this.keyField] === rec[this.keyField]); - if (isRemoved) { - this.outputRemovedRows = [...this.outputRemovedRows, rec] - } - }); + this.outputRemovedRows = [...this.outputRemovedRows, row]; // Removed row collection will be in order of removal, not original order this.numberOfRowsRemoved ++; // handle selected rows @@ -1783,7 +1795,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 // handle edited & remaining rows this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; - // this.outputRemainingRows = [...this.removeRowFromCollection(this.outputRemainingRows, keyValue)]; + this.outputRemainingRows = [...this.removeRowFromCollection(this.outputRemainingRows, keyValue)]; this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); @@ -1804,9 +1816,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.tableData = []; } - // } else { + } else { - // } + } break; default: @@ -2836,8 +2848,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 console.log(this.consoleLogPrefix+'outputSelectedRows', this.outputSelectedRows.length, (SHOW_DEBUG_INFO) ? this.outputSelectedRows : '***'); console.log(this.consoleLogPrefix+'outputEditedRows', this.outputEditedRows.length, (SHOW_DEBUG_INFO) ? this.outputEditedRows : '***'); - // console.log(this.consoleLogPrefix+'outputRemovedRows', this.outputRemovedRows.length, (SHOW_DEBUG_INFO) ? this.outputRemovedRows : '***'); - // console.log(this.consoleLogPrefix+'outputRemainingRows', this.outputRemainingRows.length, (SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); + console.log(this.consoleLogPrefix+'outputRemovedRows', this.outputRemovedRows.length, (SHOW_DEBUG_INFO) ? this.outputRemovedRows : '***'); + console.log(this.consoleLogPrefix+'outputRemainingRows', this.outputRemainingRows.length, (SHOW_DEBUG_INFO) ? this.outputRemainingRows : '***'); // Validation logic to pass back to the Flow if(!this.isRequired || this.numberOfRowsSelected > 0) { From 3f9fc389b18efe30d33ff73b1cc77d33ca96091c Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 16:17:30 -0400 Subject: [PATCH 27/38] Disable Remove after Max, uncomment lines removed for deployment size --- flow_screen_components/datatable/README.md | 5 +- .../main/default/lwc/datatable/datatable.js | 99 +++++++++++-------- .../ers_customLightningDatatableStyles.css | 5 +- 3 files changed, 64 insertions(+), 45 deletions(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index 4546e6333..50c337e70 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -75,7 +75,10 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th ## 07/xx/24 - Eric Smith - Version 4.2.1 **Updates:** - New Feature: Add a Remove Row action as the first or last column in a Datatable. -- New outputs include a collection and a count of the removed rows. +- New outputs include a collection and a count of the removed rows. +- You can specify the maximum number of rows that can be removed. +- Selected Rows are now persistent when Paginating, Searching, Filtering, Sorting, and Removing! +- A new output attribute (outputRemainingRows) will provide all records passed into the table with all edits made to those records, less all records (if any) that were removed - Implemented a default setting (SHOW_DEBUG_INFO = false) to hide record details from console and debug logs - Source code changes in ers_datatableUtils.js, ers_DatatableController.cls & ers_QueryNRecords.cls - Console.log statements are now identified with the Datatable's header label diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index f5bfb6759..28dc73aca 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -104,10 +104,18 @@ export default class Datatable extends LightningElement { // Remove Row Action Attributes @api removeLabel = 'Remove Row'; @api removeIcon = 'utility:close'; + @api maxRemovedRows = 3; + @api removeRowLeftOrRight = 'Right'; @api outputRemovedRows = []; @api numberOfRowsRemoved = 0; @api outputRemainingRows = []; - @api maxRemovedRows = 0; + removeRowActionColNum; + + @api + get isRemoveRowAction() { + return (this.cb_isRemoveRowAction == CB_TRUE) ? true : false; + } + @api cb_isRemoveRowAction; // Console Log differentiation get consoleLogPrefix() { @@ -301,22 +309,22 @@ export default class Datatable extends LightningElement { return JSON.stringify(this.tableData); } set serializedRecordData(value) { - // if(this.isSerializedRecordData && this.isUpdateTable) { - // if(value) { - // this._tableData = JSON.parse(value); - // } else { - // this._tableData = []; - // } - // this.outputEditedRows = []; - // this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); - // this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); - // this.outputEditedSerializedRows = ''; - // this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); - // setTimeout(function() { - // this.connectedCallback(); - // }.bind(this), 1000); - // } - // this.isUpdateTable = true; + if(this.isSerializedRecordData && this.isUpdateTable) { + if(value) { + this._tableData = JSON.parse(value); + } else { + this._tableData = []; + } + this.outputEditedRows = []; + this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); + this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + this.outputEditedSerializedRows = ''; + this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); + setTimeout(function() { + this.connectedCallback(); + }.bind(this), 1000); + } + this.isUpdateTable = true; } //NEW isUpdateTable = true; @@ -806,31 +814,31 @@ export default class Datatable extends LightningElement { // Decode config mode attributes if (this.isConfigMode) { - // this.columnAlignments = decodeURIComponent(this.columnAlignments); - // this.columnEdits = decodeURIComponent(this.columnEdits); - // this.columnFilters = decodeURIComponent(this.columnFilters); - // this.columnIcons = decodeURIComponent(this.columnIcons); - // this.columnLabels = decodeURIComponent(this.columnLabels); - // this.columnWidths = decodeURIComponent(this.columnWidths); - // this.columnWraps = decodeURIComponent(this.columnWraps); - // this.columnFlexes = decodeURIComponent(this.columnFlexes); - // this.columnFields = decodeURIComponent(this.columnFields); - // this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); - // this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); - // this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); - // console.log(this.consoleLogPrefix+"Config Mode Input columnAlignments:", this.columnAlignments); - // console.log(this.consoleLogPrefix+"Config Mode Input columnEdits:", this.columnEdits); - // console.log(this.consoleLogPrefix+"Config Mode Input columnFilters:", this.columnFilters); - // console.log(this.consoleLogPrefix+"Config Mode Input columnIcons:", this.columnIcons); - // console.log(this.consoleLogPrefix+"Config Mode Input columnLabels:", this.columnLabels); - // console.log(this.consoleLogPrefix+"Config Mode Input columnWidths:", this.columnWidths); - // console.log(this.consoleLogPrefix+"Config Mode Input columnWraps:", this.columnWraps); - // console.log(this.consoleLogPrefix+"Config Mode Input columnFlexes:", this.columnFlexes); - // console.log(this.consoleLogPrefix+"Config Mode Input columnFields:", this.columnFields); - // console.log(this.consoleLogPrefix+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); - // console.log(this.consoleLogPrefix+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); - // console.log(this.consoleLogPrefix+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); - // this.not_suppressNameFieldLink = false; + this.columnAlignments = decodeURIComponent(this.columnAlignments); + this.columnEdits = decodeURIComponent(this.columnEdits); + this.columnFilters = decodeURIComponent(this.columnFilters); + this.columnIcons = decodeURIComponent(this.columnIcons); + this.columnLabels = decodeURIComponent(this.columnLabels); + this.columnWidths = decodeURIComponent(this.columnWidths); + this.columnWraps = decodeURIComponent(this.columnWraps); + this.columnFlexes = decodeURIComponent(this.columnFlexes); + this.columnFields = decodeURIComponent(this.columnFields); + this.columnCellAttribs = decodeURIComponent(this.columnCellAttribs); + this.columnTypeAttribs = decodeURIComponent(this.columnTypeAttribs); + this.columnOtherAttribs = decodeURIComponent(this.columnOtherAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnAlignments:", this.columnAlignments); + console.log(this.consoleLogPrefix+"Config Mode Input columnEdits:", this.columnEdits); + console.log(this.consoleLogPrefix+"Config Mode Input columnFilters:", this.columnFilters); + console.log(this.consoleLogPrefix+"Config Mode Input columnIcons:", this.columnIcons); + console.log(this.consoleLogPrefix+"Config Mode Input columnLabels:", this.columnLabels); + console.log(this.consoleLogPrefix+"Config Mode Input columnWidths:", this.columnWidths); + console.log(this.consoleLogPrefix+"Config Mode Input columnWraps:", this.columnWraps); + console.log(this.consoleLogPrefix+"Config Mode Input columnFlexes:", this.columnFlexes); + console.log(this.consoleLogPrefix+"Config Mode Input columnFields:", this.columnFields); + console.log(this.consoleLogPrefix+"Config Mode Input columnCellAttribs:", this.columnCellAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnTypeAttribs:", this.columnTypeAttribs); + console.log(this.consoleLogPrefix+"Config Mode Input columnOtherAttribs:", this.columnOtherAttribs); + this.not_suppressNameFieldLink = false; } console.log(this.consoleLogPrefix+'tableDataString - ',(SHOW_DEBUG_INFO) ? this._tableDataString : '***', this.isUserDefinedObject); @@ -1367,6 +1375,8 @@ export default class Datatable extends LightningElement { let columnNumber = 0; let lufield = ''; + // if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 + this.basicColumns.forEach(colDef => { // Standard parameters @@ -1676,6 +1686,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 wrapText: false, flex: false }); + this.removeRowActionColNum = this.cols.length - 1; } updatePreSelectedRows() { @@ -1816,7 +1827,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.tableData = []; } - } else { + if (this.numberOfRowsRemoved === this.maxRemovedRows) { + this.columns[this.removeRowActionColNum].cellAttributes["class"] = "remove-icon-disabled"; + } } break; diff --git a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css index eabf0282b..7f287b125 100644 --- a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css +++ b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css @@ -85,4 +85,7 @@ c-datatable c-ers_custom-lightning-datatable .dt-outer-container lightning-primi /* v4.2.1 Remove Row Icon styling */ .remove-icon { --slds-c-icon-color-foreground: red; -} \ No newline at end of file +} +.remove-icon-disabled { + --slds-c-icon-color-foreground: #E6E6E6; +} From 7bbd62e7a54f510a2b7b1a0877a6e2471c5641d3 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 16:37:21 -0400 Subject: [PATCH 28/38] Disable Remove Row Action Button when Max is reached --- .../force-app/main/default/lwc/datatable/datatable.js | 7 ++++--- .../staticresources/ers_customLightningDatatableStyles.css | 3 --- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 28dc73aca..7316be982 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1673,7 +1673,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 iconName: this.removeIcon, tooltip: this.removeLabel, variant: "border", - size: "medium" + size: "medium", + disabled: false }, cellAttributes: { class: "remove-icon" @@ -1828,9 +1829,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } if (this.numberOfRowsRemoved === this.maxRemovedRows) { - this.columns[this.removeRowActionColNum].cellAttributes["class"] = "remove-icon-disabled"; + this.columns[this.removeRowActionColNum].typeAttributes["disabled"] = ""; } - + } break; diff --git a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css index 7f287b125..9e5c93a30 100644 --- a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css +++ b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css @@ -86,6 +86,3 @@ c-datatable c-ers_custom-lightning-datatable .dt-outer-container lightning-primi .remove-icon { --slds-c-icon-color-foreground: red; } -.remove-icon-disabled { - --slds-c-icon-color-foreground: #E6E6E6; -} From c2ef042a2cee2d02fc1ce2b32c47175100ab3190 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 17:02:27 -0400 Subject: [PATCH 29/38] Add input & output properties --- .../main/default/lwc/datatable/datatable.js | 2 +- .../default/lwc/datatable/datatable.js-meta.xml | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 7316be982..ecf7a256f 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -104,7 +104,7 @@ export default class Datatable extends LightningElement { // Remove Row Action Attributes @api removeLabel = 'Remove Row'; @api removeIcon = 'utility:close'; - @api maxRemovedRows = 3; + @api maxRemovedRows = 0; @api removeRowLeftOrRight = 'Right'; @api outputRemovedRows = []; @api numberOfRowsRemoved = 0; diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml index 8f44e6da5..1d3620b70 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml @@ -22,6 +22,10 @@ - NOTE: These records may not contain all of the edited values."/> + + @@ -43,7 +47,10 @@ + + + @@ -142,9 +149,13 @@ - - - + + + + + + + \ No newline at end of file From 078a755770eca3fff8462981a3402fc9558be282 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 17:30:35 -0400 Subject: [PATCH 30/38] Dispatch new output attributes when changed --- .../force-app/main/default/lwc/datatable/datatable.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index ecf7a256f..081ef7a52 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1361,6 +1361,7 @@ export default class Datatable extends LightningElement { this.savePreEditData = [...this._mydata]; this.editedData = JSON.parse(JSON.stringify([...this._tableData])); // Must clone because cached items are read-only this.outputRemainingRows = [...this.editedData]; + this.dispatchEvent(new FlowAttributeChangeEvent('outputRemainingRows', this.outputRemainingRows)); console.log(this.consoleLogPrefix+'allSelectedRowIds',(SHOW_DEBUG_INFO) ? this.allSelectedRowIds : '***'); console.log(this.consoleLogPrefix+'keyField:',(SHOW_DEBUG_INFO) ? this.keyField : '***'); console.log(this.consoleLogPrefix+'tableData',(SHOW_DEBUG_INFO) ? this._tableData : '***'); @@ -1491,9 +1492,9 @@ export default class Datatable extends LightningElement { } if (this.isConfigMode) { - let wizardAlignLeft = (!alignmentAttrib) ? (this.convertType(type) != 'number') : (alignment == 'left'); + let wizardAlignLeft = (!alignmentAttrib) ? (convertType(type) != 'number') : (alignment == 'left'); let wizardAlignCenter = (!alignmentAttrib) ? false : (alignment == 'center'); - let wizardAlignRight = (!alignmentAttrib) ? (this.convertType(type) == 'number') : (alignment == 'right'); + let wizardAlignRight = (!alignmentAttrib) ? (convertType(type) == 'number') : (alignment == 'right'); let wizardEdit = (!editAttrib) ? false : (editAttrib.edit || false); let wizardFilter = filterAttrib.filter || false; let wizardFlex = (!flexAttrib) ? false : (flexAttrib.flex || false); @@ -1810,6 +1811,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.outputRemainingRows = [...this.removeRowFromCollection(this.outputRemainingRows, keyValue)]; this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + this.dispatchEvent(new FlowAttributeChangeEvent('outputRemovedRows', this.outputRemovedRows)); + this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsRemoved', this.numberOfRowsRemoved)); + this.dispatchEvent(new FlowAttributeChangeEvent('outputRemainingRows', this.outputRemainingRows)); // remove record from collection this.mydata = this.removeRowFromCollection(this._mydata, keyValue); From f8e7845e4a754fbe1d72fb5b4746ce8e204bda53 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 18:25:15 -0400 Subject: [PATCH 31/38] Update remaining rows collection with edits --- .../main/default/lwc/datatable/datatable.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 081ef7a52..544593682 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1848,7 +1848,18 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 const index = this.findRowIndexById(collection, keyValue); let result = collection; if (index !== -1) { - result = collection.slice(0, index).concat(collection.slice(index +1)); + result = collection.slice(0, index).concat(collection.slice(index+1)); + } + return result; + } + + replaceRowInCollection(original, updated, keyValue) { + // Replace the matching row in the original collection with the matching row from the updated collection + const oindex = this.findRowIndexById(original, keyValue); + const uindex = this.findRowIndexById(updated, keyValue); + let result = original; + if (oindex !== -1 && uindex !== -1) { + result = original.slice(0, oindex).concat(updated.slice(uindex,uindex+1)).concat(original.slice(oindex+1)); } return result; } @@ -1999,6 +2010,8 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 if (!isRemovedBeforeSave) { this.outputEditedRows = [...this.outputEditedRows,eitem]; // Add to output attribute collection } + + this.outputRemainingRows = this.replaceRowInCollection(this.outputRemainingRows, this.outputEditedRows, eitem[this.keyField]); } return eitem; }); @@ -2006,6 +2019,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.isUpdateTable = false; this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); + this.dispatchEvent(new FlowAttributeChangeEvent('outputRemainingRows', this.outputRemainingRows)); if(this.isSerializedRecordData) { this.outputEditedSerializedRows = JSON.stringify(this.outputEditedRows); this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedSerializedRows', this.outputEditedSerializedRows)); From 9e81c476c6ff127917df4329fc2cffcedb25c12e Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 7 Jul 2024 18:44:55 -0400 Subject: [PATCH 32/38] Move removeRowFromCollection, replaceRowInCollection, findRowIndexById to utils --- .../main/default/lwc/datatable/datatable.js | 56 ++++--------------- .../ers_datatableUtils/ers_datatableUtils.js | 34 ++++++++++- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index 544593682..d7eda7fa7 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -12,7 +12,7 @@ import { LightningElement, api, track, wire } from 'lwc'; import getReturnResults from '@salesforce/apex/ers_DatatableController.getReturnResults'; import { FlowAttributeChangeEvent, FlowNavigationNextEvent } from 'lightning/flowSupport'; import {getPicklistValuesByRecordType} from "lightning/uiObjectInfoApi"; -import { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime } from 'c/ers_datatableUtils'; +import { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime, removeRowFromCollection, replaceRowInCollection, findRowIndexById } from 'c/ers_datatableUtils'; // Translatable Custom Labels import CancelButton from '@salesforce/label/c.ers_CancelButton'; @@ -1806,9 +1806,9 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } // handle edited & remaining rows - this.savePreEditData = [...this.removeRowFromCollection(this.savePreEditData, keyValue)]; - this.outputEditedRows = [...this.removeRowFromCollection(this.outputEditedRows, keyValue)]; - this.outputRemainingRows = [...this.removeRowFromCollection(this.outputRemainingRows, keyValue)]; + this.savePreEditData = [...removeRowFromCollection(this, this.savePreEditData, keyValue)]; + this.outputEditedRows = [...removeRowFromCollection(this, this.outputEditedRows, keyValue)]; + this.outputRemainingRows = [...removeRowFromCollection(this, this.outputRemainingRows, keyValue)]; this.dispatchEvent(new FlowAttributeChangeEvent('outputEditedRows', this.outputEditedRows)); this.dispatchEvent(new FlowAttributeChangeEvent('numberOfRowsEdited', this.outputEditedRows.length)); this.dispatchEvent(new FlowAttributeChangeEvent('outputRemovedRows', this.outputRemovedRows)); @@ -1816,7 +1816,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.dispatchEvent(new FlowAttributeChangeEvent('outputRemainingRows', this.outputRemainingRows)); // remove record from collection - this.mydata = this.removeRowFromCollection(this._mydata, keyValue); + this.mydata = removeRowFromCollection(this, this._mydata, keyValue); if (this.mydata.length == 0) { // Last record was removed from the datatable // clear last selected row @@ -1844,38 +1844,6 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } - removeRowFromCollection(collection, keyValue) { - const index = this.findRowIndexById(collection, keyValue); - let result = collection; - if (index !== -1) { - result = collection.slice(0, index).concat(collection.slice(index+1)); - } - return result; - } - - replaceRowInCollection(original, updated, keyValue) { - // Replace the matching row in the original collection with the matching row from the updated collection - const oindex = this.findRowIndexById(original, keyValue); - const uindex = this.findRowIndexById(updated, keyValue); - let result = original; - if (oindex !== -1 && uindex !== -1) { - result = original.slice(0, oindex).concat(updated.slice(uindex,uindex+1)).concat(original.slice(oindex+1)); - } - return result; - } - - findRowIndexById(collection, id) { - let idx = -1; - collection.some((row, index) => { - if (row[this.keyField] === id) { - idx = index; - return true; - } - return false; - }); - return idx; - } - //handle change on combobox handleComboValueChange(event) { //Handle combobox value change separately if required @@ -2011,7 +1979,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 this.outputEditedRows = [...this.outputEditedRows,eitem]; // Add to output attribute collection } - this.outputRemainingRows = this.replaceRowInCollection(this.outputRemainingRows, this.outputEditedRows, eitem[this.keyField]); + this.outputRemainingRows = replaceRowInCollection(this, this.outputRemainingRows, this.outputEditedRows, eitem[this.keyField]); } return eitem; }); @@ -2063,21 +2031,21 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 } }) this._allSelectedRowIds.forEach(srowid => { - const found = this.findRowIndexById(this._paginatedData, srowid) != -1; + const found = findRowIndexById(this, this._paginatedData, srowid) != -1; if (!found) { - if (this.findRowIndexById(this.outputRemovedRows, srowid) == -1) { + if (findRowIndexById(this, this.outputRemovedRows, srowid) == -1) { otherSelectedRowIds.push(srowid); - index = this.findRowIndexById(this.savePreEditData, srowid); + index = findRowIndexById(this, this.savePreEditData, srowid); allSelectedRecs.push(this.savePreEditData[index]); } else { // Selected row was removed - index = this.findRowIndexById(allSelectedRecs, srowid); + index = findRowIndexById(this, allSelectedRecs, srowid); allSelectedRecs.splice(index, 1); } } else { - const stillSelected = this.findRowIndexById(currentSelectedRows, srowid) != -1; + const stillSelected = findRowIndexById(this, currentSelectedRows, srowid) != -1; if (stillSelected) { currentSelectedRowIds.push(srowid); - index = this.findRowIndexById(currentSelectedRows, srowid); + index = findRowIndexById(this, currentSelectedRows, srowid); allSelectedRecs.push(currentSelectedRows[index]); } } diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index 872137341..fc5354ffc 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -124,4 +124,36 @@ const convertTime = (that, dtValue) => { return timeString; } -export { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime }; \ No newline at end of file +const removeRowFromCollection = (that, collection, keyValue) => { + const index = findRowIndexById(that, collection, keyValue); + let result = collection; + if (index !== -1) { + result = collection.slice(0, index).concat(collection.slice(index+1)); + } + return result; +} + +const replaceRowInCollection = (that, original, updated, keyValue) => { + // Replace the matching row in the original collection with the matching row from the updated collection + const oindex = findRowIndexById(that, original, keyValue); + const uindex = findRowIndexById(that, updated, keyValue); + let result = original; + if (oindex !== -1 && uindex !== -1) { + result = original.slice(0, oindex).concat(updated.slice(uindex,uindex+1)).concat(original.slice(oindex+1)); + } + return result; +} + +const findRowIndexById = (that, collection, id) => { + let idx = -1; + collection.some((row, index) => { + if (row[that.keyField] === id) { + idx = index; + return true; + } + return false; + }); + return idx; +} + +export { getConstants, columnValue, removeSpaces, convertFormat, convertType, convertTime, removeRowFromCollection, replaceRowInCollection, findRowIndexById }; \ No newline at end of file From 4f0bb0fa609016a2dddb1c50492634d4777a8cd1 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 8 Jul 2024 16:07:10 -0400 Subject: [PATCH 33/38] Added removeColor attribute (red, green, black) --- .../force-app/main/default/lwc/datatable/datatable.js | 3 ++- .../main/default/lwc/datatable/datatable.js-meta.xml | 1 + .../ers_customLightningDatatableStyles.css | 11 ++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index d7eda7fa7..d60e6445c 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -104,6 +104,7 @@ export default class Datatable extends LightningElement { // Remove Row Action Attributes @api removeLabel = 'Remove Row'; @api removeIcon = 'utility:close'; + @api removeColor = 'remove-icon'; // Default red @api maxRemovedRows = 0; @api removeRowLeftOrRight = 'Right'; @api outputRemovedRows = []; @@ -1678,7 +1679,7 @@ if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 disabled: false }, cellAttributes: { - class: "remove-icon" + class: this.removeColor }, editable: false, actions: null, diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml index 1d3620b70..55bd3a3f2 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml @@ -154,6 +154,7 @@ + diff --git a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css index 9e5c93a30..daff841e0 100644 --- a/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css +++ b/flow_screen_components/datatable/force-app/main/default/staticresources/ers_customLightningDatatableStyles.css @@ -83,6 +83,15 @@ c-datatable c-ers_custom-lightning-datatable .dt-outer-container lightning-primi } /* v4.2.1 Remove Row Icon styling */ +:root{ + --remove-icon-color: red; +} .remove-icon { - --slds-c-icon-color-foreground: red; + --slds-c-icon-color-foreground: var(--remove-icon-color); +} +.remove-icon-green { + --slds-c-icon-color-foreground: green; } +.remove-icon-black { + --slds-c-icon-color-foreground: black; +} \ No newline at end of file From 7de33f44f5390303273c2949691edb13802e9a8a Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 8 Jul 2024 17:12:44 -0400 Subject: [PATCH 34/38] CPE - add new input values and new section header --- .../lwc/datatable/datatable.js-meta.xml | 2 +- .../ers_datatableCPE/ers_datatableCPE.html | 46 +++++++++++++++++++ .../lwc/ers_datatableCPE/ers_datatableCPE.js | 39 ++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml index 55bd3a3f2..0fa7ff69d 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml @@ -154,7 +154,7 @@ - + diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html index 201ba0953..3d168c335 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html @@ -391,6 +391,52 @@

Configure Columns

oncheckboxchanged={handleCheckboxChange} > + + + + +
+
+ +
+ +
+ + + +
+ +
+
+
+ Date: Mon, 8 Jul 2024 17:25:05 -0400 Subject: [PATCH 35/38] Add new banner color --- .../lwc/ers_datatableCPE/ers_datatableCPE.html | 4 ++-- .../lwc/ers_datatableCPE/ers_datatableCPE.js | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html index 3d168c335..a4cf31833 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html @@ -393,10 +393,10 @@

Configure Columns

diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js index 07f3bf443..9734c0c43 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js @@ -43,7 +43,9 @@ const COLORS = { green: '#659668', green_light: '#7E967F', red: '#966594', - red_light: '#967E95' + red_light: '#967E95', + orange: '#FFA45E', + orange_light: '#FEB97D' } export default class ers_datatableCPE extends LightningElement { @@ -56,9 +58,11 @@ export default class ers_datatableCPE extends LightningElement { _defaultBannerColor = COLORS.blue; _colorWizardOverride = COLORS.green; _colorAdvancedOverride = COLORS.red; + _colorRowActionsOverride = COLORS.orange; _defaultModalHeaderColor = COLORS.blue_light; _modalHeaderColorWizardOverride = COLORS.green_light; _modalHeaderColorAdvancedOverride = COLORS.red_light; + _modalHeaderColorRowActionsOverride = COLORS.orange_light; _inputVariables = []; _builderContext = []; @@ -180,6 +184,11 @@ export default class ers_datatableCPE extends LightningElement { return this._colorWizardOverride; } + @api + get colorRowActionsOverride() { + return this._colorRowActionsOverride; + } + @api get colorAdvancedOverride() { return this._colorAdvancedOverride; @@ -200,6 +209,11 @@ export default class ers_datatableCPE extends LightningElement { return this._modalHeaderColorAdvancedOverride; } + @api + get modalHeaderColorRowActionsOverride() { + return this._modalHeaderColorRowActionsOverride; + } + @api get showColumnAttributes() { return (this.showColumnAttributesToggle || !this.isSObjectInput || this.inputValues.isSerializedRecordData.value); From 77451e160f9fb5d4a59d2a100338cc5543507ad7 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 8 Jul 2024 17:42:43 -0400 Subject: [PATCH 36/38] Orange less bright --- .../main/default/lwc/ers_datatableCPE/ers_datatableCPE.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js index 9734c0c43..fb374d567 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js @@ -44,7 +44,7 @@ const COLORS = { green_light: '#7E967F', red: '#966594', red_light: '#967E95', - orange: '#FFA45E', + orange: '#E79556', orange_light: '#FEB97D' } From 8dc23ac1a19e88a6f266b9d71a7521ad2d1b28cd Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 9 Jul 2024 13:38:35 -0400 Subject: [PATCH 37/38] CPE finished --- .../main/default/lwc/datatable/datatable.js | 4 +- .../lwc/datatable/datatable.js-meta.xml | 6 +- .../ers_datatableCPE/ers_datatableCPE.html | 71 +++++++++++++----- .../lwc/ers_datatableCPE/ers_datatableCPE.js | 72 ++++++++++++++++--- .../ers_datatableUtils/ers_datatableUtils.js | 34 +++++---- 5 files changed, 141 insertions(+), 46 deletions(-) diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js index d60e6445c..5f40cba60 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js @@ -1377,7 +1377,7 @@ export default class Datatable extends LightningElement { let columnNumber = 0; let lufield = ''; - // if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 + if (!this.isConfigMode && this.isRemoveRowAction && this.removeRowLeftOrRight == "Left") this.addRemoveRowAction(); this.basicColumns.forEach(colDef => { @@ -1657,7 +1657,7 @@ export default class Datatable extends LightningElement { columnNumber += 1; }); -if (!this.isConfigMode) this.addRemoveRowAction(); //🚀 + if (!this.isConfigMode && this.isRemoveRowAction && this.removeRowLeftOrRight != "Left") this.addRemoveRowAction(); this.columns = this.cols; console.log(this.consoleLogPrefix+'this.columns',this.columns); diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml index 0fa7ff69d..46c436ba5 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml +++ b/flow_screen_components/datatable/force-app/main/default/lwc/datatable/datatable.js-meta.xml @@ -154,9 +154,9 @@ - - - + + + \ No newline at end of file diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html index a4cf31833..b9aff0c74 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.html @@ -151,7 +151,7 @@ + oniconselection={handleTableIcon}> @@ -413,27 +413,66 @@

Configure Columns

+ + + + + + + + + + + + -
- -
diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js index fb374d567..5edc67e09 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableCPE/ers_datatableCPE.js @@ -17,11 +17,15 @@ import {LightningElement, track, api} from 'lwc'; import getCPEReturnResults from '@salesforce/apex/ers_DatatableController.getCPEReturnResults'; import { getConstants } from 'c/ers_datatableUtils'; -const CONSTANTS = getConstants(); // From ers_datatableUtils : VERSION_NUMBER, MAXROWCOUNT, ROUNDWIDTH, MYDOMAIN, ISCOMMUNITY, WIZROWCOUNT, SHOW_DEBUG_INFO, DEBUG_INFO_PREFIX +const CONSTANTS = getConstants(); // From ers_datatableUtils const CB_TRUE = CONSTANTS.CB_TRUE; const CB_FALSE = CONSTANTS.CB_FALSE; const CB_PREFIX = CONSTANTS.CB_ATTRIB_PREFIX; const RECORDS_PER_PAGE = CONSTANTS.RECORDS_PER_PAGE; +const REMOVE_ROW_LABEL = CONSTANTS.REMOVE_ROW_LABEL; +const REMOVE_ROW_ICON = CONSTANTS.REMOVE_ROW_ICON; +const REMOVE_ROW_COLOR = CONSTANTS.REMOVE_ROW_COLOR; +const REMOVE_ROW_SIDE = CONSTANTS.REMOVE_ROW_SIDE; const SHOW_DEBUG_INFO = CONSTANTS.SHOW_DEBUG_INFO; const DEBUG_INFO_PREFIX = CONSTANTS.DEBUG_INFO_PREFIX; @@ -600,10 +604,10 @@ export default class ers_datatableCPE extends LightningElement { removeIcon: {value: null, valueDataType: null, isCollection: false, label: 'Remove Row Action Icon', helpText: 'This is the icon that will be used for the Remove Row Action Button (Default: utility:close)'}, removeColor: {value: null, valueDataType: null, isCollection: false, label: 'Remove Row Action Icon Color', - helpText: 'This is the color (red, green or black) for the icon that will be used for the Remove Row Action Button (Default: red)'}, - maxRemovedRows: {value: null, valueDataType: null, isCollection: false, label: 'Maximum number of rows that can be removed', + helpText: 'This is the color (Red, Green or Black) for the icon that will be used for the Remove Row Action Button (Default: Red)'}, + maxRemovedRows: {value: null, valueDataType: null, isCollection: false, label: 'Maximum # of rows that can be removed', helpText: 'Enter a number here if you want to restrict how many rows can be removed from the datatable (Default: 0 - no limit)'}, - removeRowLeftOrRight: {value: null, valueDataType: null, isCollection: false, label: 'Remove Row Action Button Location', + removeRowLeftOrRight: {value: null, valueDataType: null, isCollection: false, label: 'Remove Row Action Column Location', helpText: 'Specify if the Remove Row Action column should be on the Left or the Right (Default: Right)'}, }; @@ -678,11 +682,11 @@ export default class ers_datatableCPE extends LightningElement { {name: 'rowActions', attributes: [ {name: 'isRemoveRowAction'}, - {name: 'removeLabel'}, + {name: 'removeLabel'}, {name: 'removeIcon'}, - {name: 'removeColor'}, - {name: 'maxRemovedRows'}, + {name: 'removeColor'}, {name: 'removeRowLeftOrRight'}, + {name: 'maxRemovedRows'}, ] }, {name: 'advancedAttributes', @@ -722,6 +726,32 @@ export default class ers_datatableCPE extends LightningElement { } ] + removeColorOptions = [ + { + label: 'Red', + value: 'remove-icon' + }, + { + label: 'Green', + value: 'remove-icon-green' + }, + { + label: 'Black', + value: 'remove-icon-black' + } + ] + + removeLeftOrRightOptions = [ + { + label: 'Left', + value: 'Left' + }, + { + label: 'Right', + value: 'Right' + } + ] + // settings = { // attributeObjectName: 'objectName', // attributeFieldName: 'fieldName', @@ -860,6 +890,21 @@ export default class ers_datatableCPE extends LightningElement { if (this.inputValues.recordsPerPage.value == null) { this.inputValues.recordsPerPage.value = RECORDS_PER_PAGE.toString(); } + if (this.inputValues.removeLabel.value == null) { + this.inputValues.removeLabel.value = REMOVE_ROW_LABEL; + } + if (this.inputValues.removeIcon.value == null) { + this.inputValues.removeIcon.value = REMOVE_ROW_ICON; + } + if (this.inputValues.removeColor.value == null) { + this.inputValues.removeColor.value = REMOVE_ROW_COLOR; + } + if (this.inputValues.removeRowLeftOrRight.value == null) { + this.inputValues.removeRowLeftOrRight.value = REMOVE_ROW_SIDE; + } + if (this.inputValues.maxRemovedRows.value == null) { + this.inputValues.maxRemovedRows.value = 0; + } } handleBuildHelpInfo() { @@ -1087,7 +1132,7 @@ export default class ers_datatableCPE extends LightningElement { let changedAttribute = event.target.name.replace(defaults.inputAttributePrefix, ''); let newType = event.detail.newValueDataType; let newValue = event.detail.newValue; - if ((changedAttribute == 'maxNumberOfRows' || changedAttribute == 'recordsPerPage') && newType != 'reference') { + if ((changedAttribute == 'maxNumberOfRows' || changedAttribute == 'maxRemovedRows' || changedAttribute == 'recordsPerPage') && newType != 'reference') { newType = 'Number'; } this.dispatchFlowValueChangeEvent(changedAttribute, newValue, newType); @@ -1108,8 +1153,15 @@ export default class ers_datatableCPE extends LightningElement { } } - handlePickIcon(event) { - let changedAttribute = 'tableIcon'; + handleTableIcon(event) { + this.setIconAttribute('tableIcon', event); + } + + handleRemoveIcon(event) { + this.setIconAttribute('removeIcon', event); + } + + setIconAttribute(changedAttribute, event) { this.inputValues[changedAttribute].value = event.detail; this.dispatchFlowValueChangeEvent(changedAttribute, event.detail, 'String'); } diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index fc5354ffc..aabe50eba 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -33,21 +33,25 @@ console.log("DATATABLE: isCommunity, isFlowBuilder:", isCommunity, isFlowBuilder const getConstants = () => { return { - VERSION_NUMBER : '4.2.1', // Current Source Code Version # - MAXROWCOUNT : 2000, // Limit the total number of records to be handled by this component - ROUNDWIDTH : 5, // Used to round off the column widths during Config Mode to nearest value - WIZROWCOUNT : 6, // Number of records to display in the Column Wizard datatable - MYDOMAIN : myDomain, // Used for building links for lookup fields - ISCOMMUNITY : isCommunity, // Used for building links for lookup fields - ISFLOWBUILDER : isFlowBuilder, // Used for building links for lookup fields - CB_TRUE : 'CB_TRUE', // Used with fsc_flowCheckbox component - CB_FALSE : 'CB_FALSE', // Used with fsc_flowCheckbox component - CB_ATTRIB_PREFIX : 'cb_', // Used with fsc_flowCheckbox component - MIN_SEARCH_TERM_SIZE : 2, // Set the minimum number of characters required to start searching - SEARCH_WAIT_TIME : 300, // Set the delay to start searching while user is typing a search term - RECORDS_PER_PAGE : 10, // Default number of records per page for pagination - SHOW_DEBUG_INFO : true, // Set to true to show sensitive debug info in the console and debug logs - DEBUG_INFO_PREFIX : 'DATATABLE: ' // Prefix to be used for debug info in the console + VERSION_NUMBER : '4.2.1', // Current Source Code Version # + MAXROWCOUNT : 2000, // Limit the total number of records to be handled by this component + ROUNDWIDTH : 5, // Used to round off the column widths during Config Mode to nearest value + WIZROWCOUNT : 6, // Number of records to display in the Column Wizard datatable + MYDOMAIN : myDomain, // Used for building links for lookup fields + ISCOMMUNITY : isCommunity, // Used for building links for lookup fields + ISFLOWBUILDER : isFlowBuilder, // Used for building links for lookup fields + CB_TRUE : 'CB_TRUE', // Used with fsc_flowCheckbox component + CB_FALSE : 'CB_FALSE', // Used with fsc_flowCheckbox component + CB_ATTRIB_PREFIX : 'cb_', // Used with fsc_flowCheckbox component + MIN_SEARCH_TERM_SIZE : 2, // Set the minimum number of characters required to start searching + SEARCH_WAIT_TIME : 300, // Set the delay to start searching while user is typing a search term + RECORDS_PER_PAGE : 10, // Default number of records per page for pagination + REMOVE_ROW_LABEL : 'Remove Row', // Default label for the Remove Row button + REMOVE_ROW_ICON : 'utility:close', // Default Icon for the Remove Row button + REMOVE_ROW_COLOR : 'remove-icon', // Default Color for the Remove Row button + REMOVE_ROW_SIDE : 'Right', // Default Side for the Remove Row button + SHOW_DEBUG_INFO : true, // Set to true to show sensitive debug info in the console and debug logs + DEBUG_INFO_PREFIX : 'DATATABLE: ' // Prefix to be used for debug info in the console } } From fdbe73d653ef5224797cf165fff85ee51eb1029d Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 9 Jul 2024 17:01:48 -0400 Subject: [PATCH 38/38] v4.2.1 Package --- flow_screen_components/datatable/README.md | 11 ++++++----- .../lwc/ers_datatableUtils/ers_datatableUtils.js | 2 +- flow_screen_components/datatable/sfdx-project.json | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/flow_screen_components/datatable/README.md b/flow_screen_components/datatable/README.md index 50c337e70..48d201e13 100644 --- a/flow_screen_components/datatable/README.md +++ b/flow_screen_components/datatable/README.md @@ -34,7 +34,7 @@ Additional components packaged with this LWC: **Documentation:** https://unofficialsf.com/datatable-lightning-web-component-for-flow-screens-2/ **Created by:** Eric Smith -**Date:** 2019 - 2023 +**Date:** 2019 - 2024 LinkedIn: https://www.linkedin.com/in/ericrsmith2 Salesforce: https://trailblazer.me/id/ericsmith @@ -51,8 +51,8 @@ https://unofficialsf.com/flow-action-and-screen-component-basepacks/ --- **Install Datatable** -[Version 4.2.0 (Production or Developer)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5G000004XZlHQAW) -[Version 4.2.0 (Sandbox)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5G000004XZlHQAW) +[Version 4.2.1 (Production or Developer)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5G000004fz7wQAA) +[Version 4.2.1 (Sandbox)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5G000004fz7wQAA) --- **Starting with the Winter '21 Release, Salesforce requires that a User's Profile or Permission Set is given specific permission to access any @AuraEnabled Apex Method.** @@ -72,10 +72,11 @@ A Permission Set (**USF Flow Screen Component - Datatable**) is included with th --- # Release Notes -## 07/xx/24 - Eric Smith - Version 4.2.1 +## 07/09/24 - Eric Smith - Version 4.2.1 **Updates:** - New Feature: Add a Remove Row action as the first or last column in a Datatable. -- New outputs include a collection and a count of the removed rows. +- New outputs include a collection and a count of the removed rows. +- You can specify the icon and color for the action button. - You can specify the maximum number of rows that can be removed. - Selected Rows are now persistent when Paginating, Searching, Filtering, Sorting, and Removing! - A new output attribute (outputRemainingRows) will provide all records passed into the table with all edits made to those records, less all records (if any) that were removed diff --git a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js index aabe50eba..7b2504bf0 100644 --- a/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js +++ b/flow_screen_components/datatable/force-app/main/default/lwc/ers_datatableUtils/ers_datatableUtils.js @@ -50,7 +50,7 @@ const getConstants = () => { REMOVE_ROW_ICON : 'utility:close', // Default Icon for the Remove Row button REMOVE_ROW_COLOR : 'remove-icon', // Default Color for the Remove Row button REMOVE_ROW_SIDE : 'Right', // Default Side for the Remove Row button - SHOW_DEBUG_INFO : true, // Set to true to show sensitive debug info in the console and debug logs + SHOW_DEBUG_INFO : false, // Set to true to show sensitive debug info in the console and debug logs DEBUG_INFO_PREFIX : 'DATATABLE: ' // Prefix to be used for debug info in the console } } diff --git a/flow_screen_components/datatable/sfdx-project.json b/flow_screen_components/datatable/sfdx-project.json index 41acc7e35..d23cc608d 100644 --- a/flow_screen_components/datatable/sfdx-project.json +++ b/flow_screen_components/datatable/sfdx-project.json @@ -91,6 +91,7 @@ "datatable@4.1.4": "04t5G000004J7MxQAK", "datatable@4.1.6": "04t5G000004XZk9QAG", "datatable@4.1.7": "04t5G000004XZknQAG", - "datatable@4.2.0": "04t5G000004XZlHQAW" + "datatable@4.2.0": "04t5G000004XZlHQAW", + "datatable@4.2.1": "04t5G000004fz7wQAA" } } \ No newline at end of file