Skip to content

Commit

Permalink
feat(index): expose createURL (#4603)
Browse files Browse the repository at this point in the history
* feat(index): expose createURL

This is useful for recreating what an index widget does when it renders, see ssr in Vue, as well as poc/telemetry2

I think in the future we might want a function to retrieve the parameters given to render / init.

* add tests
  • Loading branch information
Haroenv committed Dec 18, 2020
1 parent 6550885 commit f57e9c5
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 18 deletions.
98 changes: 98 additions & 0 deletions src/widgets/index/__tests__/index-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { runAllMicroTasks } from '../../../../test/utils/runAllMicroTasks';
import { Widget, InstantSearch } from '../../../types';
import index from '../index';
import { warning } from '../../../lib/utils';
import { refinementList } from '../..';

describe('index', () => {
const createSearchBox = (args: Partial<Widget> = {}): Widget =>
Expand Down Expand Up @@ -651,6 +652,103 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index-widge
});
});

describe('createURL', () => {
it('default url returns #', () => {
const instance = index({ indexName: 'indexName' });
const searchBox = createSearchBox();
const pagination = createPagination();

instance.addWidgets([searchBox, pagination]);

instance.init(createInitOptions());

expect(instance.createURL(new SearchParameters())).toEqual('#');
});

it('calls the createURL of routing', () => {
const instance = index({ indexName: 'indexName' });
const searchBox = createSearchBox();
const pagination = createPagination();

instance.addWidgets([searchBox, pagination]);

instance.init(
createInitOptions({
instantSearchInstance: createInstantSearch({
// @ts-ignore
_createURL(routeState) {
return routeState;
},
}),
})
);

expect(instance.createURL(new SearchParameters())).toEqual({
indexName: {},
});
});

it('create URLs with custom helper state', () => {
const instance = index({ indexName: 'indexName' });
const searchBox = createSearchBox();
const pagination = createPagination();

instance.addWidgets([searchBox, pagination]);

instance.init(
createInitOptions({
instantSearchInstance: createInstantSearch({
// @ts-ignore
_createURL(routeState) {
return routeState;
},
}),
})
);

expect(instance.createURL(new SearchParameters({ page: 100 }))).toEqual({
indexName: { page: 100 },
});
});

it('create URLs with non-namesake helper state', () => {
const instance = index({ indexName: 'indexName' });
const searchBox = createSearchBox();
const pagination = createPagination();

const container = document.createElement('div');
document.body.append(container);

instance.addWidgets([
searchBox,
pagination,
refinementList({ container, attribute: 'doggies' }),
]);

instance.init(
createInitOptions({
instantSearchInstance: createInstantSearch({
// @ts-ignore
_createURL(routeState) {
return routeState;
},
}),
})
);

expect(
instance.createURL(
new SearchParameters({
disjunctiveFacets: ['doggies'],
disjunctiveFacetsRefinements: { doggies: ['zap'] },
})
)
).toEqual({
indexName: { refinementList: { doggies: ['zap'] } },
});
});
});

