diff --git a/app/client/package-lock.json b/app/client/package-lock.json index 520ff827c..05083ad47 100644 --- a/app/client/package-lock.json +++ b/app/client/package-lock.json @@ -41,7 +41,7 @@ "react-sticky-box": "2.0.5", "react-switch": "7.0.0", "react-table": "7.8.0", - "react-window": "1.8.10", + "react-virtuoso": "4.6.2", "smoothscroll-polyfill": "0.4.4", "uuid": "9.0.1" }, @@ -58,7 +58,6 @@ "@types/react": "18.2.47", "@types/react-dom": "18.2.18", "@types/react-ranger": "2.0.4", - "@types/react-window": "1.8.8", "@types/smoothscroll-polyfill": "0.3.3", "@types/uuid": "9.0.7", "husky": "8.0.3", @@ -5303,15 +5302,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-window": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", - "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -17826,27 +17816,18 @@ "react-dom": ">=16.13" } }, - "node_modules/react-window": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", - "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", - "dependencies": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - }, + "node_modules/react-virtuoso": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.6.2.tgz", + "integrity": "sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ==", "engines": { - "node": ">8.0.0" + "node": ">=10" }, "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + "react": ">=16 || >=17 || >= 18", + "react-dom": ">=16 || >=17 || >= 18" } }, - "node_modules/react-window/node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -24714,15 +24695,6 @@ "@types/react": "*" } }, - "@types/react-window": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", - "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -33693,21 +33665,10 @@ "debounce": "^1.2.1" } }, - "react-window": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", - "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", - "requires": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - }, - "dependencies": { - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - } - } + "react-virtuoso": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.6.2.tgz", + "integrity": "sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ==" }, "read-cache": { "version": "1.0.0", diff --git a/app/client/package.json b/app/client/package.json index 12b9ac85b..e556a8474 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -48,7 +48,6 @@ "@types/react": "18.2.47", "@types/react-dom": "18.2.18", "@types/react-ranger": "2.0.4", - "@types/react-window": "1.8.8", "@types/smoothscroll-polyfill": "0.3.3", "@types/uuid": "9.0.7", "husky": "8.0.3", @@ -90,7 +89,7 @@ "react-sticky-box": "2.0.5", "react-switch": "7.0.0", "react-table": "7.8.0", - "react-window": "1.8.10", + "react-virtuoso": "4.6.2", "smoothscroll-polyfill": "0.4.4", "uuid": "9.0.1" }, diff --git a/app/client/src/components/pages/StateTribal.Tabs.AdvancedSearch.js b/app/client/src/components/pages/StateTribal.Tabs.AdvancedSearch.js index a6b884284..a6813914d 100644 --- a/app/client/src/components/pages/StateTribal.Tabs.AdvancedSearch.js +++ b/app/client/src/components/pages/StateTribal.Tabs.AdvancedSearch.js @@ -1,7 +1,7 @@ // @flow /** @jsxImportSource @emotion/react */ -import { useContext, useEffect, useState } from 'react'; +import { useContext, useEffect, useMemo, useState } from 'react'; import { css } from '@emotion/react'; import { useWindowSize } from '@reach/window-size'; import Select, { createFilter } from 'react-select'; @@ -9,8 +9,8 @@ import * as query from '@arcgis/core/rest/query'; // components import LoadingSpinner from 'components/shared/LoadingSpinner'; import { GlossaryTerm } from 'components/shared/GlossaryPanel'; -import MenuList from 'components/shared/MenuList'; import Modal from 'components/shared/Modal'; +import PaginatedSelect from 'components/shared/PaginatedSelect'; import StateMap from 'components/shared/StateMap'; import WaterbodyListVirtualized from 'components/shared/WaterbodyListVirtualized'; // styled components @@ -344,6 +344,13 @@ function AdvancedSearch() { // get a list of watersheds and build the esri where clause const [watersheds, setWatersheds] = useState(null); + const watershedOptions = useMemo(() => { + return watersheds + ? watersheds + .filter((watershed) => watershed.label) // filter out nulls + .sort((a, b) => a.label.localeCompare(b.label)) + : []; + }, [watersheds]); useEffect(() => { if (activeState.value === '' || !watershedsLayerMaxRecordCount) return; @@ -407,6 +414,11 @@ function AdvancedSearch() { // these lists just have the name and id for faster load time const [waterbodiesList, setWaterbodiesList] = useState(null); + const waterbodiesOptions = useMemo(() => { + return waterbodiesList + ? waterbodiesList.sort((a, b) => a.label.localeCompare(b.label)) + : []; + }, [waterbodiesList]); // Get the features on the waterbodies point layer useEffect(() => { if (!stateAndOrganization || !summaryLayerMaxRecordCount) { @@ -844,43 +856,27 @@ function AdvancedSearch() { : - a.label.localeCompare(b.label)) - : [] - } - value={waterbodyFilter} + inputId="waterbodies" + isLoading={!waterbodiesList} onChange={(ev) => setWaterbodyFilter(ev)} - styles={reactSelectStyles} + options={waterbodiesOptions} + value={waterbodyFilter} /> diff --git a/app/client/src/components/shared/CharacteristicsSelect.tsx b/app/client/src/components/shared/CharacteristicsSelect.tsx index 5dd1fadba..0bf7134d8 100644 --- a/app/client/src/components/shared/CharacteristicsSelect.tsx +++ b/app/client/src/components/shared/CharacteristicsSelect.tsx @@ -1,17 +1,16 @@ /** @jsxImportSource @emotion/react */ import { useContext, useMemo } from 'react'; -import Select from 'react-select'; import { css } from '@emotion/react'; // components import { GlossaryTerm } from 'components/shared/GlossaryPanel'; -import MenuList from 'components/shared/MenuList'; +import PaginatedSelect from 'components/shared/PaginatedSelect'; // contexts import { LocationSearchContext } from 'contexts/locationSearch'; // utils import { useMonitoringLocations } from 'utils/hooks'; // styles -import { groupHeadingStyles, reactSelectStyles } from 'styles/index'; +import { groupHeadingStyles } from 'styles/index'; export default CharacteristicsSelect; export function CharacteristicsSelect({ @@ -66,19 +65,16 @@ export function CharacteristicsSelect({ Filter by{' '} Characteristics: - { + setInputValue(newValue); + setStartIndex(0); + }} + onMenuClose={() => { + setInputValue(''); + setStartIndex(0); + }} + options={optionsOrGroupsPage} + styles={{ + ...reactSelectStyles, + ...styles, + }} + {...rest} + /> + ); +} + +function wrapMenuList(loadPrevious: () => boolean, loadNext: () => boolean) { + return (props: MenuListProps