From c859d7fde3ab79427bf00796138e2e6f14f32ecc Mon Sep 17 00:00:00 2001 From: tschug Date: Wed, 21 Jan 2026 19:13:10 -0500 Subject: [PATCH 1/3] Added ldsUtils fix(indicatorBundle): improve error rendering and message clarity - Wrap error content in lightning-card body to align with SLDS structure and spacing - Replace JSON.stringify with reduceErrors for user-friendly error messages - Correct target message to use resolved targetIdValue and objectApiName - **This resolves issue with grandparent fields** - Keeps illustration rendering when applicable This enhances UX, provides clearer errors, and fixes inaccurate message content. --- .../lwc/indicatorBundle/indicatorBundle.html | 22 ++--- .../lwc/indicatorBundle/indicatorBundle.js | 7 +- .../main/default/lwc/ldsUtils/ldsUtils.js | 81 +++++++++++++++++++ .../default/lwc/ldsUtils/ldsUtils.js-meta.xml | 5 ++ 4 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 force-app/main/default/lwc/ldsUtils/ldsUtils.js create mode 100644 force-app/main/default/lwc/ldsUtils/ldsUtils.js-meta.xml diff --git a/force-app/main/default/lwc/indicatorBundle/indicatorBundle.html b/force-app/main/default/lwc/indicatorBundle/indicatorBundle.html index b892cc9..2c2a259 100644 --- a/force-app/main/default/lwc/indicatorBundle/indicatorBundle.html +++ b/force-app/main/default/lwc/indicatorBundle/indicatorBundle.html @@ -104,16 +104,18 @@

