diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FilterPickerOption/index.js b/packages/strapi-plugin-content-manager/admin/src/components/FilterPickerOption/index.js index 73e7c977cd..4ff4e44f69 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FilterPickerOption/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FilterPickerOption/index.js @@ -47,7 +47,12 @@ function FilterPickerOption({ onClick={() => onRemoveFilter(index)} /> { + // Change the attribute + onChange(e); + // Change the default filter so it reset to the common one which is '=' + onChange({ target: { name: `${index}.filter`, value: '=' } }); + }} name={`${index}.name`} value={get(modifiedData, [index, 'name'], '')} selectOptions={allowedAttributes.map(attr => attr.name)} diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js index 202735dbe1..830797a613 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js @@ -451,6 +451,10 @@ function EditView({
{fields.map((fieldsRow, key) => { + if (fieldsRow.length === 0) { + return null; + } + const [{ name }] = fieldsRow; const group = get(layout, ['schema', 'attributes', name], {}); const groupMetas = get( diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/saga.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/saga.js index 21baa9c81b..87fa483d56 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/saga.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/saga.js @@ -1,6 +1,6 @@ import { all, fork, put, call, takeLatest } from 'redux-saga/effects'; import { request } from 'strapi-helper-plugin'; -import { set, unset } from 'lodash'; +import { clone, set, unset } from 'lodash'; import pluginId from '../../pluginId'; import { @@ -15,21 +15,22 @@ const getRequestUrl = path => `/${pluginId}/explorer/${path}`; // eslint-disable-next-line require-yield export function* getData({ uid, params }) { try { - const _start = (params._page - 1) * parseInt(params._limit, 10); + const clonedParams = clone(params); + const _start = (clonedParams._page - 1) * parseInt(clonedParams._limit, 10); - set(params, '_start', _start); - unset(params, '_page'); + set(clonedParams, '_start', _start); + unset(clonedParams, '_page'); - if (params._q === '') { - unset(params, '_q'); + if (clonedParams._q === '') { + unset(clonedParams, '_q'); } - const search = Object.keys(params) + const search = Object.keys(clonedParams) .reduce((acc, current) => { if (current !== 'filters') { - acc.push(`${current}=${params[current]}`); + acc.push(`${current}=${clonedParams[current]}`); } else { - const filters = params[current].reduce((acc, curr) => { + const filters = clonedParams[current].reduce((acc, curr) => { const key = curr.filter === '=' ? curr.name : `${curr.name}${curr.filter}`; acc.push(`${key}=${curr.value}`); diff --git a/packages/strapi-plugin-content-manager/admin/src/utils/search.js b/packages/strapi-plugin-content-manager/admin/src/utils/search.js index d0c543a698..74e1dd8bb4 100644 --- a/packages/strapi-plugin-content-manager/admin/src/utils/search.js +++ b/packages/strapi-plugin-content-manager/admin/src/utils/search.js @@ -1,4 +1,4 @@ -import { isEmpty } from 'lodash'; +import { isEmpty, toString } from 'lodash'; /** * Generate filters object from string * @param {String} search @@ -18,10 +18,31 @@ const generateFiltersFromSearch = search => { .reduce((acc, curr) => { const [name, value] = curr.split('='); const split = name.split('_'); - const filter = split.length > 1 ? `_${split[1]}` : '='; + let filter = `_${split[split.length - 1]}`; + + if ( + ![ + '_ne', + '_lt', + '_lte', + '_gt', + '_gte', + '_contains', + '_containss', + '_in', + '_nin', + ].includes(filter) + ) { + filter = '='; + } + const toSlice = filter === '=' ? split.length : split.length - 1; acc.push({ - name: split[0].replace('?', ''), + name: split + .slice(0, toSlice) + .join('_') + + .replace('?', ''), filter, value: decodeURIComponent(value), }); @@ -32,7 +53,7 @@ const generateFiltersFromSearch = search => { const generateSearchFromFilters = filters => { return Object.keys(filters) - .filter(key => !isEmpty(filters[key])) + .filter(key => !isEmpty(toString(filters[key]))) .map(key => { let ret = `${key}=${filters[key]}`; diff --git a/packages/strapi-plugin-content-manager/admin/src/utils/tests/search.test.js b/packages/strapi-plugin-content-manager/admin/src/utils/tests/search.test.js new file mode 100644 index 0000000000..21cb465e5d --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/utils/tests/search.test.js @@ -0,0 +1,103 @@ +import { + generateFiltersFromSearch, + generateSearchFromFilters, +} from '../search'; + +describe('Content Manager | utils | search', () => { + describe('generateFiltersFromSearch', () => { + it('should generate an array of filters', () => { + const search = + '?_sort=id:ASC&source=content-manager&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; + const expected = [ + { + name: 'bool', + filter: '=', + value: 'true', + }, + { + name: 'big_number', + filter: '_ne', + value: '1', + }, + { + name: 'created_at', + filter: '_lt', + value: '2019-08-01T00:00:00Z', + }, + { + name: 'date', + filter: '_lte', + value: '2019-08-02T00:00:00Z', + }, + { + name: 'decimal_number', + filter: '_gt', + value: '2', + }, + { + name: 'enum', + filter: '_ne', + value: 'noon', + }, + { + name: 'float_number', + filter: '_gte', + value: '3', + }, + ]; + + expect(generateFiltersFromSearch(search)).toEqual(expected); + }); + }); + + describe('generateSearchFromFilters', () => { + it('should return a string with all the applied filters', () => { + const data = { + _limit: 10, + _sort: 'id:ASC', + _page: 2, + source: 'content-manager', + filters: [ + { + name: 'bool', + filter: '=', + value: 'true', + }, + { + name: 'big_number', + filter: '_ne', + value: '1', + }, + { + name: 'created_at', + filter: '_lt', + value: '2019-08-01T00:00:00Z', + }, + { + name: 'date', + filter: '_lte', + value: '2019-08-02T00:00:00Z', + }, + { + name: 'decimal_number', + filter: '_gt', + value: '2', + }, + { + name: 'enum', + filter: '_ne', + value: 'noon', + }, + { + name: 'float_number', + filter: '_gte', + value: '3', + }, + ], + }; + const expected = + '_limit=10&_sort=id:ASC&_page=2&source=content-manager&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; + expect(generateSearchFromFilters(data)).toEqual(expected); + }); + }); +});