From b5d6406ffd6323adf181ab1177583b2b98f5d39e Mon Sep 17 00:00:00 2001 From: lublagg Date: Fri, 15 Sep 2023 15:31:04 -0400 Subject: [PATCH] Limit years options and "get data" button availability. --- src/components/app.scss | 2 +- src/components/app.tsx | 17 ++++++++- src/components/constants.ts | 16 ++++---- src/components/types.ts | 16 ++++---- src/components/utils.ts | 4 ++ src/components/years-options.tsx | 65 +++++++++++++++++--------------- src/scripts/connect.js | 2 +- 7 files changed, 71 insertions(+), 51 deletions(-) create mode 100644 src/components/utils.ts diff --git a/src/components/app.scss b/src/components/app.scss index 2edc7c5..b9c2a4e 100644 --- a/src/components/app.scss +++ b/src/components/app.scss @@ -86,7 +86,7 @@ button { font-family: 'Montserrat', sans-serif; font-size: 12px; font-weight: 500; - &:hover { + &:hover:not(:disabled) { cursor: pointer; background: $teal-light-12; } diff --git a/src/components/app.tsx b/src/components/app.tsx index 0cce018..d8228a7 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -2,7 +2,7 @@ import React, {useEffect, useState} from "react"; import { Dropdown } from "./dropdown"; import classnames from "classnames"; import { Information } from "./information"; -import { categories, defaultSelectedOptions } from "./constants"; +import { attributeOptions, categories, defaultSelectedOptions, yearsOptions } from "./constants"; import { IStateOptions } from "./types"; import { createQueryFromSelections } from "../scripts/api"; import { connect } from "../scripts/connect"; @@ -13,6 +13,8 @@ import css from "./app.scss"; function App() { const [showInfo, setShowInfo] = useState(false); const [selectedOptions, setSelectedOptions] = useState(defaultSelectedOptions); + const [getDataDisabled, setGetDataDisabled] = useState(true); + const {farmerDemographics, farmDemographics, crops, economicsAndWages} = selectedOptions; useEffect(() => { const init = async () => { @@ -21,6 +23,17 @@ function App() { init(); }, []); + useEffect(() => { + const {geographicLevel, states, years} = selectedOptions; + const attrKeys = attributeOptions.filter((attr) => attr.key !== "cropUnits").map((attr) => attr.key); + const selectedAttrKeys = attrKeys.filter((key) => selectedOptions[key].length > 0); + if (selectedAttrKeys.length && geographicLevel && states.length && years.length) { + setGetDataDisabled(false); + } else { + setGetDataDisabled(true); + } + }, [selectedOptions]); + const handleSetSelectedOptions = (option: string, value: string | string[]) => { const newSelectedOptions = {...selectedOptions, [option]: value}; setSelectedOptions(newSelectedOptions); @@ -74,7 +87,7 @@ function App() {
- +
diff --git a/src/components/constants.ts b/src/components/constants.ts index ef141c0..b1061cb 100644 --- a/src/components/constants.ts +++ b/src/components/constants.ts @@ -120,12 +120,12 @@ export const categories = [ ]; export const defaultSelectedOptions: IStateOptions = { - "geographicLevel": "State", - "states": ["All States"], - "farmerDemographics": [], - "farmDemographics": [], - "economicsAndWages": [], - "cropUnits": "", - "crops": [], - "years": [] + geographicLevel: "State", + states: ["All States"], + farmerDemographics: [], + farmDemographics: [], + economicsAndWages: [], + cropUnits: "", + crops: [], + years: [] }; diff --git a/src/components/types.ts b/src/components/types.ts index 6eaa4a9..5e78030 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -1,12 +1,12 @@ export interface IStateOptions { - "geographicLevel": string, - "states": string[] - "farmerDemographics": string[], - "farmDemographics": string[], - "economicsAndWages": string[], - "cropUnits": string, - "crops": string[] - "years": string[] + geographicLevel: string, + states: string[] + farmerDemographics: string[], + farmDemographics: string[], + economicsAndWages: string[], + cropUnits: string, + crops: string[] + years: string[] } export type OptionKey = keyof IStateOptions; diff --git a/src/components/utils.ts b/src/components/utils.ts new file mode 100644 index 0000000..5d9f3b0 --- /dev/null +++ b/src/components/utils.ts @@ -0,0 +1,4 @@ +export const flatten = (arr: any[]): any[] => { + return arr.reduce((acc: any[], val: any) => + Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), []); +} diff --git a/src/components/years-options.tsx b/src/components/years-options.tsx index 924bd47..8bfd780 100644 --- a/src/components/years-options.tsx +++ b/src/components/years-options.tsx @@ -1,10 +1,11 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { attributeOptions, yearsOptions } from "./constants"; import { IStateOptions } from "./types"; import { Options } from "./options"; +import { queryData } from "../scripts/query-headers"; +import { flatten } from "./utils"; import css from "./options.scss"; -import { queryData } from "../scripts/query-headers"; interface IProps { handleSetSelectedOptions: (option: string, value: string|string[]) => void; @@ -13,47 +14,49 @@ interface IProps { export const YearsOptions: React.FC = (props) => { const {handleSetSelectedOptions, selectedOptions} = props; + const [availableYearOptions, setAvailableYearOptions] = useState([]); + const {farmerDemographics, farmDemographics, crops, economicsAndWages} = selectedOptions; - const handleSelectYear = (yearKey: string, years: string|string[]) => { - handleSetSelectedOptions(yearKey, years); - - // check if any attributeOption keys have values in selectedOptions - const attrKeys = attributeOptions.map((attr) => attr.key); + useEffect(() => { + const attrKeys = attributeOptions.filter((attr) => attr.key !== "cropUnits").map((attr) => attr.key); const selectedAttrKeys = attrKeys.filter((key) => selectedOptions[key].length > 0); - const areAnyAttrsSelected = selectedAttrKeys.length > 0; - // if any attributes are selected, check that selected year data is available for that selected attribute - if (areAnyAttrsSelected) { - const selectedYears = Array.isArray(years) ? years : [years]; - const selectedAttrs = selectedAttrKeys.map((key) => selectedOptions[key]); - selectedAttrs.forEach((attr) => { - if (Array.isArray(attr)) { - attr.forEach((subAttr) => { - const subAttrData = queryData.find((d) => d.plugInAttribute === subAttr); - const yearKeyToUse = selectedOptions.geographicLevel === "county" ? "county" : "state"; - const availableYears = subAttrData?.years[yearKeyToUse]; - if (availableYears) { - // check -- are selectedYears included in queryParams?.years[yearKeyTouse] ? - const areYearsValid = selectedYears.map((y) => availableYears.indexOf(y) > -1).indexOf(false) < 0; - console.log({areYearsValid}); - console.log({availableYears}); - console.log({selectedYears}); - // do something if years are not valid - } - }); - } - }); + + if (!selectedAttrKeys.length) { + return; } + + const yearKeyToUse = selectedOptions.geographicLevel === "County" ? "county" : "state"; + const allSelectedAttrs = flatten(selectedAttrKeys.map((key) => selectedOptions[key])); + const newAvailableYears = allSelectedAttrs.reduce((years, attr) => { + const subAttrData = queryData.find((d) => d.plugInAttribute === attr); + const availableYears = subAttrData?.years[yearKeyToUse]; + if (availableYears) { + availableYears.forEach((y) => { + years.add(y); + }); + } + return years; + }, new Set()); + + setAvailableYearOptions(Array.from(newAvailableYears)); + }, [farmerDemographics, farmDemographics, crops, economicsAndWages]) + + const handleSelectYear = (yearKey: string, years: string|string[]) => { + handleSetSelectedOptions(yearKey, years); }; return (
+ {availableYearOptions.length === 0 ? +
Please select attributes to see available years.
+ : + />}
); }; diff --git a/src/scripts/connect.js b/src/scripts/connect.js index 22a45a1..6a648b7 100644 --- a/src/scripts/connect.js +++ b/src/scripts/connect.js @@ -19,7 +19,7 @@ export const connect = { }, createNewDataset: async function (geoLevel) { - const geoLabel = geoLevel === "State" ? "States" : "Counties"; + const geoLabel = geoLevel === "State" ? states : "Counties"; return codapInterface.sendRequest({ action: 'create', resource: 'dataContext',