Motivation behind this
Today, I have received a requirement to build a suggested cases or similar cases functionality which will help Business to refer during resolving a case. Since this functionality is not by-default available as part of Case Management so tried to build from my own.
There are few approaches I have followed which might be helpful to learn and explore to build this simple component. For example, why should I use SOSL query instead of SOQL.
Let's get started.
Use Case
Business wants a have a functionality to show suggested cases or similar cases in the case detail page. This will help to refer previously closed cases and to resolve current cases quickly.
It will have following functionality:
- Based on current case subject, system will pull all the occurrences of matching keywords from any fields from Case object.
- It will display case records which has been created recently and closed.
- It might filter based on other criteria like, Case Types
- In the datatable, clicking on the Case Number (URL), it will open the case record.
Possible End Result
The component will look like as highlighted.
Solution Approach
Based on the above diagram, need to create component which will show data in datatable.
suggestedCases.html
1 2 3 4 5 6 7 8 9 10 11 12 | <template> <lightning-card> <p class="slds-p-horizontal_large">Suggested Cases</p> <div style="height: 200px;"> <lightning-datatable key-field="Id" data={records} columns={columns}> </lightning-datatable> </div> </lightning-card> </template> |
suggestedCases.js
This js controller is most important for implementing this functionality and some of the key points have been highlighted below:
- Defining a column as Case Number which will act as hyperlink. Refer type and typeAttributes
{ label: 'Case Number', fieldName: 'URLField', fixedWidth: 120, type: 'url', typeAttributes: { label: { fieldName: 'CaseNumber' }, target: '_blank' }, sortable: true }
- Use recordId with @api to capture record Id of the Case Detail Record.
- Since the Case Number column to be created and not readily available like that formatted way so elements to be created on the fly and to be pushed into the records array.
Entire code is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import { LightningElement, track, wire, api} from 'lwc'; import getSuggestedCases from '@salesforce/apex/CaseController.getSuggestedCases'; //define datatable columns with customized Case Number URL column const columns = [ { label: 'Case Number', fieldName: 'URLField', fixedWidth: 120, type: 'url', typeAttributes: { label: { fieldName: 'CaseNumber' }, target: '_blank' }, sortable: true }, { label: 'Subject', fieldName: 'Subject' } ]; export default class SuggestedCases extends LightningElement { @api recordId; //it will be passed from the screen @track records; //datatable records @track columns; //datatable columns //retrieve suggested cases based on case recordId @wire(getSuggestedCases,{caseId: '$recordId'}) wiredCases({ error, data }) { if (data) { let URLField; //retrieve Id, create URL with Id and push it into the array this.records = data.map(item=>{ URLField = '/lightning/r/Case/' + item.Id + '/view'; return {...item,URLField}; }); this.columns = columns; this.error = undefined; } else if (error) { this.error = error; this.records = undefined; } } } |
CaseController.cls
In the class, as keyword occurrences need to be search on multiple fields, so SOSL (Salesforce Object Search Language) query has been used.
Since, it needs to be searched on Case Description field which is LongTextArea so SOQL search is not possible, it cannot be used in WHERE condition.
As it should include all the keywords for search taking from Case's subject, so all the keywords to be separated by OR operator (this is tricky).
Rest of the code is simple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public with sharing class CaseController { @AuraEnabled (cacheable=true) public static List<Case> getSuggestedCases(String caseId){ List<Case> lstCase = new List<Case>(); //retrieve case subject of existing case Case caseObj = [SELECT Subject, Type FROM Case WHERE Id=:caseId]; //since all the keywords need to searched so, need to put 'OR' condition between the keywords List<String> strList = caseObj.Subject.split(' '); String strSearch = String.join(strList, '\' OR \'') + '*'; System.debug('strSearch=' + strSearch); //strSearch=Seeking' OR 'guidance' OR 'on' OR 'electrical' OR 'wiring' OR 'installation' OR 'for' OR 'GC5060* //retrieve cases which are already closed, created recently and eliminating current case List<List<SObject>> searchList = [FIND :strSearch IN ALL FIELDS RETURNING Case(Id,CaseNumber, Subject WHERE Id!=:caseId AND Status = 'Closed' AND Type =:caseObj.Type ORDER BY CreatedDate DESC LIMIT 20) ]; if(searchList.size()>0){ return searchList[0]; } return lstCase; } } |
suggestedCases.js-meta.xml
Define where this component to be exposed.
<?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> <apiVersion>48.0</apiVersion> <isExposed>true</isExposed> <targets> <target>lightning__RecordPage</target> <target>lightning__AppPage</target> <target>lightning__HomePage</target> </targets> </LightningComponentBundle>
After developing this component, expose it to Case Detail Page as shown in the picture.
Overall, it is a small piece of work but good to explore new things in Javascript and LWC. Thanks for reading!
No comments:
Post a Comment