From f9dd5b52afd8341103a818b10cbf8bb9d5f3340b Mon Sep 17 00:00:00 2001 From: Tai Wilkin-Corraggio Date: Fri, 18 Mar 2022 16:50:01 -0400 Subject: [PATCH 1/6] Remove extended fetches from search tab --- src/app/src/actions/filterOptions.js | 3 +- src/app/src/components/FilterSidebar.jsx | 69 ++---------------------- 2 files changed, 4 insertions(+), 68 deletions(-) diff --git a/src/app/src/actions/filterOptions.js b/src/app/src/actions/filterOptions.js index 1072631d0..a7e370c14 100644 --- a/src/app/src/actions/filterOptions.js +++ b/src/app/src/actions/filterOptions.js @@ -244,10 +244,9 @@ export function fetchNumberOfWorkersOptions() { }; } -export function fetchAllFilterOptions() { +export function fetchAllPrimaryFilterOptions() { return dispatch => { dispatch(fetchContributorOptions()); - dispatch(fetchContributorTypeOptions()); dispatch(fetchCountryOptions()); dispatch(fetchListOptions()); }; diff --git a/src/app/src/components/FilterSidebar.jsx b/src/app/src/components/FilterSidebar.jsx index aaf067506..1df345fd9 100644 --- a/src/app/src/components/FilterSidebar.jsx +++ b/src/app/src/components/FilterSidebar.jsx @@ -30,21 +30,13 @@ import { import { fetchContributorOptions, fetchListOptions, - fetchContributorTypeOptions, fetchCountryOptions, - fetchFacilityProcessingTypeOptions, - fetchProductTypeOptions, - fetchNumberOfWorkersOptions, - fetchAllFilterOptions, + fetchAllPrimaryFilterOptions, } from '../actions/filterOptions'; import { contributorOptionsPropType, - contributorTypeOptionsPropType, countryOptionsPropType, - facilityProcessingTypeOptionsPropType, - productTypeOptionsPropType, - numberOfWorkerOptionsPropType, } from '../util/propTypes'; import { allListsAreEmpty } from '../util/util'; @@ -67,32 +59,15 @@ class FilterSidebar extends Component { componentDidMount() { const { contributorsData, - contributorTypesData, countriesData, - facilityProcessingTypeData, - productTypeData, - numberOfWorkersData, fetchFilterOptions, fetchContributors, fetchLists, - fetchContributorTypes, fetchCountries, - fetchFacilityProcessingType, - fetchProductType, - fetchNumberOfWorkers, contributors, } = this.props; - if ( - allListsAreEmpty( - contributorsData, - contributorTypesData, - countriesData, - facilityProcessingTypeData, - productTypeData, - numberOfWorkersData, - ) - ) { + if (allListsAreEmpty(contributorsData, countriesData)) { return fetchFilterOptions(); } @@ -100,26 +75,10 @@ class FilterSidebar extends Component { fetchContributors(); } - if (!contributorTypesData.length) { - fetchContributorTypes(); - } - if (!countriesData.length) { fetchCountries(); } - if (!facilityProcessingTypeData.length) { - fetchFacilityProcessingType(); - } - - if (!productTypeData.length) { - fetchProductType(); - } - - if (!numberOfWorkersData.length) { - fetchNumberOfWorkers(); - } - if (contributors && contributors.length) { fetchLists(); } @@ -266,18 +225,9 @@ FilterSidebar.propTypes = { makeFacilitiesTabActive: func.isRequired, fetchFilterOptions: func.isRequired, fetchContributors: func.isRequired, - fetchContributorTypes: func.isRequired, fetchCountries: func.isRequired, - fetchFacilityProcessingType: func.isRequired, - fetchProductType: func.isRequired, - fetchNumberOfWorkers: func.isRequired, contributorsData: contributorOptionsPropType.isRequired, - contributorTypesData: contributorTypeOptionsPropType.isRequired, countriesData: countryOptionsPropType.isRequired, - facilityProcessingTypeData: - facilityProcessingTypeOptionsPropType.isRequired, - productTypeData: productTypeOptionsPropType.isRequired, - numberOfWorkersData: numberOfWorkerOptionsPropType.isRequired, vectorTileFeatureIsActive: bool.isRequired, fetchingFeatureFlags: bool.isRequired, }; @@ -287,11 +237,7 @@ function mapStateToProps({ filterOptions: { contributors: { data: contributorsData }, lists: { data: listsData }, - contributorTypes: { data: contributorTypesData }, countries: { data: countriesData }, - facilityProcessingType: { data: facilityProcessingTypeData }, - productType: { data: productTypeData }, - numberOfWorkers: { data: numberOfWorkersData }, }, featureFlags: { flags, fetching: fetchingFeatureFlags }, embeddedMap: { embed }, @@ -303,11 +249,7 @@ function mapStateToProps({ return { activeFilterSidebarTab, contributorsData, - contributorTypesData, countriesData, - facilityProcessingTypeData, - productTypeData, - numberOfWorkersData, listsData, vectorTileFeatureIsActive: get(flags, 'vector_tile', false), fetchingFeatureFlags, @@ -323,15 +265,10 @@ function mapDispatchToProps(dispatch) { makeSearchTabActive: () => dispatch(makeSidebarSearchTabActive()), makeFacilitiesTabActive: () => dispatch(makeSidebarFacilitiesTabActive()), - fetchFilterOptions: () => dispatch(fetchAllFilterOptions()), + fetchFilterOptions: () => dispatch(fetchAllPrimaryFilterOptions()), fetchContributors: () => dispatch(fetchContributorOptions()), fetchLists: () => dispatch(fetchListOptions()), - fetchContributorTypes: () => dispatch(fetchContributorTypeOptions()), fetchCountries: () => dispatch(fetchCountryOptions()), - fetchFacilityProcessingType: () => - dispatch(fetchFacilityProcessingTypeOptions()), - fetchProductType: () => dispatch(fetchProductTypeOptions()), - fetchNumberOfWorkers: () => dispatch(fetchNumberOfWorkersOptions()), }; } From dc12b1dc3fd5e054f19621c7fa1a146af56c0658 Mon Sep 17 00:00:00 2001 From: Tai Wilkin-Corraggio Date: Fri, 18 Mar 2022 17:22:03 -0400 Subject: [PATCH 2/6] Move extended field fetching to new component --- .../FilterSidebarExtendedSearch.jsx | 476 ++++++++++++++++++ .../src/components/FilterSidebarSearchTab.jsx | 358 +------------ 2 files changed, 486 insertions(+), 348 deletions(-) create mode 100644 src/app/src/components/FilterSidebarExtendedSearch.jsx diff --git a/src/app/src/components/FilterSidebarExtendedSearch.jsx b/src/app/src/components/FilterSidebarExtendedSearch.jsx new file mode 100644 index 000000000..7246227ba --- /dev/null +++ b/src/app/src/components/FilterSidebarExtendedSearch.jsx @@ -0,0 +1,476 @@ +import React, { useEffect } from 'react'; +import { bool, func } from 'prop-types'; +import { connect } from 'react-redux'; +import InputLabel from '@material-ui/core/InputLabel'; +import Button from '@material-ui/core/Button'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import ReactSelect from 'react-select'; +import Creatable from 'react-select/creatable'; +import Divider from '@material-ui/core/Divider'; +import { withStyles } from '@material-ui/core/styles'; +import uniq from 'lodash/uniq'; + +import ShowOnly from './ShowOnly'; + +import { + updateContributorTypeFilter, + updateParentCompanyFilter, + updateFacilityTypeFilter, + updateProcessingTypeFilter, + updateProductTypeFilter, + updateNumberofWorkersFilter, + updateNativeLanguageNameFilter, + updateBoundaryFilter, +} from '../actions/filters'; + +import { + fetchContributorTypeOptions, + fetchFacilityProcessingTypeOptions, + fetchProductTypeOptions, + fetchNumberOfWorkersOptions, +} from '../actions/filterOptions'; + +import { fetchFacilities } from '../actions/facilities'; + +import { showDrawFilter } from '../actions/ui'; + +import { + contributorOptionsPropType, + contributorTypeOptionsPropType, + facilityTypeOptionsPropType, + processingTypeOptionsPropType, + facilityProcessingTypeOptionsPropType, + productTypeOptionsPropType, + numberOfWorkerOptionsPropType, +} from '../util/propTypes'; + +import { filterSidebarStyles } from '../util/styles'; + +import { + getValueFromEvent, + mapDjangoChoiceTuplesValueToSelectOptions, +} from '../util/util'; + +const filterSidebarSearchTabStyles = theme => + Object.freeze({ + formStyle: Object.freeze({ + width: '100%', + marginBottom: '32px', + }), + inputLabelStyle: Object.freeze({ + fontFamily: theme.typography.fontFamily, + fontSize: '16px', + fontWeight: 500, + color: '#000', + transform: 'translate(0, -8px) scale(1)', + paddingBottom: '0.5rem', + }), + helpSubheadStyle: Object.freeze({ + fontFamily: theme.typography.fontFamily, + ontSize: '12px', + fontWeight: 500, + color: '#000', + paddingTop: '0.5rem', + paddingBottom: '0.5rem', + }), + selectStyle: Object.freeze({ + fontFamily: theme.typography.fontFamily, + }), + font: Object.freeze({ + fontFamily: `${theme.typography.fontFamily} !important`, + }), + reset: Object.freeze({ + marginLeft: '16px', + minWidth: '36px', + minHeight: '36px', + }), + ...filterSidebarStyles, + }); + +const CONTRIBUTORS = 'CONTRIBUTORS'; +const CONTRIBUTOR_TYPES = 'CONTRIBUTOR_TYPES'; +const PARENT_COMPANY = 'PARENT_COMPANY'; +const FACILITY_TYPE = 'FACILITY_TYPE'; +const PROCESSING_TYPE = 'PROCESSING_TYPE'; +const PRODUCT_TYPE = 'PRODUCT_TYPE'; +const NUMBER_OF_WORKERS = 'NUMBER_OF_WORKERS'; + +const mapFacilityTypeOptions = (fPTypes, pTypes) => { + let fTypes = []; + if (pTypes.length === 0) { + fTypes = fPTypes.map(type => type.facilityType); + } else { + // When there are processing types, only return the + // facility types that have those processing types + pTypes.forEach(pType => { + fPTypes.forEach(fPType => { + if (fPType.processingTypes.includes(pType.value)) { + fTypes = fTypes.concat(fPType.facilityType); + } + }); + }); + } + return mapDjangoChoiceTuplesValueToSelectOptions(uniq(fTypes.sort())); +}; + +const mapProcessingTypeOptions = (fPTypes, fTypes) => { + let pTypes = []; + if (fTypes.length === 0) { + pTypes = fPTypes.map(type => type.processingTypes).flat(); + } else { + // When there are facility types, only return the + // processing types that are under those facility types + fTypes.forEach(fType => { + fPTypes.forEach(fPType => { + if (fType.value === fPType.facilityType) { + pTypes = pTypes.concat(fPType.processingTypes); + } + }); + }); + } + return mapDjangoChoiceTuplesValueToSelectOptions(uniq(pTypes.sort())); +}; + +function FilterSidebarSearchTab({ + contributorOptions, + contributorTypeOptions, + facilityProcessingTypeOptions, + productTypeOptions, + numberOfWorkersOptions, + contributorTypes, + updateContributorType, + parentCompany, + updateParentCompany, + facilityType, + updateFacilityType, + processingType, + updateProcessingType, + productType, + updateProductType, + numberOfWorkers, + updateNumberOfWorkers, + fetchingFacilities, + fetchingExtendedOptions, + activateDrawFilter, + clearDrawFilter, + boundary, + embed, + classes, + fetchContributorTypes, + fetchFacilityProcessingType, + fetchProductType, + fetchNumberOfWorkers, +}) { + useEffect(() => { + if (!contributorTypeOptions.length) { + fetchContributorTypes(); + } + + if (!facilityProcessingTypeOptions.length) { + fetchFacilityProcessingType(); + } + + if (!productTypeOptions.length) { + fetchProductType(); + } + + if (!numberOfWorkersOptions.length) { + fetchNumberOfWorkers(); + } + }, []); + + if (fetchingExtendedOptions) { + return ( +
+ +
+ ); + } + + const boundaryButton = + boundary == null ? ( + + ) : ( + + ); + + return ( + <> +
+ + + Contributor Type + + + +
+
+ + Area + + {boundaryButton} +
+
+ +
+ The following filters are new to the OAR and may not return + complete results until we have more data +
+
+
+ + Parent Company + + +
+
+ + Facility Type + + +
+
+ + Processing Type + + +
+
+ + Product Type + + +
+
+ + Number of Workers + + +
+ + ); +} + +FilterSidebarSearchTab.propTypes = { + contributorOptions: contributorOptionsPropType.isRequired, + contributorTypeOptions: contributorTypeOptionsPropType.isRequired, + facilityProcessingTypeOptions: + facilityProcessingTypeOptionsPropType.isRequired, + productTypeOptions: productTypeOptionsPropType.isRequired, + numberOfWorkersOptions: numberOfWorkerOptionsPropType.isRequired, + updateContributorType: func.isRequired, + contributorTypes: contributorTypeOptionsPropType.isRequired, + parentCompany: contributorOptionsPropType.isRequired, + facilityType: facilityTypeOptionsPropType.isRequired, + processingType: processingTypeOptionsPropType.isRequired, + productType: productTypeOptionsPropType.isRequired, + numberOfWorkers: numberOfWorkerOptionsPropType.isRequired, + fetchingFacilities: bool.isRequired, + fetchingExtendedOptions: bool.isRequired, +}; + +function mapStateToProps({ + filterOptions: { + contributors: { + data: contributorOptions, + fetching: fetchingContributors, + }, + contributorTypes: { + data: contributorTypeOptions, + fetching: fetchingContributorTypes, + }, + facilityProcessingType: { + data: facilityProcessingTypeOptions, + fetching: fetchingFacilityProcessingType, + }, + productType: { + data: productTypeOptions, + fetching: fetchingProductType, + }, + numberOfWorkers: { + data: numberOfWorkersOptions, + fetching: fetchingNumberofWorkers, + }, + }, + filters: { + contributorTypes, + parentCompany, + facilityType, + processingType, + productType, + numberOfWorkers, + nativeLanguageName, + boundary, + }, + facilities: { + facilities: { data: facilities, fetching: fetchingFacilities }, + }, + embeddedMap: { embed }, +}) { + return { + contributorOptions, + contributorTypeOptions, + facilityProcessingTypeOptions, + productTypeOptions, + numberOfWorkersOptions, + contributorTypes, + parentCompany, + facilityType, + processingType, + productType, + numberOfWorkers, + nativeLanguageName, + fetchingFacilities, + facilities, + boundary, + fetchingExtendedOptions: + fetchingContributors || + fetchingContributorTypes || + fetchingFacilityProcessingType || + fetchingProductType || + fetchingNumberofWorkers, + embed: !!embed, + }; +} + +function mapDispatchToProps(dispatch) { + return { + updateContributorType: v => dispatch(updateContributorTypeFilter(v)), + updateParentCompany: v => dispatch(updateParentCompanyFilter(v)), + updateFacilityType: v => dispatch(updateFacilityTypeFilter(v)), + updateProcessingType: v => dispatch(updateProcessingTypeFilter(v)), + updateProductType: v => dispatch(updateProductTypeFilter(v)), + updateNumberOfWorkers: v => dispatch(updateNumberofWorkersFilter(v)), + updateNativeLanguageName: e => + dispatch(updateNativeLanguageNameFilter(getValueFromEvent(e))), + activateDrawFilter: () => dispatch(showDrawFilter(true)), + clearDrawFilter: () => { + dispatch(showDrawFilter(false)); + dispatch(updateBoundaryFilter(null)); + return dispatch(fetchFacilities({})); + }, + fetchContributorTypes: () => dispatch(fetchContributorTypeOptions()), + fetchFacilityProcessingType: () => + dispatch(fetchFacilityProcessingTypeOptions()), + fetchProductType: () => dispatch(fetchProductTypeOptions()), + fetchNumberOfWorkers: () => dispatch(fetchNumberOfWorkersOptions()), + }; +} + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(withStyles(filterSidebarSearchTabStyles)(FilterSidebarSearchTab)); diff --git a/src/app/src/components/FilterSidebarSearchTab.jsx b/src/app/src/components/FilterSidebarSearchTab.jsx index 317d52144..c73cdf946 100644 --- a/src/app/src/components/FilterSidebarSearchTab.jsx +++ b/src/app/src/components/FilterSidebarSearchTab.jsx @@ -12,14 +12,12 @@ import InfoIcon from '@material-ui/icons/Info'; import Tooltip from '@material-ui/core/Tooltip'; import Popover from '@material-ui/core/Popover'; import ReactSelect from 'react-select'; -import Creatable from 'react-select/creatable'; -import Divider from '@material-ui/core/Divider'; import { withStyles } from '@material-ui/core/styles'; import get from 'lodash/get'; -import uniq from 'lodash/uniq'; import ShowOnly from './ShowOnly'; import FeatureFlag from './FeatureFlag'; +import FilterSidebarExtendedSearch from './FilterSidebarExtendedSearch'; import { updateFacilityFreeTextQueryFilter, @@ -34,14 +32,12 @@ import { updateNumberofWorkersFilter, updateNativeLanguageNameFilter, updateCombineContributorsFilterOption, - updateBoundaryFilter, - updatePPEFilter, resetAllFilters, } from '../actions/filters'; import { fetchFacilities } from '../actions/facilities'; -import { recordSearchTabResetButtonClick, showDrawFilter } from '../actions/ui'; +import { recordSearchTabResetButtonClick } from '../actions/ui'; import { contributorOptionsPropType, @@ -49,7 +45,6 @@ import { countryOptionsPropType, facilityTypeOptionsPropType, processingTypeOptionsPropType, - facilityProcessingTypeOptionsPropType, productTypeOptionsPropType, numberOfWorkerOptionsPropType, facilityCollectionPropType, @@ -60,12 +55,12 @@ import { filterSidebarStyles } from '../util/styles'; import { getValueFromEvent, makeSubmitFormOnEnterKeyPressFunction, - mapDjangoChoiceTuplesValueToSelectOptions, } from '../util/util'; import { FACILITIES_REQUEST_PAGE_SIZE, DEFAULT_SEARCH_TEXT, + EXTENDED_PROFILE_FLAG, } from '../util/constants'; const filterSidebarSearchTabStyles = theme => @@ -106,80 +101,28 @@ const filterSidebarSearchTabStyles = theme => const FACILITIES = 'FACILITIES'; const CONTRIBUTORS = 'CONTRIBUTORS'; -const CONTRIBUTOR_TYPES = 'CONTRIBUTOR_TYPES'; const LISTS = 'LISTS'; const COUNTRIES = 'COUNTRIES'; -const PARENT_COMPANY = 'PARENT_COMPANY'; -const FACILITY_TYPE = 'FACILITY_TYPE'; -const PROCESSING_TYPE = 'PROCESSING_TYPE'; -const PRODUCT_TYPE = 'PRODUCT_TYPE'; -const NUMBER_OF_WORKERS = 'NUMBER_OF_WORKERS'; - -const mapFacilityTypeOptions = (fPTypes, pTypes) => { - let fTypes = []; - if (pTypes.length === 0) { - fTypes = fPTypes.map(type => type.facilityType); - } else { - // When there are processing types, only return the - // facility types that have those processing types - pTypes.forEach(pType => { - fPTypes.forEach(fPType => { - if (fPType.processingTypes.includes(pType.value)) { - fTypes = fTypes.concat(fPType.facilityType); - } - }); - }); - } - return mapDjangoChoiceTuplesValueToSelectOptions(uniq(fTypes.sort())); -}; - -const mapProcessingTypeOptions = (fPTypes, fTypes) => { - let pTypes = []; - if (fTypes.length === 0) { - pTypes = fPTypes.map(type => type.processingTypes).flat(); - } else { - // When there are facility types, only return the - // processing types that are under those facility types - fTypes.forEach(fType => { - fPTypes.forEach(fPType => { - if (fType.value === fPType.facilityType) { - pTypes = pTypes.concat(fPType.processingTypes); - } - }); - }); - } - return mapDjangoChoiceTuplesValueToSelectOptions(uniq(pTypes.sort())); -}; const checkIfAnyFieldSelected = fields => fields.some(f => f.length !== 0); function FilterSidebarSearchTab({ contributorOptions, listOptions, - contributorTypeOptions, countryOptions, - facilityProcessingTypeOptions, - productTypeOptions, - numberOfWorkersOptions, resetFilters, facilityFreeTextQuery, updateFacilityFreeTextQuery, contributors, updateContributor, contributorTypes, - updateContributorType, countries, updateCountry, parentCompany, - updateParentCompany, facilityType, - updateFacilityType, processingType, - updateProcessingType, productType, - updateProductType, numberOfWorkers, - updateNumberOfWorkers, combineContributors, updateCombineContributors, fetchingFacilities, @@ -188,11 +131,6 @@ function FilterSidebarSearchTab({ fetchingOptions, submitFormOnEnterKeyPress, vectorTileFlagIsActive, - activateDrawFilter, - clearDrawFilter, - boundary, - ppe, - updatePPE, embed, fetchingLists, updateList, @@ -219,7 +157,6 @@ function FilterSidebarSearchTab({ contributorPopoverAnchorEl, setContributorPopoverAnchorEl, ] = useState(null); - const [ppePopoverAnchorEl, setPpePopoverAnchorEl] = useState(null); const [expand, setExpand] = useState( checkIfAnyFieldSelected(extendedFields), ); @@ -304,38 +241,6 @@ function FilterSidebarSearchTab({ ); - const ppeInfoPopoverContent = ( -
-

- Personal protective equipment (PPE) includes masks, gloves, - gowns, visors and other equipment. -

-
- ); - - const boundaryButton = - boundary == null ? ( - - ) : ( - - ); - const expandButton = expand ? (