Skip to content

Commit

Permalink
refactor: change data structure to tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Sep 30, 2019
1 parent 2724032 commit 0ffe81e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
8 changes: 7 additions & 1 deletion src/lib/__tests__/InstantSearch-test.js
Expand Up @@ -1220,6 +1220,9 @@ describe('UI state', () => {
hierarchicalMenu: {
categories: 'Mobile',
},
range: {
price: '100:200',
},
},
},
});
Expand All @@ -1241,18 +1244,21 @@ To fully reflect the state, some widgets need to be added to the index "indexNam
- \`page\` needs one of these widgets: "pagination", "infiniteHits"
- \`refinementList\` needs one of these widgets: "refinementList"
- \`hierarchicalMenu\` needs one of these widgets: "hierarchicalMenu"
- \`range\` needs one of these widgets: "rangeInput", "rangeSlider"
If you do not wish to display widgets but still want to support their search parameters, you can mount "virtual widgets" that don't render anything:
\`\`\`
const virtualPagination = connectPagination(() => null);
const virtualRefinementList = connectRefinementList(() => null);
const virtualHierarchicalMenu = connectHierarchicalMenu(() => null);
const virtualRange = connectRange(() => null);
search.addWidgets([
virtualPagination({ /* ... */ }),
virtualRefinementList({ /* ... */ }),
virtualHierarchicalMenu({ /* ... */ })
virtualHierarchicalMenu({ /* ... */ }),
virtualRange({ /* ... */ })
]);
\`\`\`
Expand Down
54 changes: 31 additions & 23 deletions src/widgets/index/index.ts
Expand Up @@ -346,6 +346,18 @@ const index = (props: IndexProps): Index => {
instantSearchInstance.scheduleStalledRender();

if (__DEV__) {
// Some connectors are responsible for multiple widgets so we need
// to map them.
function getWidgetNames(connectorName: string): string[] {
switch (connectorName) {
case 'range':
return ['rangeInput', 'rangeSlider'];

default:
return [connectorName];
}
}

type StateToWidgets = {
[TParameter in keyof IndexUiState]: Array<Widget['$$type']>;
};
Expand All @@ -370,8 +382,10 @@ const index = (props: IndexProps): Index => {
.map(widget => widget.$$type)
.filter(Boolean);

type MissingWidgets = Array<[string, Array<Widget['$$type']>]>;

const missingWidgets = Object.keys(localUiState).reduce<
Array<Partial<StateToWidgets>>
MissingWidgets
>((acc, parameter) => {
const requiredWidgets: Array<Widget['$$type']> =
stateToWidgetsMap[parameter];
Expand All @@ -381,9 +395,13 @@ const index = (props: IndexProps): Index => {
mountedWidgets.includes(requiredWidget)
)
) {
acc.push({
[parameter]: stateToWidgetsMap[parameter],
});
acc.push([
parameter,
stateToWidgetsMap[parameter].map(
(widgetIdentifier: string) =>
widgetIdentifier.split('ais.')[1]
),
]);
}

return acc;
Expand All @@ -398,39 +416,29 @@ This can happen when the UI state is specified via \`initialUiState\` or \`routi
To fully reflect the state, some widgets need to be added to the index "${this.getIndexId()}":
${missingWidgets
.map(widget => {
const stateParameter = Object.keys(widget)[0];
const neededWidgets = stateToWidgetsMap[stateParameter]
.map(
(widgetIdentifier: string) => `"${widgetIdentifier.split('ais.')[1]}"`
)
.join(', ');
return `- \`${stateParameter}\` needs one of these widgets: ${neededWidgets}`;
.map(([stateParameter, widgets]) => {
return `- \`${stateParameter}\` needs one of these widgets: ${([] as string[])
.concat(...widgets.map(name => getWidgetNames(name!)))
.map((name: string) => `"${name}"`)
.join(', ')}`;
})
.join('\n')}
If you do not wish to display widgets but still want to support their search parameters, you can mount "virtual widgets" that don't render anything:
\`\`\`
${missingWidgets
.map(widget => {
const stateParameter = Object.keys(widget)[0];
const capitalizedWidget = capitalize(
stateToWidgetsMap[stateParameter][0].split('ais.')[1]
);
.map(([_stateParameter, widgets]) => {
const capitalizedWidget = capitalize(widgets[0]!);
return `const virtual${capitalizedWidget} = connect${capitalizedWidget}(() => null);`;
})
.join('\n')}
search.addWidgets([
${missingWidgets
.map(widget => {
const stateParameter = Object.keys(widget)[0];
const capitalizedWidget = capitalize(
stateToWidgetsMap[stateParameter][0].split('ais.')[1]
);
.map(([_stateParameter, widgets]) => {
const capitalizedWidget = capitalize(widgets[0]!);
return `virtual${capitalizedWidget}({ /* ... */ })`;
})
Expand Down

0 comments on commit 0ffe81e

Please sign in to comment.