diff --git a/force-app/main/default/lwc/indicatorBundle/indicatorBundle.js b/force-app/main/default/lwc/indicatorBundle/indicatorBundle.js index 0872d54..ecab546 100644 --- a/force-app/main/default/lwc/indicatorBundle/indicatorBundle.js +++ b/force-app/main/default/lwc/indicatorBundle/indicatorBundle.js @@ -3,6 +3,7 @@ import { getRecord, getFieldValue } from 'lightning/uiRecordApi'; import { getObjectInfo } from 'lightning/uiObjectInfoApi'; import { refreshApex } from '@salesforce/apex'; import KeyModal from 'c/indicatorBundleKey'; +import { reduceErrors } from 'c/ldsUtils'; import hasManagePermission from '@salesforce/customPermission/Manage_Indicator_Key'; import getIndicatorConfig from '@salesforce/apex/IndicatorController.getIndicatorBundle'; @@ -89,8 +90,8 @@ export default class IndicatorBundle extends LightningElement { imageName: 'custom:setup' }; } else { - this.targetMessage = 'This Indicator Bundle displays indicators based on the record id (' + data.fields[this.mappedField].value + ') in the mapped field \"' + this.mappedField + '\" from the ' + data.apiName + ' object.'; this.targetIdValue = getFieldValue(data, this.targetIdField); + this.targetMessage = 'This Indicator Bundle displays indicators based on the record id (' + this.targetIdValue + ') in the mapped field \"' + this.mappedField + '\" from the ' + this.objectApiName + ' object.'; this.showIllustration=false; this.illustration = {}; } @@ -208,7 +209,7 @@ export default class IndicatorBundle extends LightningElement { this.bundle = undefined; this.bundleActive = false; this.errorOccurred = true; - this.errorMessage = JSON.stringify(error); + this.errorMessage = reduceErrors(error).join(', '); //JSON.stringify(error); } } @@ -420,7 +421,7 @@ export default class IndicatorBundle extends LightningElement { // console.log('FieldValue => ', JSON.stringify(this.results)); // Retain for debug purposes } else if (error) { console.log('Error!'); - this.errorMessage = JSON.stringify(error); + this.errorMessage = reduceErrors(error).join(', ');//JSON.stringify(error); this.errorOccurred = true; } diff --git a/force-app/main/default/lwc/ldsUtils/ldsUtils.js b/force-app/main/default/lwc/ldsUtils/ldsUtils.js new file mode 100644 index 0000000..5d2fcc5 --- /dev/null +++ b/force-app/main/default/lwc/ldsUtils/ldsUtils.js @@ -0,0 +1,81 @@ +/** + * Reduces one or more LDS errors into a string[] of error messages. + * @param {FetchResponse|FetchResponse[]} errors + * @return {String[]} Error messages + */ +export function reduceErrors(errors) { + if (!Array.isArray(errors)) { + errors = [errors]; + } + + return ( + errors + // Remove null/undefined items + .filter((error) => !!error) + // Extract an error message + .map((error) => { + // UI API read errors + if (Array.isArray(error.body)) { + return error.body.map((e) => e.message); + } + // Page level errors + else if ( + error?.body?.pageErrors && + error.body.pageErrors.length > 0 + ) { + return error.body.pageErrors.map((e) => e.message); + } + // Field level errors + else if ( + error?.body?.fieldErrors && + Object.keys(error.body.fieldErrors).length > 0 + ) { + const fieldErrors = []; + Object.values(error.body.fieldErrors).forEach( + (errorArray) => { + fieldErrors.push( + ...errorArray.map((e) => e.message) + ); + } + ); + return fieldErrors; + } + // UI API DML page level errors + else if ( + error?.body?.output?.errors && + error.body.output.errors.length > 0 + ) { + return error.body.output.errors.map((e) => e.message); + } + // UI API DML field level errors + else if ( + error?.body?.output?.fieldErrors && + Object.keys(error.body.output.fieldErrors).length > 0 + ) { + const fieldErrors = []; + Object.values(error.body.output.fieldErrors).forEach( + (errorArray) => { + fieldErrors.push( + ...errorArray.map((e) => e.message) + ); + } + ); + return fieldErrors; + } + // UI API DML, Apex and network errors + else if (error.body && typeof error.body.message === 'string') { + return error.body.message; + } + // JS errors + else if (typeof error.message === 'string') { + return error.message; + } + // Unknown error shape so try HTTP status text + return error.statusText; + }) + // Flatten + .reduce((prev, curr) => prev.concat(curr), []) + // Remove empty strings + .filter((message) => !!message) + ); +} \ No newline at end of file diff --git a/force-app/main/default/lwc/ldsUtils/ldsUtils.js-meta.xml b/force-app/main/default/lwc/ldsUtils/ldsUtils.js-meta.xml new file mode 100644 index 0000000..5ecb591 --- /dev/null +++ b/force-app/main/default/lwc/ldsUtils/ldsUtils.js-meta.xml @@ -0,0 +1,5 @@ + + + 65.0 + false + \ No newline at end of file From fc3a26371a885a3fd4fcc5819463a921a10d2270 Mon Sep 17 00:00:00 2001 From: tschug Date: Wed, 21 Jan 2026 19:21:55 -0500 Subject: [PATCH 2/3] docs(mdt): clarify Priority help text for Indicator Item Extension - Update inlineHelpText on Priority__c to clearly explain rule selection - Specifies behavior when multiple extension rules apply and "Display Multiple" is false - Improves admin/user understanding to reduce configuration confusion --- .../fields/Priority__c.field-meta.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/force-app/main/default/objects/Indicator_Item_Extension__mdt/fields/Priority__c.field-meta.xml b/force-app/main/default/objects/Indicator_Item_Extension__mdt/fields/Priority__c.field-meta.xml index 289cc8b..26d2164 100644 --- a/force-app/main/default/objects/Indicator_Item_Extension__mdt/fields/Priority__c.field-meta.xml +++ b/force-app/main/default/objects/Indicator_Item_Extension__mdt/fields/Priority__c.field-meta.xml @@ -3,7 +3,7 @@ Priority__c false SubscriberControlled - Priority of this rule. If an field's value first multiple extension rules, the lowest priority will be used. + Priority of this rule. If multiple extension rules apply and Indicator Item's "Display Multiple" is set to false, then the extension with the lowest priority will be used. 4 false From 532cdf0dbb5ee576ab51acd67150b4b161919c3d Mon Sep 17 00:00:00 2001 From: tschug Date: Wed, 21 Jan 2026 21:30:56 -0500 Subject: [PATCH 3/3] feat(cci): add perm set assignment; reorder flows - Insert assign_permission_sets (Indicators_Setup_Access) into config_dev and config_demo - Reorder flow steps to generate sample data before deploying indicators for smoother setup --- cumulusci.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cumulusci.yml b/cumulusci.yml index 85f89ff..dc0238d 100644 --- a/cumulusci.yml +++ b/cumulusci.yml @@ -115,26 +115,33 @@ flows: config_dev: steps: 3: - task: generate_accounts_and_contacts + task: assign_permission_sets + options: + api_names: Indicators_Setup_Access 4: - flow: sample_inds + task: generate_accounts_and_contacts 5: + flow: sample_inds + 6: task: deploy_sample_indicators_objects + config_demo: steps: 1: flow: install_prod 2: - flow: sample_inds + task: assign_permission_sets + options: + api_names: Indicators_Setup_Access 3: - task: deploy_sample_indicators_objects + task: generate_accounts_and_contacts 4: - task: deploy_sample_indicators_layouts + flow: sample_inds 5: - task: deploy_training_indicators + task: deploy_sample_indicators_objects 6: - task: generate_accounts_and_contacts + task: deploy_training_indicators plans: install: