Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
fix(state): nested attributes for faceting were not handled
Browse files Browse the repository at this point in the history
* fix nested attributes for faceting

* fix eslint issue

* fix: support multi indices
  • Loading branch information
linkesch authored and mthuret committed May 17, 2017
1 parent dd2c86f commit 11bd122
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 20 deletions.
65 changes: 58 additions & 7 deletions packages/react-instantsearch/src/core/indexUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ function refineSingleIndexWithNamespace(
};
}

function getNamespaceAndAttributeName(id) {
const parts = id.match(/^([^.]*)\.(.*)/);
const namespace = parts && parts[1];
const attributeName = parts && parts[2];

return { namespace, attributeName };
}

// eslint-disable-next-line max-params
export function getCurrentRefinementValue(
props,
Expand All @@ -125,24 +133,67 @@ export function getCurrentRefinementValue(
refinementsCallback
) {
const index = getIndex(context);
const { namespace, attributeName } = getNamespaceAndAttributeName(id);
const refinements =
(hasMultipleIndex(context) && has(searchState, `indices.${index}.${id}`)) ||
(hasMultipleIndex(context) &&
searchState.indices &&
namespace &&
has(searchState.indices[`${index}`][namespace], `${attributeName}`)) ||
(hasMultipleIndex(context) &&
searchState.indices &&
has(searchState, `indices.${index}.${id}`)) ||
(!hasMultipleIndex(context) &&
namespace &&
has(searchState[namespace], attributeName)) ||
(!hasMultipleIndex(context) && has(searchState, id));
if (refinements) {
const currentRefinement = hasMultipleIndex(context)
? get(searchState.indices[index], id)
: get(searchState, id);
let currentRefinement;

if (hasMultipleIndex(context)) {
currentRefinement = namespace
? get(searchState.indices[`${index}`][namespace], attributeName)
: get(searchState.indices[index], id);
} else {
currentRefinement = namespace
? get(searchState[namespace], attributeName)
: get(searchState, id);
}

return refinementsCallback(currentRefinement);
}

if (props.defaultRefinement) {
return props.defaultRefinement;
}

return defaultValue;
}

export function cleanUpValue(searchState, context, id) {
const index = getIndex(context);
return hasMultipleIndex(context)
? omit(searchState, `indices.${index}.${id}`)
: omit(searchState, `${id}`);
const { namespace, attributeName } = getNamespaceAndAttributeName(id);
if (hasMultipleIndex(context)) {
return namespace
? {
...searchState,
indices: {
...searchState.indices,
[index]: {
...searchState.indices[index],
[namespace]: omit(
searchState.indices[index][namespace],
`${attributeName}`
),
},
},
}
: omit(searchState, `indices.${index}.${id}`);
} else {
return namespace
? {
...searchState,
[namespace]: omit(searchState[namespace], `${attributeName}`),
}
: omit(searchState, `${id}`);
}
}
132 changes: 119 additions & 13 deletions packages/react-instantsearch/src/core/indexUtils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,15 @@ describe('utility method for manipulating the search state', () => {
last: 'last',
refinement: 'refinement',
another: 'another',
namespace: { refinement: 'refinement', another: 'another' },
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
};

expect.assertions(5); //async assertions

let expectedRefinement = value => expect(value).toEqual('refinement');

getCurrentRefinementValue(
Expand All @@ -129,13 +135,24 @@ describe('utility method for manipulating the search state', () => {
expectedRefinement
);

expectedRefinement = value => expect(value).toEqual('nested.another');

getCurrentRefinementValue(
{},
searchState,
context,
'namespace.nested.another',
null,
expectedRefinement
);

let value = getCurrentRefinementValue(
{},
{},
context,
'refinement',
'defaultValue',
expectedRefinement
() => {}
);

expect(value).toEqual('defaultValue');
Expand All @@ -146,7 +163,7 @@ describe('utility method for manipulating the search state', () => {
context,
'refinement',
null,
expectedRefinement
() => {}
);

expect(value).toEqual('defaultRefinement');
Expand All @@ -158,7 +175,11 @@ describe('utility method for manipulating the search state', () => {
last: 'last',
refinement: 'refinement',
another: 'another',
namespace: { refinement: 'refinement', another: 'another' },
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
};

searchState = cleanUpValue(searchState, context, 'refinement');
Expand All @@ -167,7 +188,11 @@ describe('utility method for manipulating the search state', () => {
page: 1,
last: 'last',
another: 'another',
namespace: { refinement: 'refinement', another: 'another' },
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
});

searchState = cleanUpValue(searchState, context, 'namespace.another');
Expand All @@ -176,11 +201,27 @@ describe('utility method for manipulating the search state', () => {
page: 1,
last: 'last',
another: 'another',
namespace: { refinement: 'refinement' },
namespace: {
refinement: 'refinement',
'nested.another': 'nested.another',
},
});

searchState = cleanUpValue(searchState, context, 'namespace.refinement');

expect(searchState).toEqual({
page: 1,
last: 'last',
another: 'another',
namespace: { 'nested.another': 'nested.another' },
});

searchState = cleanUpValue(
searchState,
context,
'namespace.nested.another'
);

expect(searchState).toEqual({
page: 1,
last: 'last',
Expand Down Expand Up @@ -297,11 +338,18 @@ describe('utility method for manipulating the search state', () => {
refinement: 'refinement',
indices: {
first: {
namespace: { refinement: 'refinement', another: 'another' },
refinement: 'refinement',
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
},
},
};

expect.assertions(6); //async assertions

let expectedRefinement = value => expect(value).toEqual('refinement');

getCurrentRefinementValue(
Expand All @@ -313,6 +361,17 @@ describe('utility method for manipulating the search state', () => {
expectedRefinement
);

expectedRefinement = value => expect(value).toEqual('refinement');

getCurrentRefinementValue(
{},
searchState,
context,
'namespace.refinement',
null,
expectedRefinement
);

expectedRefinement = value => expect(value).toEqual('another');

getCurrentRefinementValue(
Expand All @@ -324,13 +383,24 @@ describe('utility method for manipulating the search state', () => {
expectedRefinement
);

expectedRefinement = value => expect(value).toEqual('nested.another');

getCurrentRefinementValue(
{},
searchState,
context,
'namespace.nested.another',
null,
expectedRefinement
);

let value = getCurrentRefinementValue(
{},
{},
context,
'refinement',
'defaultValue',
expectedRefinement
() => {}
);

expect(value).toEqual('defaultValue');
Expand All @@ -341,7 +411,7 @@ describe('utility method for manipulating the search state', () => {
context,
'refinement',
null,
expectedRefinement
() => {}
);

expect(value).toEqual('defaultRefinement');
Expand All @@ -353,7 +423,11 @@ describe('utility method for manipulating the search state', () => {
indices: {
first: {
refinement: 'refinement',
namespace: { refinement: 'refinement', another: 'another' },
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
},
},
};
Expand All @@ -364,7 +438,11 @@ describe('utility method for manipulating the search state', () => {
page: 1,
indices: {
first: {
namespace: { refinement: 'refinement', another: 'another' },
namespace: {
refinement: 'refinement',
another: 'another',
'nested.another': 'nested.another',
},
},
},
});
Expand All @@ -373,14 +451,42 @@ describe('utility method for manipulating the search state', () => {

expect(searchState).toEqual({
page: 1,
indices: { first: { namespace: { refinement: 'refinement' } } },
indices: {
first: {
namespace: {
refinement: 'refinement',
'nested.another': 'nested.another',
},
},
},
});

searchState = cleanUpValue(searchState, context, 'namespace.refinement');

expect(searchState).toEqual({
page: 1,
indices: { first: { namespace: {} } },
indices: {
first: {
namespace: {
'nested.another': 'nested.another',
},
},
},
});

searchState = cleanUpValue(
searchState,
context,
'namespace.nested.another'
);

expect(searchState).toEqual({
page: 1,
indices: {
first: {
namespace: {},
},
},
});
});

Expand Down

0 comments on commit 11bd122

Please sign in to comment.