@causalfoundry/js-sdk
Version:
Causal Foundry WEB SDK (JS/TS)
229 lines (214 loc) • 7.19 kB
text/typescript
import {
ECommerceCatalogType,
ECommerceTypes,
ItemAction,
ItemObject,
ItemType,
} from "./typings";
import CfCore from "../../core/CfCore";
import { verifyItemObject } from "./validators";
import { logIngestEvent } from "./logIngestEvent";
import {
validateAndSaveBloodCatalog,
validateAndSaveDrugCatalog,
validateAndSaveFacilityCatalog,
validateAndSaveGroceryCatalog,
validateAndSaveMedicalEquipmentCatalog,
validateAndSaveOxygenCatalog,
} from "./validators/EComCatalogValidator";
import {
logCancelCheckoutEvent,
logCheckoutEvent,
logCartEvent,
logDeliveryEvent,
logItemEvent,
} from "./legacyLoggerFunctions";
export const logCatalogEvent = (
subjectId: string,
catalogType: ECommerceCatalogType,
catalogModel: any
) => {
if (!catalogModel) {
return;
}
switch (catalogType) {
case ECommerceCatalogType.Drug:
validateAndSaveDrugCatalog(subjectId, catalogModel);
break;
case ECommerceCatalogType.Grocery:
validateAndSaveGroceryCatalog(subjectId, catalogModel);
break;
case ECommerceCatalogType.Blood:
validateAndSaveBloodCatalog(subjectId, catalogModel);
break;
case ECommerceCatalogType.Oxygen:
validateAndSaveOxygenCatalog(subjectId, catalogModel);
break;
case ECommerceCatalogType.MedicalEquipment:
validateAndSaveMedicalEquipmentCatalog(subjectId, catalogModel);
break;
case ECommerceCatalogType.Facility:
validateAndSaveFacilityCatalog(subjectId, catalogModel);
break;
}
};
/**
* Start tracking impressions automatically for the items whose parent
* is the element defined by the class `containerClassname`. A impression
* is a visualization of an item for specific amount of time (i.e.: 1s)
*
* In addition, the items to track must include some metadata by using
* the internal dataset of HTML elements, as shown in the next example.
*
* ```html
* <div
* data-log-id="0"
* data-log-quantity="9"
* data-log-price="426"
* data-log-currency="EUR"
* data-log-stock-status="in_stock"
* data-log-promo-id="your-promo-id"
* class="item-card"
* >
* ```
*
* @param {string} containerClassname Represents the CSS classname of the
* container to monitorize
*
* @param {string} itemClassname Any item within the indicated container must
* also include a common classname to let the SDK monitorize it
*
* @throws Will throw the error 'container-does-not-exist'
* when `containerClassname` does not correspond to
* any DOM element
*/
const startTrackingImpressions = (
containerClassname: string,
itemClassname: string, searchId?: string
) => {
const impressionHandler = ({ dataset, appData }) => {
const {
logId: id,
logCurrency: currency,
logType: type,
logPrice: price,
logQuantity: quantity,
logStockStatus: stock_status,
logPromoId: promo_id,
logFacilityId: facility_id,
logDrugCatalogObject: drug_catalog_object,
} = dataset;
const itemDetail: ItemObject = {
id,
type: type || ItemType.Drug,
currency: currency,
price: parseInt(price),
quantity: parseInt(quantity),
stock_status: stock_status,
promo_id: promo_id || "",
facility_id: facility_id || "",
};
let catalogObj;
let catalogData;
if (drug_catalog_object) {
try {
catalogObj = JSON.parse(drug_catalog_object);
if (type === ItemType.Drug) {
catalogData = {
market_id: catalogObj.market_id,
name: catalogObj.name,
description: catalogObj.description,
supplier_id: catalogObj.supplier_id,
supplier_name: catalogObj.supplier_name,
producer: catalogObj.producer || "",
packaging: catalogObj.packaging || "",
active_ingredients: catalogObj.active_ingredients,
drug_form: catalogObj.drug_form || "",
drug_strength: catalogObj.drug_strength || "",
atc_anatomical_group: catalogObj.atc_anatomical_group || "",
otc_or_ethical: catalogObj.otc_or_ethical || "",
};
} else if (type === ItemType.Blood) {
catalogData = {
market_id: catalogObj.market_id,
blood_component: catalogObj.blood_component,
blood_group: catalogObj.blood_group,
packaging: catalogObj.packaging,
packaging_size: catalogObj.packaging_size,
supplier_id: catalogObj.supplier_id || "",
supplier_name: catalogObj.supplier_name || "",
};
} else if (type === ItemType.MedicalEquipment) {
catalogData = {
name: catalogObj.name,
market_id: catalogObj.market_id,
description: catalogObj.description || "",
supplier_id: catalogObj.supplier_id,
supplier_name: catalogObj.supplier_name,
producer: catalogObj.producer || "",
packaging: catalogObj.packaging || "",
category: catalogObj.category || "",
};
} else if (type === ItemType.Oxygen) {
catalogData = {
market_id: catalogObj.market_id,
packaging: catalogObj.packaging,
packaging_size: catalogObj.packaging_size,
supplier_id: catalogObj.supplier_id || "",
supplier_name: catalogObj.supplier_name || "",
};
}
} catch (e) {
console.log("Malformed catalog object");
}
}
verifyItemObject(ECommerceTypes.Item, itemDetail);
logIngestEvent(ECommerceTypes.Item, {
action: ItemAction.Impression,
item: itemDetail,
});
};
CfCore.getInstance().startTrackingImpressions(
impressionHandler,
containerClassname,
itemClassname
);
};
/**
* When the container indicated in `startTrackingImpressions` is no longer
* available (i.e.: the user has jumped to another section), call this function
* to stop monitoring those items inside the removed container
*
* @param {string} containerClassname The className that identifies the container
* to stop tracking
*/
const stopTrackingImpressions = (containerClassname, searchId?: string) => {
CfCore.getInstance().stopTrackingImpressions(containerClassname);
};
/**
* When the search is updated, that is, the user introduced a new query
* or a new attribute in the available selector, but the container does not
* changed, call the this function. It may happen that some items are shared
* with the previous search but, due searchId has changed, they will be already
* logged
*
* @param {string} searchId
*
* @throws `unknown-container` when the `containerClassname` was not being already tracked
*/
const restartTrackingImpressions = (containerClassname: string, searchId?: string) => {
CfCore.getInstance().restartTrackingImpressions(containerClassname);
};
export default {
logIngestEvent,
logCatalogEvent,
restartTrackingImpressions,
startTrackingImpressions,
stopTrackingImpressions,
// Legacy functions
logCancelCheckoutEvent,
logCheckoutEvent,
logCartEvent,
logDeliveryEvent,
logItemEvent,
};