From 2e37a06b8e9b61a3cc355549d7cfdaa612774761 Mon Sep 17 00:00:00 2001 From: oskarhurst <48417811+oskarhurst@users.noreply.github.com> Date: Fri, 18 Jul 2025 16:11:16 -0700 Subject: [PATCH 01/26] add form files --- .gitignore | 1 + lib/components/data/forms/CWMSForm.jsx | 54 +++++++++++++++ .../data/tables/inputs/CWMSCheckboxes.jsx | 0 .../data/tables/inputs/CWMSDropdown.jsx | 0 .../data/tables/inputs/CWMSInput.jsx | 65 +++++++++++++++++++ .../data/tables/inputs/CWMSInputTable.jsx | 0 .../data/tables/inputs/CWMSSpreadsheet.jsx | 0 .../data/tables/inputs/CWMSTextarea.jsx | 62 ++++++++++++++++++ 8 files changed, 182 insertions(+) create mode 100644 lib/components/data/forms/CWMSForm.jsx create mode 100644 lib/components/data/tables/inputs/CWMSCheckboxes.jsx create mode 100644 lib/components/data/tables/inputs/CWMSDropdown.jsx create mode 100644 lib/components/data/tables/inputs/CWMSInput.jsx create mode 100644 lib/components/data/tables/inputs/CWMSInputTable.jsx create mode 100644 lib/components/data/tables/inputs/CWMSSpreadsheet.jsx create mode 100644 lib/components/data/tables/inputs/CWMSTextarea.jsx diff --git a/.gitignore b/.gitignore index 191a1a1..4f06409 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ dist-ssr types # Editor directories and files +.venv/* .vscode/* !.vscode/extensions.json .idea diff --git a/lib/components/data/forms/CWMSForm.jsx b/lib/components/data/forms/CWMSForm.jsx new file mode 100644 index 0000000..e0fff0a --- /dev/null +++ b/lib/components/data/forms/CWMSForm.jsx @@ -0,0 +1,54 @@ +import React, { createContext, useContext, useRef } from "react"; +import { TimeSeriesApi } from "cwmsjs"; +import { useCdaConfig } from "../helpers/cda"; + +const FormContext = createContext(); + +export function FormWrapper({ office, unit = "EN", cdaUrl, children }) { + const inputsRef = useRef([]); + const config = useCdaConfig("v2", cdaUrl); + const ts_api = new TimeSeriesApi(config); + + const registerInput = (input) => { + inputsRef.current.push(input); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + + for (const input of inputsRef.current) { + try { + const response = await ts_api.postTimeSeries({ + timeSeries: { + name: input.tsid, + officeId: office, + values: input.getValues(), + units: input.units, + }, + }); + const result = await response.json(); + console.log("API result:", result); + } catch (err) { + console.error("API call failed:", err); + } + } + }; + + const handleReset = () => { + inputsRef.current.forEach((input) => { + input.reset(); + }); + }; + + return ( + +
+ {children} + + +
+
+ ); +} diff --git a/lib/components/data/tables/inputs/CWMSCheckboxes.jsx b/lib/components/data/tables/inputs/CWMSCheckboxes.jsx new file mode 100644 index 0000000..e69de29 diff --git a/lib/components/data/tables/inputs/CWMSDropdown.jsx b/lib/components/data/tables/inputs/CWMSDropdown.jsx new file mode 100644 index 0000000..e69de29 diff --git a/lib/components/data/tables/inputs/CWMSInput.jsx b/lib/components/data/tables/inputs/CWMSInput.jsx new file mode 100644 index 0000000..6e64461 --- /dev/null +++ b/lib/components/data/tables/inputs/CWMSInput.jsx @@ -0,0 +1,65 @@ +import React, { useEffect, useState, useContext } from "react"; +import { Input } from "@usace/groundwork"; +import { FormContext } from "../../forms/CWMSForm"; + +export function CWMSInput({ + style, + disable, + invalid, + name, + defaultValue, + value, + type, + placeholder, + tsid, + precision, + offset, + order, + AllowMissingData, + loadNearest, + readonly, + onChange, + units, +}) { + const { registerInput } = useContext(FormContext); + const [inputValue, setInputValue] = useState(defaultValue || value || ""); + + const inputRef = { + tsid, + precision: precision || 2, + offset: timeoffset || 0, + order: order || 1, + AllowMissingData: true, + loadNearest: "prev", + readonly: false, + units: units || "EN", + getValues: () => [inputValue], + reset: () => setInputValue(defaultValue || ""), + }; + + useEffect(() => { + registerInput(inputRef); + }, [registerInput]); + + const handleChange = (e) => { + const newValue = e.target.value; + setInputValue(newValue); + if (onChange) { + onChange(newValue); + } + }; + + return ( + + ); +} diff --git a/lib/components/data/tables/inputs/CWMSInputTable.jsx b/lib/components/data/tables/inputs/CWMSInputTable.jsx new file mode 100644 index 0000000..e69de29 diff --git a/lib/components/data/tables/inputs/CWMSSpreadsheet.jsx b/lib/components/data/tables/inputs/CWMSSpreadsheet.jsx new file mode 100644 index 0000000..e69de29 diff --git a/lib/components/data/tables/inputs/CWMSTextarea.jsx b/lib/components/data/tables/inputs/CWMSTextarea.jsx new file mode 100644 index 0000000..2c876d9 --- /dev/null +++ b/lib/components/data/tables/inputs/CWMSTextarea.jsx @@ -0,0 +1,62 @@ +import React, { useEffect, useState, useContext } from "react"; +import { Textarea } from "@usace/groundwork"; +import { FormContext } from "../../forms/CWMSForm"; + +export function CWMSTextarea({ + style, + disable, + invalid, + name, + defaultValue, + value, + tsid, + precision, + offset, + order, + AllowMissingData, + loadNearest, + onChange, + rows, +}) { + const { registerInput } = useContext(FormContext); + const [textareaValue, setTextareaValue] = useState( + defaultValue || value || "" + ); + + const textareaRef = { + tsid, + precision: precision || 2, + offset: timeoffset || 0, + order: order || 1, + AllowMissingData: AllowMissingData || true, + loadNearest: loadNearest || "prev", + readonly: readonly || false, + units: units || "EN", + getValues: () => [textareaValue], + reset: () => setTextareaValue(defaultValue || ""), + }; + + useEffect(() => { + registerInput(textareaRef); + }, [registerInput]); + + const handleChange = (e) => { + const newValue = e.target.value; + setTextareaValue(newValue); + if (onChange) { + onChange(newValue); + } + }; + + return ( +