--- title: Leverage case context in your custom Insight Panel slug: latest-custom-ip-context canonical_url: https://docs.coveo.com/en/quantic/latest/usage/custom-ip-context/ collection: quantic source_format: adoc --- # Leverage case context in your custom Insight Panel When building a [custom Insight Panel](https://docs.coveo.com/en/quantic/latest/usage/custom-insight-panels/), you can optionally leverage case information in your [custom context](https://docs.coveo.com/en/3389/). Custom context helps [machine learning](https://docs.coveo.com/en/188/) models promote content that's more relevant to the specific case situation. At a high level, to add case context to your custom Insight Panel, retrieve case information with the Salesforce [`getRecord`](https://developer.salesforce.com/docs/platform/lwc/guide/reference-wire-adapters-record.html) wire adapter and update your Headless engine state with this information using the target [Headless Insight actions](https://docs.coveo.com/en/headless/latest/reference/modules/Insight.html#insightanalyticsactioncreators). You must also update the context and execute a new search with the updated context when the case information changes. > **Tip** > > For clarity, this article focuses only on the snippets relevant to adding case context to your custom Insight Panel. > For the full implementation, see [exampleInsightPanel.js](https://github.com/coveo/ui-kit/blob/master/packages/quantic/force-app/solutionExamples/main/lwc/exampleInsightPanel/exampleInsightPanel.js) in the Quantic project repository. . In your [custom Insight Panel](https://docs.coveo.com/en/quantic/latest/usage/custom-insight-panels/) JavaScript file, import the required Salesforce modules: ```javascript import {LightningElement, api, wire} from 'lwc'; <1> import {getRecord} from 'lightning/uiRecordApi'; <2> ``` <1> See [Understand the Wire Service](https://developer.salesforce.com/docs/platform/lwc/guide/data-wire-service-about.html). <2> See [`getRecord`](https://developer.salesforce.com/docs/platform/lwc/guide/reference-wire-adapters-record.html). . Define variables you'll need as well as the case fields that your Insight Panel will leverage: ```javascript triggeredFirstSearch = false; <1> caseRecord; <2> caseFields = [ <3> 'Case.CreatedDate', 'Case.CreatedBy.Email', 'Case.CaseNumber', 'Case.Subject', 'Case.Description', ]; ``` <1> A flag that will be used below to ensure the first search is executed only once. <2> The current case record data. It will be populated using the `getRecord` wire below. <3> The case fields that your Insight Panel will use. . Define functions to check if the watched fields of a case record have been updated and to retrieve the value of a record field: ```javascript watchedFieldsUpdated(newRecordData) { return Object.values(this.caseFields)?.reduce((result, field) => { const previousValue = this.getFieldValueFromRecord( this.caseRecord, field ); const newValue = this.getFieldValueFromRecord(newRecordData, field); return result || previousValue !== newValue; }, false); } getFieldValueFromRecord(record, fieldName) { let innerKeys = fieldName.split('.'); <1> if (!record || !innerKeys.length) return null; if (innerKeys[0].toLowerCase() === 'case') { innerKeys = innerKeys.slice(1); } if (innerKeys.length === 1) return record.fields?.[innerKeys[0]]?.value; return this.getFieldValueFromRecord( record.fields?.[innerKeys[0]]?.value, innerKeys.slice(1).join('.') ); } ``` <1> This function expects the `fieldName` to be in the following format: `Case.Contact.Name`. . In your engine initialization function, load the required Headless actions and set the case number in the engine state: ```javascript initialize = (engine) => { // ... this.actions = { // ... ...this.headless.loadInsightSearchAnalyticsActions(engine), <1> ...this.headless.loadInsightSearchActions(engine), <2> }; this.caseNumber = this.getFieldValueFromRecord(this.caseRecord, 'Case.CaseNumber') || '1234'; <3> // ... this.engine.dispatch(this.actions.setCaseNumber(this.caseNumber)); <4> }; ``` <1> See [loadInsightSearchAnalyticsActions](https://docs.coveo.com/en/headless/latest/reference/functions/Insight.loadInsightSearchAnalyticsActions.html). <2> See [loadInsightSearchActions](https://docs.coveo.com/en/headless/latest/reference/functions/Insight.loadInsightSearchActions.html). <3> Provide a default case number if the Insight Panel isn't on a case record page. <4> Dispatch an action to [set the case number](https://docs.coveo.com/en/headless/latest/reference/interfaces/Insight.CaseContextActionCreators.html#setcasenumber-1) in the engine. . Use the [`getRecord`](https://developer.salesforce.com/docs/platform/lwc/guide/reference-wire-adapters-record.html) wire adapter to fetch and store the target case record data. This wire adapter is reactive, so also use the `watchedFieldsUpdated` function just defined to check if the watched fields have changed. If they have, update the case record and execute a search with the updated context, which will yield better results. ```javascript @wire(getRecord, {recordId: '$caseId', fields: '$caseFields'}) <1> wiredRecord({data, error}) { if (data) { if (!this.triggeredFirstSearch) { this.caseRecord = data; } else { if (this.watchedFieldsUpdated(data)) { this.caseRecord = data; this.executeSearchAfterContextChanged(); } } } else { console.warn('An error occurred while retrieving the record.'); console.warn(error); } } executeSearchAfterContextChanged() { this.setupContext(); <2> this.engine.dispatch( this.actions.executeSearch( this.actions.logContextChanged(this.caseId, this.caseNumber) ) ); } setupContext() { const context = { <3> Case_ID: this.caseId, Case_Subject: this.getFieldValueFromRecord( this.caseRecord, 'Case.Subject' ), Case_Description: this.getFieldValueFromRecord( this.caseRecord, 'Case.Description' ), }; this.engine.dispatch(this.actions.setCaseContext(context)); <4> } ``` <1> Target only the case record by its ID and the fields you want to monitor. <2> Update the context, [execute a search](https://docs.coveo.com/en/headless/latest/reference/interfaces/Insight.InsightSearchActionCreators.html#executesearch-1), and [log the context change](https://docs.coveo.com/en/headless/latest/reference/interfaces/Insight.InsightSearchAnalyticsActionCreators.html#logcontextchanged) when case fields are modified. <3> Create a context object with case information that will be sent with search requests. <4> [Set the case context](https://docs.coveo.com/en/headless/latest/reference/interfaces/Insight.CaseContextActionCreators.html#setcasecontext) in the Headless engine so it's included in all searches. . Update your search execution methods to include case context: ```javascript handleInterfaceLoad = (event) => { event.stopPropagation(); if (!this.triggeredFirstSearch) { <1> this.triggeredFirstSearch = true; this.executeFirstSearch(); } }; executeFirstSearch = () => { this.setupContext(); <2> this.engine.executeFirstSearch(); }; ``` <1> Only execute the first search once when the interface loads. <2> Set up case context before executing the initial search. . Validate that the Insight Panel works as expected. When you open a case record page in which you've included your custom Insight Panel, it should automatically execute a search request with the case context. ![Quantic Insight Panel request with custom context | Coveo Quantic](https://docs.coveo.com/en/assets/images/quantic/quantic-custom-ip-context.png)