From 0ffe81e8c3ecad6c14868b6b7b4c60b763b69b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chalifour?= Date: Mon, 30 Sep 2019 13:05:18 +0200 Subject: [PATCH] refactor: change data structure to tuples --- src/lib/__tests__/InstantSearch-test.js | 8 +++- src/widgets/index/index.ts | 54 ++++++++++++++----------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/lib/__tests__/InstantSearch-test.js b/src/lib/__tests__/InstantSearch-test.js index 4f23ecca8c..549cea29ff 100644 --- a/src/lib/__tests__/InstantSearch-test.js +++ b/src/lib/__tests__/InstantSearch-test.js @@ -1220,6 +1220,9 @@ describe('UI state', () => { hierarchicalMenu: { categories: 'Mobile', }, + range: { + price: '100:200', + }, }, }, }); @@ -1241,6 +1244,7 @@ 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: @@ -1248,11 +1252,13 @@ If you do not wish to display widgets but still want to support their search par const virtualPagination = connectPagination(() => null); const virtualRefinementList = connectRefinementList(() => null); const virtualHierarchicalMenu = connectHierarchicalMenu(() => null); +const virtualRange = connectRange(() => null); search.addWidgets([ virtualPagination({ /* ... */ }), virtualRefinementList({ /* ... */ }), - virtualHierarchicalMenu({ /* ... */ }) + virtualHierarchicalMenu({ /* ... */ }), + virtualRange({ /* ... */ }) ]); \`\`\` diff --git a/src/widgets/index/index.ts b/src/widgets/index/index.ts index 8f4d4b591c..d9b249376a 100644 --- a/src/widgets/index/index.ts +++ b/src/widgets/index/index.ts @@ -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; }; @@ -370,8 +382,10 @@ const index = (props: IndexProps): Index => { .map(widget => widget.$$type) .filter(Boolean); + type MissingWidgets = Array<[string, Array]>; + const missingWidgets = Object.keys(localUiState).reduce< - Array> + MissingWidgets >((acc, parameter) => { const requiredWidgets: Array = stateToWidgetsMap[parameter]; @@ -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; @@ -398,15 +416,11 @@ 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')} @@ -414,11 +428,8 @@ If you do not wish to display widgets but still want to support their search par \`\`\` ${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);`; }) @@ -426,11 +437,8 @@ ${missingWidgets 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}({ /* ... */ })`; })