Skip to content

Commit

Permalink
feat: filter relation widget (decaporg#2405)
Browse files Browse the repository at this point in the history
  • Loading branch information
JimmyOei committed Mar 26, 2024
1 parent 590dfb2 commit d92a114
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 29 deletions.
6 changes: 3 additions & 3 deletions packages/decap-cms-widget-relation/src/RelationControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { components } from 'react-select';
import AsyncSelect from 'react-select/async';
import { debounce, filter, find, get, isEmpty, last, uniqBy } from 'lodash';
import { debounce, find, get, isEmpty, last, uniqBy } from 'lodash';
import { fromJS, List, Map } from 'immutable';
import { reactSelectStyles } from 'decap-cms-ui-default';
import { stringTemplate, validations } from 'decap-cms-lib-widgets';
Expand Down Expand Up @@ -379,10 +379,10 @@ export default class RelationControl extends React.Component {
const searchFieldsArray = getFieldArray(field.get('search_fields'));
const file = field.get('file');

query(forID, collection, searchFieldsArray, term, file, optionsLength).then(({ payload }) => {
query(forID, collection, searchFieldsArray, term, file).then(({ payload }) => {
const hits = payload.hits || [];
const options = this.parseHitOptions(hits);
const uniq = uniqOptions(this.state.initialOptions, options);
const uniq = uniqOptions(this.state.initialOptions, options).slice(0, optionsLength);
callback(uniq);
});
}, 500);
Expand Down
54 changes: 28 additions & 26 deletions packages/decap-cms-widget-relation/src/__tests__/relation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ const emptyFilterFieldConfig = {
],
};


function generateHits(length) {
const hits = Array.from({ length }, (val, idx) => {
const title = `Post # ${idx + 1}`;
Expand Down Expand Up @@ -247,11 +246,7 @@ class RelationController extends React.Component {
hits = [queryHits[queryHits.length - 4]];
}

console.log(hits.length)

hits = hits.slice(0, optionsLength);

console.log(hits.length, optionsLength)

this.setQueryHits(hits);

Expand Down Expand Up @@ -409,7 +404,9 @@ describe('Relation widget', () => {
const value = 'post-number-1';
const label = 'post-number-1 post-number-1 md';
const metadata = {
post: { posts: { 'post-number-1': { title: 'Post # 1', draft: true, slug: 'post-number-1' } } },
post: {
posts: { 'post-number-1': { title: 'Post # 1', draft: true, slug: 'post-number-1' } },
},
};

fireEvent.keyDown(input, { key: 'ArrowDown' });
Expand Down Expand Up @@ -553,64 +550,70 @@ describe('Relation widget', () => {
const field = fromJS(filterBooleanFieldConfig);
const { getAllByText, input } = setup({ field });
const expectedOptions = [];
for (let i = 2; i <= 20; i += 2) {
for (let i = 2; i <= 25; i += 2) {
expectedOptions.push(`Post # ${i} post-number-${i}`);
}
fireEvent.keyDown(input, { key: 'ArrowDown' });

await waitFor(() => {
const displayedOptions = getAllByText(/^Post # (\d{1,2}) post-number-\1$/);
expect(displayedOptions).toHaveLength(expectedOptions.length);
for (let i = 0; i < expectedOptions.length; i++) {
for (let i = 0; i < expectedOptions.length; i++) {
const expectedOption = expectedOptions[i];
const optionFound = displayedOptions.some(option => option.textContent === expectedOption);
const optionFound = displayedOptions.some(
option => option.textContent === expectedOption,
);
expect(optionFound).toBe(true);
}
}
});
});

it('should list the 5 option hits on initial load using a filter on string value', async () => {
const field = fromJS(filterStringFieldConfig);
const { getAllByText, input } = setup({ field });
const expectedOptions = [
'Post # 1 post-number-1',
'Post # 2 post-number-2',
'Post # 7 post-number-7',
'Post # 9 post-number-9',
'Post # 15 post-number-15'
'Post # 1 post-number-1',
'Post # 2 post-number-2',
'Post # 7 post-number-7',
'Post # 9 post-number-9',
'Post # 15 post-number-15',
];
fireEvent.keyDown(input, { key: 'ArrowDown' });

await waitFor(() => {
const displayedOptions = getAllByText(/^Post # (\d{1,2}) post-number-\1$/);
expect(displayedOptions).toHaveLength(expectedOptions.length);
for (let i = 0; i < expectedOptions.length; i++) {
for (let i = 0; i < expectedOptions.length; i++) {
const expectedOption = expectedOptions[i];
const optionFound = displayedOptions.some(option => option.textContent === expectedOption);
const optionFound = displayedOptions.some(
option => option.textContent === expectedOption,
);
expect(optionFound).toBe(true);
}
}
});
});

it('should list 4 option hits on initial load using multiple filters', async () => {
const field = fromJS(multipleFiltersFieldConfig);
const { getAllByText, input } = setup({ field });
const expectedOptions = [
'Post # 1 post-number-1',
'Post # 7 post-number-7',
'Post # 9 post-number-9',
'Post # 15 post-number-15'
'Post # 1 post-number-1',
'Post # 7 post-number-7',
'Post # 9 post-number-9',
'Post # 15 post-number-15',
];
fireEvent.keyDown(input, { key: 'ArrowDown' });

await waitFor(() => {
const displayedOptions = getAllByText(/^Post # (\d{1,2}) post-number-\1$/);
expect(displayedOptions).toHaveLength(expectedOptions.length);
for (let i = 0; i < expectedOptions.length; i++) {
for (let i = 0; i < expectedOptions.length; i++) {
const expectedOption = expectedOptions[i];
const optionFound = displayedOptions.some(option => option.textContent === expectedOption);
const optionFound = displayedOptions.some(
option => option.textContent === expectedOption,
);
expect(optionFound).toBe(true);
}
}
});
});

Expand All @@ -623,6 +626,5 @@ describe('Relation widget', () => {
expect(() => getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toThrow(Error);
});
});

});
});

0 comments on commit d92a114

Please sign in to comment.