As Adrian pointed out, it has been established that we can do this from Apex via the Metadata API. That makes it quite a lot of work, though.
Possible to update NamedCredential from Apex?
For my purposes, this is a temporary measure while the external system sorts out doing OAuth 2.0 server flow. So, I query the ExternalDataUserAuth
table:
List<ExternalDataUserAuth> existingAuths = [
SELECT Id
FROM ExternalDataUserAuth
WHERE ExternalDataSource.Name = :systemName
AND UserId = :UserInfo.getUserId()
];
If there is one, I pop up a window like this:
window.open('/' + component.get('v.externalDataUserAuthId') + '/e', 'Enter Login Details', 'width=900,height=600');
If there is no existing ExternalDataUserAuth
record, you can just use ExternalDataUserAuth.getSObjectType().getDescribe().getKeyPrefix()
instead of the Id to create one.
It takes a bit of user-training to explain this (and we give them information before popping up the window), but this seems like a good easy solution for now.
I implemented a RTE component by using dijit/Editor inside a Visualforce page. I then wrapped that Visualforce page inside a Lightning Component by using an iFrame, so that I can easily use it anywhere I wanted.
NOTE: You will have to implement communication between this Visualforce page and the Lightning Component - there's a nice blog post that solves this problem.
Below is the code from my Visualforce page without the Lightning Component <-> VF Page communication part. This should be enough to get you started quickly:
<apex:page standardController="EmailMessage"
applyBodyTag="false" showHeader="false" sidebar="false" standardStylesheets="false">
<!-- loading required DOJO resources -->
<style type="text/css">
@import "//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css";
</style>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true, parseOnLoad: false"> </script>
<body class="claro" style="margin: 0px;">
<!-- dijit RTE -->
<div id="dijit-rich-text-editor"
data-dojo-type="dijit/Editor"
data-dojo-props="extraPlugins:['foreColor','hiliteColor','|','createLink']">
</div>
<!-- Email Message's HtmlBody -->
<div id="emailMessage-htmlBody" style="display: none" >
<apex:outputText value="{!EmailMessage.HtmlBody}" escape="false"/>
</div>
</body>
<!-- initializing the editor -->
<script>
var myEditor = undefined;
require([
"dojo/parser",
"dijit/registry",
"dijit/Editor",
"dijit/_editor/plugins/TextColor",
"dijit/_editor/plugins/LinkDialog",
"dijit/_editor/plugins/FullScreen"
], function(parser, registry, editor) {
parser.parse();
myEditor = registry.byId("dijit-rich-text-editor");
myEditor.setValue(document.getElementById('emailMessage-htmlBody').innerHTML);
});
</script>
</apex:page>
I needed this component to provide the ability to edit EmailMessages
, so that's why it's using EmailMessage
standard controller, but you can easily change that to support something else. Also, the reason I used dijit/Editor was because it messed the least with the HTML that was generated by the email templates.
It has the functionality to support adding links, but for uploading attachments I think you'll need to implement a separate component that you'll use in conjunction with RTE (which shouldn't be that hard).
P.S. As I said, I used dijit/Editor for my own reasons, however, you can probably use a very similar approach to implement any other RTE library that is out there. For example, Salesforce's new lightning-input-rich-text
LWC is using Quill.
Best Answer
We have implemented this using below code and it is working on prod org as well.