Skip to content

Commit

Permalink
feat(headless): Add locale to insight search (#4302)
Browse files Browse the repository at this point in the history
[SFINT-5668]

Essentially, you can now set the `locale` parameter in the
initialization options of the InsightEngine:

```
search: {
  locale: LOCALE,
}
```

It is under `search` because this is a concept that already existed on
the search engine that I am just bringing to the Insight Engine because
we need it.

It will be sent now as the `locale` parameter on the insight search
requests.


![image](https://github.com/user-attachments/assets/3dd809ee-36e0-4025-84d6-41f55668dbde)

I am re-using the existing Search Engine configuration action
`engine.dispatch(updateSearchConfiguration(search));` to update the
`engine.state.search.locale` value in the Insight Engine.


[SFINT-5668]:
https://coveord.atlassian.net/browse/SFINT-5668?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
erocheleau authored Aug 21, 2024
1 parent a5941c9 commit 3bea5b6
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ContextParam,
FoldingParam,
LocaleParam,
NumberOfResultsParam,
} from '../../../platform-service-params';
import {
Expand Down Expand Up @@ -36,6 +37,7 @@ export type InsightQueryRequest = InsightParam &
TabParam &
FoldingParam &
ContextParam &
LocaleParam &
PipelineRuleParams;

interface CaseContextParam {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {Schema} from '@coveo/bueno';
import {requiredNonEmptyString} from '../../utils/validate-payload';
import {RecordValue, Schema} from '@coveo/bueno';
import {
nonEmptyString,
requiredNonEmptyString,
} from '../../utils/validate-payload';
import {
EngineConfiguration,
engineConfigurationDefinitions,
Expand All @@ -13,10 +16,36 @@ export interface InsightEngineConfiguration extends EngineConfiguration {
* Specifies the unique identifier of the target insight configuration.
*/
insightId: string;
/**
* Specifies the configuration for the insight search.
*/
search?: InsightEngineSearchConfigurationOptions;
}

/**
* The insight engine search configuration options.
*/
export interface InsightEngineSearchConfigurationOptions {
/**
* The locale of the current user. Must comply with IETF’s BCP 47 definition: https://www.rfc-editor.org/rfc/bcp/bcp47.txt.
*
* Notes:
* Coveo Machine Learning models use this information to provide contextually relevant output.
* Moreover, this information can be referred to in query expressions and QPL statements by using the $locale object.
*/
locale?: string;
}

export const insightEngineConfigurationSchema =
new Schema<InsightEngineConfiguration>({
...engineConfigurationDefinitions,
insightId: requiredNonEmptyString,
search: new RecordValue({
options: {
required: false,
},
values: {
locale: nonEmptyString,
},
}),
});
11 changes: 10 additions & 1 deletion packages/headless/src/app/insight-engine/insight-engine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ describe('buildInsightEngine', () => {

beforeEach(() => {
options = {
configuration: getSampleInsightEngineConfiguration(),
configuration: {
...getSampleInsightEngineConfiguration(),
search: {
locale: 'en-US',
},
},
loggerOptions: {level: 'silent'},
};

Expand All @@ -41,6 +46,10 @@ describe('buildInsightEngine', () => {
);
});

it('sets the locale correctly', () => {
expect(engine.state.configuration?.search?.locale).toEqual('en-US');
});

it('exposes an #executeFirstSearch method', () => {
expect(engine.executeFirstSearch).toBeTruthy();
});
Expand Down
13 changes: 11 additions & 2 deletions packages/headless/src/app/insight-engine/insight-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {NoopPreprocessRequest} from '../../api/preprocess-request';
import {InsightAPIClient} from '../../api/service/insight/insight-api-client';
import {interfaceLoad} from '../../features/analytics/analytics-actions';
import {LegacySearchAction} from '../../features/analytics/analytics-utils';
import {updateSearchConfiguration} from '../../features/configuration/configuration-actions';
import {setInsightConfiguration} from '../../features/insight-configuration/insight-configuration-actions';
import {insightConfigurationReducer as insightConfiguration} from '../../features/insight-configuration/insight-configuration-slice';
import {insightInterfaceReducer as insightInterface} from '../../features/insight-interface/insight-interface-slice';
Expand All @@ -28,9 +29,13 @@ import {buildThunkExtraArguments} from '../thunk-extra-arguments';
import {
InsightEngineConfiguration,
insightEngineConfigurationSchema,
InsightEngineSearchConfigurationOptions,
} from './insight-engine-configuration';

export type {InsightEngineConfiguration};
export type {
InsightEngineConfiguration,
InsightEngineSearchConfigurationOptions,
};

const insightEngineReducers = {
insightConfiguration,
Expand Down Expand Up @@ -99,14 +104,18 @@ export function buildInsightEngine(

const engine = buildEngine(augmentedOptions, thunkArguments);

const {insightId} = options.configuration;
const {insightId, search} = options.configuration;

engine.dispatch(
setInsightConfiguration({
insightId,
})
);

if (search) {
engine.dispatch(updateSearchConfiguration(search));
}

return {
...engine,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('insight search request', () => {
expect(params.accessToken).toBe(state.configuration.accessToken);
expect(params.organizationId).toBe(state.configuration.organizationId);
expect(params.url).toBe(state.configuration.platformUrl);
expect(params.locale).toBe(state.configuration.search.locale);
});

it('#buildInsightSearchRequest returns the state #insightId', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ export const buildInsightBaseRequest = async (
): Promise<MappedSearchRequest<InsightQueryRequest>> => {
const cq = buildConstantQuery(state);
const facets = getAllFacets(state);

return mapSearchRequest<InsightQueryRequest>({
accessToken: state.configuration.accessToken,
organizationId: state.configuration.organizationId,
url: state.configuration.platformUrl,
locale: state.configuration.search.locale,
insightId: state.insightConfiguration.insightId,
...(state.configuration.analytics.enabled &&
(await fromAnalyticsStateToAnalyticsParams(
Expand Down
1 change: 1 addition & 0 deletions packages/headless/src/insight.index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type {
InsightEngine,
InsightEngineOptions,
InsightEngineConfiguration,
InsightEngineSearchConfigurationOptions,
} from './app/insight-engine/insight-engine';
export {buildInsightEngine} from './app/insight-engine/insight-engine';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-ignore
import getHeadlessConfiguration from '@salesforce/apex/InsightController.getHeadlessConfiguration';
import LOCALE from '@salesforce/i18n/locale';
import {
getHeadlessBindings,
loadDependencies,
Expand Down Expand Up @@ -64,6 +65,9 @@ export default class QuanticInsightInterface extends LightningElement {
configuration: {
...JSON.parse(data),
insightId: this.insightId,
search: {
locale: LOCALE,
},
},
};
setEngineOptions(
Expand Down

0 comments on commit 3bea5b6

Please sign in to comment.