Skip to content

Commit 3d10297

Browse files
committed
Generate renderingContent automatically.
Context: #150 (comment)
1 parent bcd0ac6 commit 3d10297

9 files changed

+173
-20
lines changed

README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,9 @@ const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
369369

370370
> Available as of Typesense Server `v0.25.0.rc12`
371371
372-
In order to use [`dynamicWidgets`](https://www.algolia.com/doc/api-reference/widgets/dynamic-facets/js/),
373-
Instantsearch expects a parameter called [`renderingContent`](https://www.algolia.com/doc/api-reference/api-parameters/renderingContent/) to be set
374-
which controls the display logic for this widget.
375-
376-
In Algolia, this configuration can be set via the dashboard or via the API.
377-
But when using Typesense and this adapter, this setting has to be configured when instantiating the adapter like this:
372+
This [`dynamicWidgets`](https://www.algolia.com/doc/api-reference/widgets/dynamic-facets/js/) widget works out of the box with no additional changes,
373+
but if you want to control the order in which these facets are displayed in the UI
374+
Instantsearch expects a parameter called [`renderingContent`](https://www.algolia.com/doc/api-reference/api-parameters/renderingContent/) to be set.
378375

379376
```js
380377
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
@@ -389,10 +386,8 @@ const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
389386
},
390387
],
391388
},
392-
renderingContent: {
393-
// <<====== Required
389+
renderingContent: { // <<===== Add this, only if you want to control the order of the widgets displayed by dynamicWidgets
394390
facetOrdering: {
395-
// <<====== Required: this controls the order in which the dynamic facets are displayed, and is *required* for the dynamicWidget to render
396391
facets: {
397392
order: ["size", "brand"], // <<===== Change this as needed
398393
},

dist/typesense-instantsearch-adapter.js

Lines changed: 22 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/typesense-instantsearch-adapter.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/typesense-instantsearch-adapter.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/typesense-instantsearch-adapter.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/SearchResponseAdapter.js

Lines changed: 22 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/SearchResponseAdapter.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/SearchResponseAdapter.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,21 @@ export class SearchResponseAdapter {
264264
return adaptedResult;
265265
}
266266

267+
_adaptRenderingContent(typesenseFacetCounts) {
268+
const adaptedResult = Object.assign({}, this.configuration.renderingContent);
269+
270+
// Only set facet ordering if the user has not set one
271+
if (adaptedResult.facetOrdering?.facets?.order == null) {
272+
adaptedResult.facetOrdering = adaptedResult.facetOrdering || {};
273+
adaptedResult.facetOrdering.facets = adaptedResult.facetOrdering.facets || {};
274+
adaptedResult.facetOrdering.facets.order = typesenseFacetCounts.map((fc) => fc["field_name"]);
275+
}
276+
277+
return adaptedResult;
278+
}
279+
267280
adapt() {
281+
const adaptedRenderingContent = this._adaptRenderingContent(this.typesenseResponse.facet_counts || []);
268282
const adaptedResult = {
269283
hits: this.typesenseResponse.grouped_hits
270284
? this._adaptGroupedHits(this.typesenseResponse.grouped_hits)
@@ -277,7 +291,7 @@ export class SearchResponseAdapter {
277291
facets_stats: this._adaptFacetStats(this.typesenseResponse.facet_counts || {}),
278292
query: this.typesenseResponse.request_params.q,
279293
processingTimeMS: this.typesenseResponse.search_time_ms,
280-
...(this.configuration.renderingContent != null && { renderingContent: this.configuration.renderingContent }),
294+
...(Object.keys(adaptedRenderingContent).length > 0 ? { renderingContent: adaptedRenderingContent } : null),
281295
};
282296

283297
// console.log(adaptedResult);

test/SearchResponseAdpater.test.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { SearchResponseAdapter } from "../src/SearchResponseAdapter";
22
import { Configuration } from "../src/Configuration";
3+
import typesenseResponse from "./support/data/typesense-search-response.json";
34

45
describe("SearchResponseAdapter", () => {
56
describe("._adaptHighlightResult", () => {
@@ -274,4 +275,109 @@ describe("SearchResponseAdapter", () => {
274275
});
275276
});
276277
});
278+
279+
describe("._adaptRenderingContent", () => {
280+
describe("when user does not specify any renderingContent", () => {
281+
it("generates the facet ordering for the user automatically", () => {
282+
const typesenseResponse = require("./support/data/typesense-search-response.json");
283+
const subject = new SearchResponseAdapter(
284+
typesenseResponse["results"][0],
285+
{
286+
params: {
287+
highlightPreTag: "<mark>",
288+
highlightPostTag: "</mark>",
289+
},
290+
},
291+
{}
292+
);
293+
294+
const result = subject.adapt();
295+
expect(result?.renderingContent?.facetOrdering?.facets?.order).toEqual([
296+
"brand",
297+
"free_shipping",
298+
"price",
299+
"rating",
300+
"categories",
301+
"categories.lvl0",
302+
]);
303+
});
304+
});
305+
describe("when user specifies partial renderingContent, without facet ordering", () => {
306+
it("generates the facet ordering for the user automatically, and merges with the provided data", () => {
307+
const typesenseResponse = require("./support/data/typesense-search-response.json");
308+
const subject = new SearchResponseAdapter(
309+
typesenseResponse["results"][0],
310+
{
311+
params: {
312+
highlightPreTag: "<mark>",
313+
highlightPostTag: "</mark>",
314+
},
315+
},
316+
{
317+
renderingContent: {
318+
facetOrdering: {
319+
somevalue: "abc",
320+
anothervalue: {
321+
key: "value",
322+
},
323+
},
324+
},
325+
}
326+
);
327+
328+
const result = subject.adapt();
329+
expect(result?.renderingContent).toEqual({
330+
facetOrdering: {
331+
somevalue: "abc",
332+
anothervalue: {
333+
key: "value",
334+
},
335+
facets: {
336+
order: ["brand", "free_shipping", "price", "rating", "categories", "categories.lvl0"],
337+
},
338+
},
339+
});
340+
});
341+
});
342+
describe("when user specifies facet ordering", () => {
343+
it("it uses that and doesn't override", () => {
344+
const typesenseResponse = require("./support/data/typesense-search-response.json");
345+
const subject = new SearchResponseAdapter(
346+
typesenseResponse["results"][0],
347+
{
348+
params: {
349+
highlightPreTag: "<mark>",
350+
highlightPostTag: "</mark>",
351+
},
352+
},
353+
{
354+
renderingContent: {
355+
facetOrdering: {
356+
somevalue: "abc",
357+
anothervalue: {
358+
key: "value",
359+
},
360+
facets: {
361+
order: ["brand", "free_shipping"],
362+
},
363+
},
364+
},
365+
}
366+
);
367+
368+
const result = subject.adapt();
369+
expect(result?.renderingContent).toEqual({
370+
facetOrdering: {
371+
somevalue: "abc",
372+
anothervalue: {
373+
key: "value",
374+
},
375+
facets: {
376+
order: ["brand", "free_shipping"],
377+
},
378+
},
379+
});
380+
});
381+
});
382+
});
277383
});

0 commit comments

Comments
 (0)