Skip to content

Commit

Permalink
add insights
Browse files Browse the repository at this point in the history
  • Loading branch information
raed667 committed Apr 8, 2024
1 parent 485f25a commit 8498792
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 26 deletions.
3 changes: 3 additions & 0 deletions examples/js/getting-started/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ search.addWidgets([
frequentlyBoughtTogether({
container: '#hits',
objectID: '5723538',
queryParameters: {
clickAnalytics: true,
},
}),
configure({
hitsPerPage: 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
RecommendTranslations,
RecordWithObjectID,
Renderer,
SendEventForHits,
} from '../types';
import type { ViewProps } from './recommend-inner/ListView';

Expand All @@ -20,7 +21,6 @@ export type FrequentlyBoughtTogetherComponentProps<TObject> = {
recommendations: TObject[];
translations: Partial<RecommendTranslations>;
};

export type HeaderComponentProps<TObject> =
FrequentlyBoughtTogetherComponentProps<TObject>;

Expand All @@ -47,6 +47,7 @@ export type RecommendComponentProps<
) => JSX.Element;
status: RecommendStatus;
translations?: Partial<RecommendTranslations>;
sendEvent: SendEventForHits;
view?: (
props: ViewProps<
RecordWithObjectID<TObject>,
Expand Down Expand Up @@ -102,6 +103,7 @@ export function createFrequentlyBoughtTogetherComponent({
translations={translations}
itemComponent={props.itemComponent}
items={props.items}
sendEvent={props.sendEvent}
/>
</section>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
RecommendTranslations,
RecordWithObjectID,
Renderer,
SendEventForHits,
} from '../../types';

export type ViewProps<
Expand All @@ -22,6 +23,7 @@ export type ViewProps<
) => JSX.Element;
items: TItem[];
translations: TTranslations;
sendEvent: SendEventForHits;
};

export function createListViewComponent({ createElement, Fragment }: Renderer) {
Expand All @@ -32,7 +34,12 @@ export function createListViewComponent({ createElement, Fragment }: Renderer) {
Partial<RecommendClassNames>
>
) {
const { classNames = {}, itemComponent: ItemComponent, items } = userProps;
const {
classNames = {},
itemComponent: ItemComponent,
items,
sendEvent,
} = userProps;
return (
<div className={cx('ais-Recommend-container', classNames.container)}>
<ol className={cx('ais-Recommend-list', classNames.list)}>
Expand All @@ -43,6 +50,12 @@ export function createListViewComponent({ createElement, Fragment }: Renderer) {
createElement={createElement}
Fragment={Fragment}
item={item}
onClick={() => {
sendEvent('click:internal', item, 'Hit Clicked');
}}
onAuxClick={() => {
sendEvent('click:internal', item, 'Hit Clicked');
}}
/>
))}
</ol>
Expand Down
11 changes: 8 additions & 3 deletions packages/instantsearch-ui-components/src/types/Recommend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,20 @@ export type InnerComponentProps<TObject> = {
translations: Partial<RecommendTranslations>;
};

// Should be imported in a shared package (e.g. instantsearch-core)
export type RecordWithObjectID<TObject = Record<string, unknown>> = TObject & {
objectID: string;
__position: number; // to do
__queryID?: string; // to do
__position: number;
__queryID?: string;
};

export type ItemComponentProps<TObject> = {
item: TObject;
onClick: () => void;
onAuxClick: () => void;
};

// use instantsearch status instead
// Should the same as instantsearch status in a shared package (e.g. instantsearch-core)
export type RecommendStatus = 'idle' | 'loading' | 'stalled' | 'error';

export type SendEventForHits = (...props: unknown[]) => void;
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import {
createDocumentationMessageGenerator,
checkRendering,
noop,
escapeHits,
createSendEventForHits,
addAbsolutePosition,
addQueryID,
} from '../../lib/utils';

import type { SendEventForHits } from '../../lib/utils';
import type {
Connector,
WidgetRenderState,
Expand All @@ -12,6 +17,7 @@ import type {
BaseHit,
RenderOptions,
} from '../../types';
import type { RecommendResultItem } from 'algoliasearch-helper';

const withUsage = createDocumentationMessageGenerator({
name: 'frequentlyBoughtTogether',
Expand All @@ -34,12 +40,11 @@ export type FrequentlyBoughtTogetherRenderState<
/**
* Sends an event to the Insights middleware.
*/
// sendEvent: SendEventForHits;
sendEvent: SendEventForHits;
};

/**
* Returns a string for the `data-insights-event` attribute for the Insights middleware
*/
// bindEvent: BindEventForHits;
export type TransformItemsMetadata = {
results?: RecommendResultItem;
};

export type FrequentlyBoughtTogetherConnectorParams<
Expand All @@ -59,7 +64,7 @@ export type FrequentlyBoughtTogetherConnectorParams<
/**
* Function to transform the items passed to the templates.
*/
transformItems?: TransformItems<Hit<THit>>;
transformItems?: TransformItems<Hit<THit>, TransformItemsMetadata>;
};

export type FrequentlyBoughtTogetherWidgetDescription<
Expand Down Expand Up @@ -87,6 +92,16 @@ const connectFrequentlyBoughtTogether: FrequentlyBoughtTogetherConnector =
checkRendering(renderFn, withUsage());

return (widgetParams) => {
const {
// @MAJOR: this can default to false
escapeHTML = true,
transformItems = ((items) => items) as NonNullable<
FrequentlyBoughtTogetherConnectorParams['transformItems']
>,
...rest
} = widgetParams || {};
let sendEvent: SendEventForHits;

return {
dependsOn: 'recommend',
$$type: 'ais.frequentlyBoughtTogether',
Expand All @@ -113,7 +128,7 @@ const connectFrequentlyBoughtTogether: FrequentlyBoughtTogetherConnector =
false
);

// renderState.sendEvent('view:internal', renderState.hits);
renderState.sendEvent('view:internal', renderState.hits);
},

getRenderState(renderState, renderOptions) {
Expand All @@ -123,12 +138,42 @@ const connectFrequentlyBoughtTogether: FrequentlyBoughtTogetherConnector =
};
},

getWidgetRenderState({ results }) {
getWidgetRenderState({ results, helper, instantSearchInstance }) {
if (!sendEvent) {
sendEvent = createSendEventForHits({
instantSearchInstance,
getIndex: () => helper.getIndex(),
widgetType: this.$$type,
});
}

if (results === null || results === undefined) {
return { hits: [], widgetParams };
return { hits: [], sendEvent, widgetParams };
}

if (escapeHTML && results.hits.length > 0) {
results.hits = escapeHits(results.hits);
}

return { hits: results.hits, widgetParams };
const hitsWithAbsolutePosition = addAbsolutePosition(
results.hits,
results.page,
results.hitsPerPage
);

const hitsWithAbsolutePositionAndQueryID = addQueryID(
hitsWithAbsolutePosition,
results.queryID
);

const transformedHits = transformItems(
hitsWithAbsolutePositionAndQueryID,
{
results: results as RecommendResultItem,
}
);

return { hits: transformedHits, sendEvent, widgetParams };
},

dispose({ state }) {
Expand All @@ -139,6 +184,7 @@ const connectFrequentlyBoughtTogether: FrequentlyBoughtTogetherConnector =

getWidgetParameters(state) {
return state.addFrequentlyBoughtTogether({
...rest,
$$id: 123456789,
objectID: widgetParams.objectID,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ const renderer =
hits: receivedHits,
results,
instantSearchInstance,
// insights,
// bindEvent,
// sendEvent,
sendEvent,
// insights
},
isFirstRendering
) => {
Expand All @@ -75,7 +74,10 @@ const renderer =
return;
}

// to do insights
// const handleInsightsClick = createInsightsEventHandler({
// insights,
// sendEvent,
// });

const emptyComponent: FrequentlyBoughtTogetherUiProps<Hit>['fallbackComponent'] =
({ ...rootProps }) => (
Expand All @@ -84,34 +86,37 @@ const renderer =
rootProps={rootProps}
templateKey="empty"
data={results}
sendEvent={sendEvent}
/>
);

const itemComponent: FrequentlyBoughtTogetherUiProps<Hit>['itemComponent'] =
({ item }) => (
({ item, ...rootProps }) => (
<TemplateComponent
{...renderState.templateProps}
templateKey="item"
rootTagName="li"
rootProps={{
...rootProps,
onClick: (_event: MouseEvent) => {
// handleInsightsClick(event);
// rootProps.onClick();
rootProps.onClick();
},
onAuxClick: (_event: MouseEvent) => {
// handleInsightsClick(event);
// rootProps.onAuxClick();
rootProps.onAuxClick();
},
}}
data={item}
sendEvent={sendEvent}
/>
);

render(
<FrequentlyBoughtTogether
items={receivedHits}
itemComponent={itemComponent}
// sendEvent={sendEvent}
sendEvent={sendEvent}
classNames={cssClasses}
fallbackComponent={emptyComponent}
status={instantSearchInstance.status}
Expand Down Expand Up @@ -172,10 +177,11 @@ const frequentlyBoughtTogether: FrequentlyBoughtTogetherWidget =
function frequentlyBoughtTogether(widgetParams) {
const {
container,
// escapeHTML,
// transformItems,
escapeHTML,
transformItems,
templates = {},
cssClasses = {},
...rest
} = widgetParams || {};

if (!container) {
Expand All @@ -196,7 +202,12 @@ const frequentlyBoughtTogether: FrequentlyBoughtTogetherWidget =
() => render(null, containerNode)
);
return {
...makeWidget({ objectID: widgetParams.objectID }),
...makeWidget({
...rest,
objectID: widgetParams.objectID,
escapeHTML,
transformItems,
}),
$$widgetType: 'ais.frequentlyBoughtTogether',
};
};
Expand Down

0 comments on commit 8498792

Please sign in to comment.