I am using custom permissions to control when my lightning component appears on a given flexipage record page. The intent here is to make it easy for an admin to use a UI that I made to toggle visibility of the components by toggling this permission into and out of a permission set that users of my managed package already were assigned earlier.
Here is the XML for the lead record page (MyCustomLeadRecordPage.flexipage-meta.xml
) for context:
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>hideChatterActions</name>
<value>false</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>numVisibleActions</name>
<value>3</value>
</componentInstanceProperties>
<componentName>force:highlightsPanel</componentName>
</componentInstances>
<mode>Replace</mode>
<name>header</name>
<type>Region</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>hideUpdateButton</name>
<value>false</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>variant</name>
<value>linear</value>
</componentInstanceProperties>
<componentName>runtime_sales_lead:pathAssistant</componentName>
</componentInstances>
<mode>Replace</mode>
<name>subheader</name>
<type>Region</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentName>runtime_sales_activities:activityPanel</componentName>
</componentInstances>
<mode>Replace</mode>
<name>activityTabContent</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentName>force:detailPanel</componentName>
</componentInstances>
<mode>Replace</mode>
<name>detailTabContent</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentName>forceChatter:recordFeedContainer</componentName>
</componentInstances>
<mode>Replace</mode>
<name>feedTabContent</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>active</name>
<value>true</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>body</name>
<value>activityTabContent</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>title</name>
<value>Standard.Tab.activity</value>
</componentInstanceProperties>
<componentName>flexipage:tab</componentName>
</componentInstances>
<componentInstances>
<componentInstanceProperties>
<name>body</name>
<value>detailTabContent</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>title</name>
<value>Standard.Tab.detail</value>
</componentInstanceProperties>
<componentName>flexipage:tab</componentName>
</componentInstances>
<componentInstances>
<componentInstanceProperties>
<name>body</name>
<value>feedTabContent</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>title</name>
<value>Standard.Tab.collaborate</value>
</componentInstanceProperties>
<componentName>flexipage:tab</componentName>
</componentInstances>
<componentInstances>
<componentInstanceProperties>
<name>body</name>
<value>newsTabContent</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>title</name>
<value>Standard.Tab.news</value>
</componentInstanceProperties>
<componentName>flexipage:tab</componentName>
</componentInstances>
<mode>Replace</mode>
<name>tabs</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>tabs</name>
<value>tabs</value>
</componentInstanceProperties>
<componentName>flexipage:tabset</componentName>
</componentInstances>
<mode>Replace</mode>
<name>main</name>
<type>Region</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>displayOption</name>
<value>BOTH</value>
</componentInstanceProperties>
<componentName>runtime_sales_merge:mergeCandidatesPreviewCard</componentName>
</componentInstances>
<componentInstances>
<componentInstanceProperties>
<name>relatedListComponentOverride</name>
<value>NONE</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>rowsToDisplay</name>
<value>10</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>showActionBar</name>
<value>true</value>
</componentInstanceProperties>
<componentName>force:relatedListContainer</componentName>
</componentInstances>
<mode>Replace</mode>
<name>relatedListTabContent</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentInstanceProperties>
<name>active</name>
<value>true</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>body</name>
<value>relatedListTabContent</value>
</componentInstanceProperties>
<componentInstanceProperties>
<name>title</name>
<value>Standard.Tab.relatedLists</value>
</componentInstanceProperties>
<componentName>flexipage:tab</componentName>
</componentInstances>
<mode>Replace</mode>
<name>sidebartabs</name>
<type>Facet</type>
</flexiPageRegions>
<flexiPageRegions>
<componentInstances>
<componentName>CustomComponent1</componentName>
<visibilityRule>
<criteria>
<leftValue>{!$Permission.CustomPermission.Lead_Record_Install_App}</leftValue>
<operator>EQUAL</operator>
<rightValue>true</rightValue>
</criteria>
</visibilityRule>
</componentInstances>
<componentInstances>
<componentName>CustomComponent2</componentName>
<visibilityRule>
<criteria>
<leftValue>{!$Permission.CustomPermission.Lead_Record_Responses}</leftValue>
<operator>EQUAL</operator>
<rightValue>true</rightValue>
</criteria>
</visibilityRule>
</componentInstances>
<componentInstances>
<componentInstanceProperties>
<name>tabs</name>
<value>sidebartabs</value>
</componentInstanceProperties>
<componentName>flexipage:tabset</componentName>
</componentInstances>
<mode>Replace</mode>
<name>sidebar</name>
<type>Region</type>
</flexiPageRegions>
<masterLabel>Lead Record Page</masterLabel>
<parentFlexiPage>runtime_sales_lead__Lead_rec_L</parentFlexiPage>
<sobjectType>Lead</sobjectType>
<template>
<name>flexipage:recordHomeWithSubheaderTemplateDesktop</name>
</template>
<type>RecordPage</type>
</FlexiPage>
That flexipage XML used to work perfectly before I added my namespace into my scratch org (it used to be blank):
sfdx-project.json
included for context: (namespace used to be "")
{
"packageDirectories": [{
"path": "force-app/main",
"default": true
},
{
"path": "force-app/main/crud-fls",
"default": false
}],
"namespace": "mynamespace",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "46.0"
}
I added in the namespace to my scratch orgs so that I could appropriately use that namespace in custom labels and translations and I would rather not switch it back if I can help it.
Does anyone know why visibility based on custom permissions broke here so that the record page thinks that the user doesn't have the custom permissions, even though the permissions are present? The visibility based on custom permissions still works correctly on the flexipages I made that aren't an override for record pages, oddly enough.
And as a related followup question: what do I need to do to get my record flexipage to go back to working with my custom permissions now that namespacing is turned on?
{!$Permission.CustomPermission.mynamespace__Lead_Record_Install_App}
and it still fails.