From 96a40a9bbeb66b45c0eaf8627cb80480e14e55f9 Mon Sep 17 00:00:00 2001 From: Bethany Dunfield Date: Wed, 10 Jan 2024 10:44:20 -0700 Subject: [PATCH] Migrate to react-query and updated endpoints (#188) * Install react-query and migrate search page * fix tests for search page * Upgrade dataset pages to use react-query. Remove resource reducer and deprecated code * Remove unused code and migrate last axios call to react-query * Update loading states * Update version and remove unused code * Fixes for tests * restore resource_reducer and manually control certain aspects of the table * Restore column ordering to resource_reducer and fix tests --- .gitignore | 3 +- package.json | 6 +- src/components/ColumnFilter/index.jsx | 24 +- .../DataTable/DataTablePageResults/index.jsx | 11 +- .../DataTablePageResults/index.test.jsx | 39 +- .../DataTable/DataTablePageSizer/index.jsx | 22 +- .../DataTablePageSizer/index.test.jsx | 40 +- .../DataTable/ManageColumns/index.jsx | 5 +- src/components/Organization/index.jsx | 47 +- src/components/Resource/index.jsx | 128 +---- src/components/Search/functions.js | 64 +-- src/components/Search/index.jsx | 137 +++-- src/components/Search/index.test.jsx | 84 +-- src/components/SearchResultsMessage/index.jsx | 4 +- src/index.ts | 6 - src/services/resource/api.js | 23 - src/services/resource/datastore.js | 136 ----- src/services/resource/resource_defaults.js | 5 +- src/services/resource/resource_functions.js | 126 +---- src/services/resource/resource_reducer.js | 46 +- src/services/search/doc.mdx | 4 - src/services/search/search_reducer.js | 57 --- src/services/search/search_reducer.test.js | 106 ---- src/services/useDatastore/fetch.js | 67 --- src/services/useDatastore/index.js | 1 - src/services/useDatastore/useDatastore.jsx | 112 ---- src/templates/DataTable/data.js | 12 +- src/templates/DataTable/datatable.scss | 4 +- src/templates/DataTable/index.jsx | 482 +++++++++++------- src/templates/DataTableHeader/index.jsx | 27 +- src/templates/NavBar/index.jsx | 2 +- src/templates/SearchContent/index.jsx | 23 +- src/templates/SearchSidebar/index.jsx | 69 +-- src/tests/utils.js | 1 + stories/dataset.stories.jsx | 9 +- yarn.lock | 83 +-- 36 files changed, 670 insertions(+), 1345 deletions(-) delete mode 100644 src/services/resource/api.js delete mode 100644 src/services/resource/datastore.js delete mode 100644 src/services/search/search_reducer.test.js delete mode 100644 src/services/useDatastore/fetch.js delete mode 100644 src/services/useDatastore/index.js delete mode 100644 src/services/useDatastore/useDatastore.jsx diff --git a/.gitignore b/.gitignore index 0ae596bf..56dc2b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ lib dist .parcel-cache/* -.DS_Store \ No newline at end of file +.DS_Store +.vscode \ No newline at end of file diff --git a/package.json b/package.json index f5a07c35..af25cf97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@civicactions/data-catalog-components", - "version": "1.17.1", + "version": "1.18.0", "description": "React Components for Open Data Catalogs.", "main": "dist/index.js", "source": "src/index.ts", @@ -26,7 +26,6 @@ "@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/react-fontawesome": "^0.2.0", "@tanstack/react-table": "^8.10.7", - "axios": "^1.6.2", "bootstrap": "^4.2.1", "excerpts": "0.0.3", "html-to-react": "^1.7.0", @@ -63,7 +62,8 @@ }, "peerDependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "@tanstack/react-query": "^5.14.1" }, "files": [ "lib", diff --git a/src/components/ColumnFilter/index.jsx b/src/components/ColumnFilter/index.jsx index e9ca8ff8..bca3265e 100644 --- a/src/components/ColumnFilter/index.jsx +++ b/src/components/ColumnFilter/index.jsx @@ -1,20 +1,26 @@ - import React from "react"; + import React, {useState, useEffect} from "react"; function ColumnFilter({ - column: { getFilterValue, setFilterValue, Header }, - resourceState + column, + count }) { + const [inputValue, setInputValue] = useState(column.getFilterValue() || '') + + useEffect(() => { + const delayedInputTimeout = setTimeout(() => { + column.setFilterValue(inputValue || ''); + }, 500) + return () => clearTimeout(delayedInputTimeout); + }, [inputValue, 500]); return ( { - e.preventDefault(); - e.stopPropagation(); - setFilterValue(e.target.value || undefined); // Set undefined to remove the filter entirely + setInputValue(e.target.value || '') }} - placeholder={`Search ${resourceState.count} records...`} + placeholder={`Search ${count} records...`} /> ); }; diff --git a/src/components/DataTable/DataTablePageResults/index.jsx b/src/components/DataTable/DataTablePageResults/index.jsx index 3d5dc727..40b754b3 100644 --- a/src/components/DataTable/DataTablePageResults/index.jsx +++ b/src/components/DataTable/DataTablePageResults/index.jsx @@ -1,13 +1,16 @@ -import React from 'react'; +import React, { useContext } from 'react'; +import { ResourceDispatch } from '../../../services/resource/resource_defaults'; import PropTypes from 'prop-types'; const DataTablePageResults = ({ total, - pageSize, - currentPage, className, viewing = false }) => { + const { resourceState } = useContext(ResourceDispatch); + const pageSize = resourceState.pageSize; + const currentPage = resourceState.currentPage + // Add one to offset the 0 array index. const page = currentPage + 1; let displayTotal = total; @@ -48,8 +51,6 @@ DataTablePageResults.defaultProps = { DataTablePageResults.propTypes = { className: PropTypes.string, total: PropTypes.number.isRequired, - pageSize: PropTypes.number.isRequired, - currentPage: PropTypes.number.isRequired, }; export default DataTablePageResults; diff --git a/src/components/DataTable/DataTablePageResults/index.test.jsx b/src/components/DataTable/DataTablePageResults/index.test.jsx index ea115b0c..75abb16c 100644 --- a/src/components/DataTable/DataTablePageResults/index.test.jsx +++ b/src/components/DataTable/DataTablePageResults/index.test.jsx @@ -1,39 +1,46 @@ import React from 'react'; import { render } from '@testing-library/react'; import DataTablePageResults from '.'; +import { ResourceDispatch, defaultResourceState } from '../../../services/resource/resource_defaults'; import { getByTextContent } from '../../../tests/utils'; describe('', () => { + const dispatch = jest.fn(); it('renders correct initial results', () => { + const resourceState = { + pageSize: 10, + currentPage: 0 + } render( - , + + + ); expect(getByTextContent('1 - 10 of 100 rows')).toBeInTheDocument(); }); it('renders correct results on subsequent pages', () => { + const resourceState = { + pageSize: 10, + currentPage: 4 + } render( - , + + + ); expect(getByTextContent('41 - 50 of 100 rows')).toBeInTheDocument(); }); it('Correctly displays appended viewing to results list', () => { + const resourceState = { + pageSize: 10, + currentPage: 4 + } render( - , + + + ); expect(getByTextContent('Viewing 41 - 50 of 100 rows')).toBeInTheDocument(); }) diff --git a/src/components/DataTable/DataTablePageSizer/index.jsx b/src/components/DataTable/DataTablePageSizer/index.jsx index 992aacc3..f2745c69 100644 --- a/src/components/DataTable/DataTablePageSizer/index.jsx +++ b/src/components/DataTable/DataTablePageSizer/index.jsx @@ -1,26 +1,28 @@ -import React from 'react'; +import React, {useContext} from 'react'; import PropTypes from 'prop-types'; +import { ResourceDispatch } from '../../../services/resource/resource_defaults'; const DataTablePageSizer = ({ label, - pageSizeChange, - initSize, options, className, selectClassName, id, }) => { - const [selValue, setSelValue] = React.useState(initSize); - React.useEffect(() => { - pageSizeChange(Number(selValue)); - }, [selValue]); + const {dispatch, resourceState} = useContext(ResourceDispatch); + return (
Sort by: + { - dispatch({ type: 'UPDATE_SORT', data: { sort: e.target.value } }); - }} + aria-labelledby='search-list-sort-label' + toggle={toggle} + isOpen={dropdownOpen} > - {sortOptions.map((sortOpt) => ( - - ))} - + {label} + + {sortOptions.map((sortOpt) => ( + { + dispatch({ type: 'UPDATE_SORT', data: { sort: sortOpt.field, "sort-order": sortOpt.order } }); + }} + > + {sortOpt.label} + + ))} + +
- {loading ? : - facetsResults && facetsResults.length - && ( - - ) + {loading || !facetsResults || !facetsResults.length ? + : + }
diff --git a/src/tests/utils.js b/src/tests/utils.js index 629712af..424a9cb1 100644 --- a/src/tests/utils.js +++ b/src/tests/utils.js @@ -1,6 +1,7 @@ import { screen } from '@testing-library/react'; export const getByTextContent = (text) => { + console.log(text) return screen.getByText((content, element) => { const hasText = element => element.textContent === text const elementHasText = hasText(element) diff --git a/stories/dataset.stories.jsx b/stories/dataset.stories.jsx index 67da2e44..2f519512 100755 --- a/stories/dataset.stories.jsx +++ b/stories/dataset.stories.jsx @@ -28,7 +28,6 @@ import tables from './data/tables.json'; import '../src/theme/styles/index.scss'; import TopicIcon from '../src/templates/TopicIcon'; import TopicWrapper from '../src/components/TopicWrapper'; -import { ResourceDispatch } from '../src/services/resource/resource_defaults'; import DataTable from '../src/templates/DataTable'; import { resourceData } from './data/resourceData'; @@ -179,11 +178,5 @@ storiesOf('Dataset', module) useSortBy, usePagination, ); - return ( - ({}), reactTable }} - > - - - ); + return ( ); }); diff --git a/yarn.lock b/yarn.lock index 05ef23d1..35ed111a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@adobe/css-tools@^4.3.1": +"@adobe/css-tools@^4.3.2": version "4.3.2" resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz" integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== @@ -2450,6 +2450,18 @@ resolved "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== +"@tanstack/query-core@5.14.1": + version "5.14.1" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.14.1.tgz" + integrity sha512-TlZarySCVEiap4K7BCvrsYZnX7jBbEkR55YMrk8ELcRbuAx6ydL+qoxqUt8Fq8VMvQyGt52icn6T7eJL1Q35KQ== + +"@tanstack/react-query@^5.14.1": + version "5.14.1" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.14.1.tgz" + integrity sha512-v7jhe/3jhChiR0XJbGHaG5WNPd/cURwzDGBCr4rzpUTeudPzxrtVRKsF1xJRLcJK3qH/0gIwTYHIPZ3gj+01Yw== + dependencies: + "@tanstack/query-core" "5.14.1" + "@tanstack/react-table@^8.10.7": version "8.10.7" resolved "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.10.7.tgz" @@ -2477,16 +2489,16 @@ pretty-format "^27.0.2" "@testing-library/jest-dom@^6.1.5": - version "6.1.5" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.5.tgz" - integrity sha512-3y04JLW+EceVPy2Em3VwNr95dOKqA8DhR0RJHhHKDZNYXcVXnEK7WIrpj4eYU8SVt/qYZ2aRWt/WgQ+grNES8g== + version "6.2.0" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.2.0.tgz" + integrity sha512-+BVQlJ9cmEn5RDMUS8c2+TU6giLvzaHZ8sU/x0Jj7fk+6/46wPdwlgOPcpxS17CjcanBi/3VmGMqVr2rmbUmNw== dependencies: - "@adobe/css-tools" "^4.3.1" + "@adobe/css-tools" "^4.3.2" "@babel/runtime" "^7.9.2" aria-query "^5.0.0" chalk "^3.0.0" css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" + dom-accessibility-api "^0.6.3" lodash "^4.17.15" redent "^3.0.0" @@ -2500,9 +2512,9 @@ "@types/react-dom" "^18.0.0" "@testing-library/user-event@^14.5.1": - version "14.5.1" - resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz" - integrity sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg== + version "14.5.2" + resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz" + integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== "@tootallnate/once@2": version "2.0.0" @@ -2531,9 +2543,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.7" - resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz" - integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== + version "7.6.8" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" @@ -2546,9 +2558,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.4" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" - integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: "@babel/types" "^7.20.7" @@ -2863,14 +2875,14 @@ acorn@^6.4.1: integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^8.1.0: - version "8.11.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + version "8.11.3" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== acorn@^8.8.1: - version "8.11.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + version "8.11.3" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== acorn@^8.8.2: version "8.11.2" @@ -2982,14 +2994,7 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.0.0: - version "5.3.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -aria-query@5.1.3: +aria-query@^5.0.0, aria-query@5.1.3: version "5.1.3" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== @@ -3079,7 +3084,7 @@ available-typed-arrays@^1.0.5: resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@^1.4.0, axios@^1.6.2: +axios@^1.4.0: version "1.6.2" resolved "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz" integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== @@ -4170,11 +4175,6 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - des.js@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz" @@ -4226,11 +4226,16 @@ dnd-core@^16.0.1: "@react-dnd/invariant" "^4.0.1" redux "^4.2.0" -dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: +dom-accessibility-api@^0.5.9: version "0.5.16" resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== +dom-accessibility-api@^0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz" + integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== + dom-helpers@^5.0.1: version "5.2.1" resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz" @@ -9235,9 +9240,9 @@ write-file-atomic@^4.0.2: signal-exit "^3.0.7" ws@^8.11.0: - version "8.15.1" - resolved "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz" - integrity sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ== + version "8.16.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== xml-but-prettier@^1.0.1: version "1.0.1"