describe('init', () => {
it('forwards the `search` call to the main instance', () => {
const instance = index({ indexName: 'indexName' });
Expand Down
40 changes: 22 additions & 18 deletions src/widgets/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ export type Index = Widget & {
getResults(): SearchResults | null;
getParent(): Index | null;
getWidgets(): Widget[];
createURL(state: SearchParameters): string;

addWidgets(widgets: Widget[]): Index;
removeWidgets(widgets: Widget[]): Index;

init(options: IndexInitOptions): void;
render(options: IndexRenderOptions): void;
dispose(): void;
Expand Down Expand Up @@ -103,7 +106,7 @@ function privateHelperSetState(
}
}

function getLocalWidgetsState(
function getLocalWidgetsUiState(
widgets: Widget[],
widgetStateOptions: WidgetUiStateOptions,
initialUiState: IndexUiState = {}
Expand Down Expand Up @@ -196,14 +199,6 @@ const index = (props: IndexProps): Index => {
let helper: Helper | null = null;
let derivedHelper: DerivedHelper | null = null;

const createURL = (nextState: SearchParameters) =>
localInstantSearchInstance!._createURL!({
[indexId]: getLocalWidgetsState(localWidgets, {
searchParameters: nextState,
helper: helper!,
}),
});

return {
$$type: 'ais.index',

Expand All @@ -227,6 +222,15 @@ const index = (props: IndexProps): Index => {
return localParent;
},

createURL(nextState: SearchParameters) {
return localInstantSearchInstance!._createURL!({
[indexId]: getLocalWidgetsUiState(localWidgets, {
searchParameters: nextState,
helper: helper!,
}),
});
},

getWidgets() {
return localWidgets;
},
Expand Down Expand Up @@ -278,7 +282,7 @@ const index = (props: IndexProps): Index => {
state: helper!.state,
renderState: localInstantSearchInstance!.renderState,
templatesConfig: localInstantSearchInstance!.templatesConfig,
createURL,
createURL: this.createURL,
scopedResults: [],
searchMetadata: {
isSearchStalled: localInstantSearchInstance!._isSearchStalled,
Expand All @@ -304,7 +308,7 @@ const index = (props: IndexProps): Index => {
state: helper!.state,
renderState: localInstantSearchInstance!.renderState,
templatesConfig: localInstantSearchInstance!.templatesConfig,
createURL,
createURL: this.createURL,
scopedResults: [],
searchMetadata: {
isSearchStalled: localInstantSearchInstance!._isSearchStalled,
Expand Down Expand Up @@ -344,7 +348,7 @@ const index = (props: IndexProps): Index => {
return next || state;
}, helper!.state);

localUiState = getLocalWidgetsState(localWidgets, {
localUiState = getLocalWidgetsUiState(localWidgets, {
searchParameters: nextState,
helper: helper!,
});
Expand Down Expand Up @@ -484,7 +488,7 @@ const index = (props: IndexProps): Index => {
state: helper!.state,
renderState: instantSearchInstance.renderState,
templatesConfig: instantSearchInstance.templatesConfig,
createURL,
createURL: this.createURL,
scopedResults: [],
searchMetadata: {
isSearchStalled: instantSearchInstance._isSearchStalled,
Expand Down Expand Up @@ -515,7 +519,7 @@ const index = (props: IndexProps): Index => {
state: helper!.state,
renderState: instantSearchInstance.renderState,
templatesConfig: instantSearchInstance.templatesConfig,
createURL,
createURL: this.createURL,
scopedResults: [],
searchMetadata: {
isSearchStalled: instantSearchInstance._isSearchStalled,
Expand All @@ -536,7 +540,7 @@ const index = (props: IndexProps): Index => {
// @ts-ignore _uiState comes from privateHelperSetState and thus isn't typed on the helper event
const _uiState = event._uiState;

localUiState = getLocalWidgetsState(
localUiState = getLocalWidgetsUiState(
localWidgets,
{
searchParameters: state,
Expand Down Expand Up @@ -571,7 +575,7 @@ const index = (props: IndexProps): Index => {
state: this.getResults()!._state,
renderState: instantSearchInstance.renderState,
templatesConfig: instantSearchInstance.templatesConfig,
createURL,
createURL: this.createURL,
searchMetadata: {
isSearchStalled: instantSearchInstance._isSearchStalled,
},
Expand Down Expand Up @@ -604,7 +608,7 @@ const index = (props: IndexProps): Index => {
state: this.getResults()!._state,
renderState: instantSearchInstance.renderState,
templatesConfig: instantSearchInstance.templatesConfig,
createURL,
createURL: this.createURL,
searchMetadata: {
isSearchStalled: instantSearchInstance._isSearchStalled,
},
Expand Down Expand Up @@ -665,7 +669,7 @@ const index = (props: IndexProps): Index => {
},

refreshUiState() {
localUiState = getLocalWidgetsState(localWidgets, {
localUiState = getLocalWidgetsUiState(localWidgets, {
searchParameters: this.getHelper()!.state,
helper: this.getHelper()!,
});
Expand Down

0 comments on commit f57e9c5

Please sign in to comment.