diff --git a/app/index.html b/app/index.html index 788ef3c..a5d40a8 100644 --- a/app/index.html +++ b/app/index.html @@ -3,7 +3,9 @@ - + + + Vector Hydrologic Model Output @@ -14,4 +16,4 @@ - \ No newline at end of file + diff --git a/app/public/favicon.ico b/app/public/favicon.ico new file mode 100644 index 0000000..523a790 Binary files /dev/null and b/app/public/favicon.ico differ diff --git a/app/src/App.jsx b/app/src/App.jsx index 2b65941..98b628f 100644 --- a/app/src/App.jsx +++ b/app/src/App.jsx @@ -1,12 +1,5 @@ -import React from 'react'; import MapComponent from "./components/map/MapComponent.jsx"; -console.log("Rendering App..."); -const App = () => { - console.log("Rendering MapComponent from App..."); - return ; -}; - -console.log("Rendering MapComponent..."); +const App = () => ; export default App; diff --git a/app/src/assets/logo.png b/app/src/assets/logo.png deleted file mode 100644 index f3107a7..0000000 Binary files a/app/src/assets/logo.png and /dev/null differ diff --git a/app/src/assets/logo.webp b/app/src/assets/logo.webp new file mode 100644 index 0000000..0c12d27 Binary files /dev/null and b/app/src/assets/logo.webp differ diff --git a/app/src/components/data/DataSelectionTable.jsx b/app/src/components/data/DataSelectionTable.jsx index 84e5f8c..346eb1f 100644 --- a/app/src/components/data/DataSelectionTable.jsx +++ b/app/src/components/data/DataSelectionTable.jsx @@ -1,8 +1,20 @@ import { useState, useEffect, useCallback } from "react"; import PropTypes from "prop-types"; -import { getAvailableOptions, downloadTimeseries } from "../../services/timeseriesApi.js"; +import { + getAvailableOptions, + downloadTimeseries, +} from "../../services/timeseriesApi.js"; import "./DataSelection.css"; +const HISTORICAL_SCENARIO = "historical"; +const HISTORICAL_MODEL = "PNWNAmet"; + +const getModelLabel = (model) => + model === HISTORICAL_MODEL ? `${model} (historical)` : model; + +const getScenarioLabel = (scenario) => + scenario === HISTORICAL_SCENARIO ? `${scenario} (PNWNAmet only)` : scenario; + const DataSelectionTable = ({ featureId, onClose }) => { const outletId = `${featureId}`; const [options, setOptions] = useState({ @@ -15,18 +27,21 @@ const DataSelectionTable = ({ featureId, onClose }) => { scenario: "", variable: "", }); + const [isFetching, setIsFetching] = useState(true); const [isLoading, setIsLoading] = useState(false); const [showValidation, setShowValidation] = useState(false); const [shake, setShake] = useState(false); useEffect(() => { const fetchOptions = async () => { - try { + try { const availableOptions = await getAvailableOptions(outletId); setOptions(availableOptions); } catch (error) { console.error("Failed to fetch options:", error); alert("Failed to load available options"); + } finally { + setIsFetching(false); } }; @@ -34,16 +49,24 @@ const DataSelectionTable = ({ featureId, onClose }) => { }, [outletId]); const handleChange = (field, value) => { - setSelections((prev) => ({ - ...prev, - [field]: value, - })); - }; + setSelections((prev) => { + const isNowInvalid = + field === "model" && + prev.scenario !== "" && + (value === HISTORICAL_MODEL) !== + (prev.scenario === HISTORICAL_SCENARIO); - const getValidationClass = (field) => { - return showValidation && !selections[field] ? "invalid" : ""; + return { + ...prev, + [field]: value, + ...(isNowInvalid ? { scenario: "" } : {}), + }; + }); }; + const getValidationClass = (field) => + showValidation && !selections[field] ? "invalid" : ""; + const handleDownload = useCallback(async () => { if (Object.values(selections).some((v) => !v)) { setShowValidation(true); @@ -77,11 +100,12 @@ const DataSelectionTable = ({ featureId, onClose }) => { value={selections.model} onChange={(e) => handleChange("model", e.target.value)} className={getValidationClass("model")} + disabled={isFetching} > - + {options.models.map((model) => ( ))} @@ -90,11 +114,24 @@ const DataSelectionTable = ({ featureId, onClose }) => { value={selections.scenario} onChange={(e) => handleChange("scenario", e.target.value)} className={getValidationClass("scenario")} + disabled={isFetching} > - + {options.scenarios.map((scenario) => ( - ))} @@ -103,8 +140,11 @@ const DataSelectionTable = ({ featureId, onClose }) => { value={selections.variable} onChange={(e) => handleChange("variable", e.target.value)} className={getValidationClass("variable")} + disabled={isFetching} > - + {options.variables.map((variable) => (