@jss-rule-engine/nextjs
Version:
198 lines (140 loc) • 7.54 kB
text/typescript
import { GetItemByIdQuery } from '../queries/getItemById'
import { constants, GraphQLRequestClient } from '@sitecore-jss/sitecore-jss-nextjs';
import { JssRuleEngine, RuleEngineContext } from '@jss-rule-engine/core'
import { RuleEnginePersonalizationContext } from '@jss-rule-engine/edge';
export class PersonalizationHelper {
endpointUrl:string;
sitecoreApiKey: string;
constructor(graphQlEndpoint:string, sitecoreApiKey:string){
this.endpointUrl = graphQlEndpoint;
this.sitecoreApiKey = sitecoreApiKey;
}
guid() {
var w = () => { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); }
return `${w()}${w()}-${w()}-${w()}-${w()}-${w()}${w()}${w()}`;
}
async getItemById(itemId: String) {
if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
return null;
}
const graphQLClient = new GraphQLRequestClient(this.endpointUrl, {
apiKey: this.sitecoreApiKey,
});
var graphQlResponse = await graphQLClient.request(GetItemByIdQuery, {
"id": itemId
});
return graphQlResponse;
}
async populateFields(rendering: any) {
if (!rendering?.dataSource?.length) {
return;
}
var itemResult:any = await this.getItemById(rendering?.dataSource);
if (!itemResult) {
return;
}
itemResult.item.fields.forEach(async (fieldObj: any) => {
if (rendering.fields[fieldObj.name]?.value) {
rendering.fields[fieldObj.name].value = fieldObj.value;
} else {
rendering.fields[fieldObj.name] = {
value: fieldObj.value
};
}
});
return rendering;
}
async doPersonalizePlaceholder(placeholderPersonalization: any, elementPlaceholderRenderings: any) {
if (placeholderPersonalization && placeholderPersonalization.renderings) {
for (let y = 0; y < elementPlaceholderRenderings.length; y++) {
let renderingToUpdate = elementPlaceholderRenderings[y];
var renderingPersonalization = placeholderPersonalization.renderings
.find((i: any) => i.name == renderingToUpdate.componentName);
if (!renderingPersonalization) {
continue;
}
if (renderingPersonalization.hide) {
if (!renderingToUpdate) {
console.log('Layout is missing rendering named ', renderingPersonalization.name);
continue;
}
elementPlaceholderRenderings = elementPlaceholderRenderings
.filter((y: any) => y.name != renderingToUpdate.componentName);
}
if (renderingPersonalization.update) {
if (!renderingToUpdate) {
console.log('Layout is missing rendering named ', renderingPersonalization.name);
continue;
}
if (renderingToUpdate.dataSource != renderingPersonalization.datasource) {
renderingToUpdate.dataSource = renderingPersonalization.datasource;
await this.populateFields(renderingToUpdate);
}
}
}
var personalizationsToAdd = placeholderPersonalization.renderings.filter((i: any) => i.add);
for await (const renderingPersonalization of personalizationsToAdd) {
var newRendering = {
componentName: renderingPersonalization.name,
dataSource: renderingPersonalization.datasource,
fields: {},
params: [],
experiences: {},
uid: this.guid()
};
await this.populateFields(newRendering);
elementPlaceholderRenderings.push(newRendering);
}
return elementPlaceholderRenderings;
}
else {
return elementPlaceholderRenderings;
}
}
async runRuleActions(ruleEngine: JssRuleEngine, props:any, personalizationRule: any, ruleActions: any){
let placeholdersLayout = props.layoutData.sitecore.route?.placeholders;
if (placeholdersLayout && personalizationRule?.value?.length > 0) {
var ruleEngineContext = ruleEngine.getRuleEngineContext() as RuleEngineContext;
let parsedRule = ruleEngine.parseRuleXml(personalizationRule.value, ruleEngineContext);
await ruleEngine.runRuleActions(parsedRule, ruleActions, ruleEngineContext);
const personalization = ruleEngineContext.sessionContext?.get<RuleEnginePersonalizationContext>("personalization");
if(personalization?.placeholders)
{
var placeholderPersonalizationsKeys = Object.keys(personalization?.placeholders);
for await (const phName of placeholderPersonalizationsKeys) {
var placeholderPersonalization = personalization?.placeholders[phName];
var placeholderRenderings = placeholdersLayout[phName];
var personalizedRenderings =
await this.doPersonalizePlaceholder(placeholderPersonalization, placeholderRenderings);
placeholdersLayout[phName] = personalizedRenderings;
}
}
}
return props;
}
async personalize(ruleEngine:JssRuleEngine, props: any, personalizationRule: any) {
let placeholdersLayout = props.layoutData.sitecore.route?.placeholders;
if (placeholdersLayout && personalizationRule?.value?.length > 0) {
console.log('Applying personalization')
var ruleEngineContext = ruleEngine.getRuleEngineContext() as RuleEngineContext;
ruleEngine.parseAndRunRule(personalizationRule.value, ruleEngineContext);
console.log("Rule parsed")
const personalization = ruleEngineContext.sessionContext?.get<RuleEnginePersonalizationContext>("personalization");
console.log('Personalization data', personalization);
if(personalization?.placeholders)
{
var placeholderPersonalizationsKeys = Object.keys(personalization?.placeholders);
for await (const phName of placeholderPersonalizationsKeys) {
console.log('Personalizing placeholder - ', phName)
var placeholderPersonalization = personalization?.placeholders[phName];
var placeholderRenderings = placeholdersLayout[phName];
var personalizedRenderings =
await this.doPersonalizePlaceholder(placeholderPersonalization, placeholderRenderings);
placeholdersLayout[phName] = personalizedRenderings;
}
}
}
return props;
}
}
//exports.PersonalizationHelper = PersonalizationHelper;