diff --git a/packages/strapi-admin/package.json b/packages/strapi-admin/package.json index 4e229bc0c5..4f0df741e0 100644 --- a/packages/strapi-admin/package.json +++ b/packages/strapi-admin/package.json @@ -70,6 +70,7 @@ "p-map": "4.0.0", "passport-local": "1.0.0", "prop-types": "^15.7.2", + "qs": "6.9.4", "react": "^16.13.1", "react-copy-to-clipboard": "^5.0.1", "react-dnd": "^10.0.2", diff --git a/packages/strapi-admin/webpack.alias.js b/packages/strapi-admin/webpack.alias.js index 78263a67b9..132cf8e9e8 100644 --- a/packages/strapi-admin/webpack.alias.js +++ b/packages/strapi-admin/webpack.alias.js @@ -18,6 +18,7 @@ const alias = [ 'immutable', 'invariant', 'moment', + 'qs', 'react', 'react-copy-to-clipboard', 'react-dnd', diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js b/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js index 560631bc4e..855d621939 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js @@ -45,13 +45,16 @@ class Search extends React.Component { this.triggerChange(''); }; - triggerChange = value => - this.props.changeParams({ - target: { - name: '_q', - value, + triggerChange = value => { + const method = value ? 'push' : 'remove'; + + this.props.changeParams( + { + _q: value, }, - }); + method + ); + }; render() { const { model } = this.props; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/Footer.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/Footer.js index 7243c091ec..05b9db28aa 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/Footer.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/Footer.js @@ -1,21 +1,23 @@ import React, { memo } from 'react'; import { FormattedMessage } from 'react-intl'; +import PropTypes from 'prop-types'; import { GlobalPagination, InputSelect, useGlobalContext } from 'strapi-helper-plugin'; -import useListView from '../../hooks/useListView'; + import { FooterWrapper, SelectWrapper, Label } from './components'; -function Footer() { +function Footer({ count, onChange, params }) { const { emitEvent } = useGlobalContext(); - const { count, onChangeSearch, _limit, _page } = useListView(); + const _limit = parseInt(params.pageSize, 10); + const _page = parseInt(params.page, 10); const handleChangePage = ({ target: { value } }) => { - onChangeSearch({ target: { name: '_page', value } }); + onChange({ page: value }); }; const handleChangeLimit = ({ target: { value } }) => { emitEvent('willChangeNumberOfEntriesPerPage'); - onChangeSearch({ target: { name: '_limit', value } }); + onChange({ pageSize: value }); }; return ( @@ -49,4 +51,10 @@ function Footer() { ); } +Footer.propTypes = { + count: PropTypes.number.isRequired, + onChange: PropTypes.func.isRequired, + params: PropTypes.object.isRequired, +}; + export default memo(Footer); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js index e0fda77a2c..ed66b563c8 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js @@ -17,6 +17,7 @@ import { } from 'strapi-helper-plugin'; import pluginId from '../../pluginId'; import pluginPermissions from '../../permissions'; +import { useQueryParams } from '../../hooks'; import { generatePermissionsObject, getRequestUrl, getTrad } from '../../utils'; import DisplayedFieldsDropdown from '../../components/DisplayedFieldsDropdown'; @@ -88,13 +89,34 @@ function ListView({ onResetListHeaders, setLayout, }) { + const { + contentType: { + attributes, + settings: { + defaultSortBy, + defaultSortOrder, + bulkable: isBulkable, + filterable: isFilterable, + searchable: isSearchable, + pageSize: defaultPageSize, + // mainField, + }, + }, + } = layout; + const { emitEvent } = useGlobalContext(); const viewPermissions = useMemo(() => generatePermissionsObject(slug), [slug]); const { isLoading: isLoadingForPermissions, allowedActions: { canCreate, canRead, canUpdate, canDelete }, } = useUserPermissions(viewPermissions); - const query = useQuery(); + // const query = useQuery(); + const defaultSort = `${defaultSortBy}:${defaultSortOrder}`; + const [{ query, rawQuery }, setQuery] = useQueryParams({ + page: 1, + pageSize: defaultPageSize, + _sort: defaultSort, + }); const { pathname, search } = useLocation(); const { push } = useHistory; @@ -105,88 +127,41 @@ function ListView({ const [idToDelete, setIdToDelete] = useState(null); const contentType = layout.contentType; - const { - contentType: { - attributes, - settings: { - defaultSortBy, - defaultSortOrder, - bulkable: isBulkable, - filterable: isFilterable, - searchable: isSearchable, - pageSize, - // mainField, - }, - }, - } = layout; const hasDraftAndPublish = contentType.options.draftAndPublish; - const defaultSort = `${defaultSortBy}:${defaultSortOrder}`; + const allAllowedHeaders = getAllAllowedHeaders(attributes); - const filters = useMemo(() => { - const currentSearch = new URLSearchParams(search); + const filters = query._where || []; - // Delete all params that are not related to the filters - const paramsToDelete = ['_limit', '_page', '_sort', '_q']; + const _limit = parseInt(query.pageSize, 10); + const _page = parseInt(query.page, 10); + const _sort = query._sort; + const _q = query._q || ''; - for (let i = 0; i < paramsToDelete.length; i++) { - currentSearch.delete(paramsToDelete[i]); - } - - return generateFiltersFromSearch(currentSearch.toString()); - }, [search]); - - // TODO - const _limit = pageSize; - // const _limit = useMemo(() => { - // return parseInt(query.get('_limit') || pageSize, 10); - // }, [pageSize, query]); - // TODO - const _q = query.get('_q') || ''; - // TODO - const _page = parseInt(query.get('_page') || 1, 10); - - // TODO - const _sort = query.get('_sort') || defaultSort; const label = contentType.info.label; - const _start = useMemo(() => { - return (_page - 1) * parseInt(_limit, 10); - }, [_limit, _page]); + const searchToSendForRequest = rawQuery; + // const searchToSendForRequest = useMemo(() => { + // const currentSearch = new URLSearchParams(search); - const searchToSendForRequest = useMemo(() => { - const currentSearch = new URLSearchParams(search); + // currentSearch.set('_limit', _limit); + // currentSearch.set('_sort', _sort); + // currentSearch.set('_start', _start); + // currentSearch.delete('_page'); - currentSearch.set('_limit', _limit); - currentSearch.set('_sort', _sort); - currentSearch.set('_start', _start); - currentSearch.delete('_page'); + // return currentSearch.toString(); + // }, [_limit, _sort, _start, search]); - return currentSearch.toString(); - }, [_limit, _sort, _start, search]); - - const getDataActionRef = useRef(getData); + // const getDataActionRef = useRef(getData); const getDataSucceededRef = useRef(getDataSucceeded); const shouldSendRequest = useMemo(() => { return !isLoadingForPermissions && canRead; }, [canRead, isLoadingForPermissions]); - const fetchData = async (search = searchToSendForRequest) => { + const fetchData = async () => { try { - // getDataActionRef.current(); - // const [{ count }, data] = await Promise.all([ - // request(getRequestUrl(`explorer/${slug}/count?${search}`), { - // method: 'GET', - // }), - // request(getRequestUrl(`explorer/${slug}?${search}`), { - // method: 'GET', - // }), - // ]); - - // const c = await request(getRequestUrl(`collection-types/${slug}?${search}`)); - // console.log({ c }); const data = [ { id: 16, @@ -231,8 +206,6 @@ function ListView({ }; useEffect(() => { - // TODO - console.log('up'); setLayout(layout); }, [layout, setLayout]); @@ -354,23 +327,23 @@ function ListView({ [displayedHeaders, onChangeListHeaders] ); - const handleChangeFilters = ({ target: { value } }) => { - const newSearch = new URLSearchParams(); + // const handleChangeFilters = ({ target: { value } }) => { + // const newSearch = new URLSearchParams(); - // Set the default params - newSearch.set('_limit', _limit); - newSearch.set('_sort', _sort); - newSearch.set('_page', 1); + // // Set the default params + // newSearch.set('_limit', _limit); + // newSearch.set('_sort', _sort); + // newSearch.set('_page', 1); - value.forEach(({ filter, name, value: filterValue }) => { - const filterType = filter === '=' ? '' : filter; - const filterName = `${name}${filterType}`; + // value.forEach(({ filter, name, value: filterValue }) => { + // const filterType = filter === '=' ? '' : filter; + // const filterName = `${name}${filterType}`; - newSearch.append(filterName, filterValue); - }); + // newSearch.append(filterName, filterValue); + // }); - push({ search: newSearch.toString() }); - }; + // push({ search: newSearch.toString() }); + // }; const handleChangeSearch = async ({ target: { name, value } }) => { const currentSearch = new URLSearchParams(searchToSendForRequest); @@ -403,7 +376,7 @@ function ListView({ const handleSubmit = (filters = []) => { emitEvent('didFilterEntries'); toggleFilterPickerState(); - handleChangeFilters({ target: { name: 'filters', value: filters } }); + // handleChangeFilters({ target: { name: 'filters', value: filters } }); }; const toggleFilterPickerState = () => { @@ -421,7 +394,7 @@ function ListView({ onClick: () => { toggleFilterPickerState(); // Delete all filters - handleChangeFilters({ target: { name: 'filters', value: [] } }); + // handleChangeFilters({ target: { name: 'filters', value: [] } }); }, }, { @@ -496,7 +469,9 @@ function ListView({ <> {!isFilterPickerOpen &&
} {isSearchable && canRead && ( - + )} {canRead && ( @@ -542,7 +519,7 @@ function ListView({ {filters.map((filter, key) => ( -