I have Created one custom component which can be used as a quick action and it enables you to create the note related to the current record.
Look what I have done:-
Here is my code:-
<--component-->
<aura:component controller="CreateNoteRecord"
implements="lightning:actionOverride,force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickActionWithoutHeader"
access="global" >
<!-- Define Attribute-->
<aura:attribute name="note" type="ContentNote" default="{'sobjectType': 'ContentNote','Title': '','Content': ''}"/>
<div class="slds-m-around--xx-large">
<div role="dialog" tabindex="-1" aria-labelledby="header99" class="slds-modal slds-fade-in-open ">
<div class="slds-modal__container">
<div class="slds-modal__header">
<button class="slds-button slds-modal__close slds-button--icon-inverse" title="Close" onclick="{!c.closeModel}">
X
<span class="slds-assistive-text">Close</span>
</button>
<h2 id="header99" class="slds-text-heading--medium">Creating Custom Note</h2>
</div>
<div class="slds-modal__content slds-p-around--medium">
<div class="slds-page-header">
<div class="slds-media">
<div class="slds-media__body">
<center>
<h1 class="slds-page-header__title slds-truncate slds-align-middle" title="Requests User Guides">New Note</h1>
</center>
</div>
</div>
</div>
<b>Title:</b>
<br/>
<ui:inputText class="form-control" value="{!v.note.Title}"/>
<br/>
<b>Content:</b>
<br/>
<lightning:inputRichText value="{!v.note.Content}" placeholder="Type something interesting"/>
<br/>
<div class="slds-modal__footer">
<div class="col-md-4 text-center">
<ui:button class="btn btn-default" press="{!c.create}">Create</ui:button>
<ui:button class="btn btn-default" press="{!c.closeModel}">Cancel</ui:button>
</div>
</div>
</div>
</div>
</div>
</div>
</aura:component>
JavaScript Controller:-
({
create : function(component, event, helper) {
//getting the candidate information
var candidate = component.get("v.note");
//Calling the Apex Function
var action = component.get("c.createRecord");
//Setting the Apex Parameter
action.setParams({
nt : candidate,
PrentId : component.get("v.recordId")
});
//Setting the Callback
action.setCallback(this,function(a){
//get the response state
var state = a.getState();
//check if result is successfull
if(state == "SUCCESS"){
//Reset Form
var newCandidate = {'sobjectType': 'ContentNote',
'Title': '',
'Content': ''
};
//resetting the Values in the form
component.set("v.note",newCandidate);
} else if(state == "ERROR"){
alert('Error in calling server side action');
}
});
var navEvt = $A.get("e.force:navigateToSObject");
navEvt.setParams({
"recordId": component.get("v.recordId"),
"slideDevName": "detail"
});
navEvt.fire();
$A.get('e.force:refreshView').fire();
//adds the server-side action to the queue
$A.enqueueAction(action);
},
closeModel : function (component, event, helper) {
var navEvt = $A.get("e.force:navigateToSObject");
navEvt.setParams({
"recordId": component.get("v.recordId"),
"slideDevName": "detail"
});
navEvt.fire();
}
})
css:-
.THIS .slds-modal__container{
max-width: 50rem !important;
width:100% !important;
}
APEX Controller:-
public with sharing class CreateNoteRecord {
@AuraEnabled
public static void createRecord (ContentNote nt, id PrentId){
try{
if(nt != null){
insert nt;
ContentDocument cd=[select id from ContentDocument where id=:nt.Id];
ContentDocumentLink cdl=new ContentDocumentLink();
cdl.ContentDocumentId=cd.id;
cdl.LinkedEntityId=PrentId;
cdl.ShareType='V';
cdl.Visibility='AllUsers';
insert cdl;
}
} catch (Exception ex){
}
}
}
Once the note is getting created, I am inserting the ContentDocumentLink object to link the current record to this note.
Hope it helps you.
The key to this is the ContentDocumentLink
record that is a junction between the Object (Account
in your case) and the ContentDocument
(which is the parent of ContentVersion
). You have to reconstruct this.
Example:
Source org
ContentDocumentLink.LinkedEntityId = someAccountId in source org
ContentDocumentLink.ContentDocumentId = some ContentDocument parent of
one or more versions of a ContentVersion
Target org (you have to build this)
ContentDocumentLink.LinkedEntityId = someAccountId in target org
ContentDocumentLink.ContentDocumentId = some ContentDocument parent of
imported ContentVersion
When I have done this in the past (and it was an unpleasant experience requiring a lot of concentration), I ended up using a spreadsheet tool to do the correlation. Others have used MySQL or MS Access to keep track of the correlation.
Remember that the Ids of the source org will never be the same as the Ids in the target org. If you transferred accounts and opportunities already, you know this by now. You would have had to do an xref prior to Data Loading the Opportunities to make sure that the uploaded Oppos point to the newly uploaded Accounts (and the right Accounts)
Doing the Files and Notes is no different except the schema is more complicated
Best Answer
To help folks migrate from Classic Notes (Note) to Enhanced Notes (ContentNote) I've developed open source project on GitHub:
https://github.com/DouglasCAyers/sfdc-convert-notes-to-chatter-notes
And if you're converting notes you might also want to convert Classic Attachments (Attachment) to Salesforce Files (ContentVersion):
https://github.com/DouglasCAyers/sfdc-convert-attachments-to-chatter-files
The conversion is done entirely in Apex and handles sharing via ContentDocumentLink the new note/file (ContentNote/ContentVersion) with the original parent record.