From 54fd387cb9cf5e56cb46cfb6802b78ffbea21b1b Mon Sep 17 00:00:00 2001 From: Jinyu Xie Date: Sat, 16 Sep 2023 16:46:53 -0700 Subject: [PATCH] Add edit environment info features --- frontend/src/components/environment_card.tsx | 49 +++++++- frontend/src/components/variable_spec.tsx | 120 ++++++++++++++----- 2 files changed, 136 insertions(+), 33 deletions(-) diff --git a/frontend/src/components/environment_card.tsx b/frontend/src/components/environment_card.tsx index 90af28c..e16a2c5 100644 --- a/frontend/src/components/environment_card.tsx +++ b/frontend/src/components/environment_card.tsx @@ -1,13 +1,54 @@ -import { Environment } from "@/types/environment"; +import { Environment, VectorSpec } from "@/types/environment"; import VariableSpec from "@/components/variable_spec"; +import { useState, useEffect } from "react"; export default function EnvironmentCard({ env }: { env: Environment }) { + const [envSpecs, setEnvSpecs] = useState(env); + const [obsSpecs, setObsSpecs] = useState( + env.observation_spec ?? [] + ); + const [actSpecs, setActSpecs] = useState(env.action_spec ?? []); + useEffect(() => { + setEnvSpecs((prevState) => { + const newState = { ...prevState }; + newState.observation_spec = obsSpecs; + newState.action_spec = actSpecs; + return newState; + }); + }, [obsSpecs, actSpecs]); + const onSave = () => { + fetch(`/api/env/${env.id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(envSpecs), + }) + .then((response) => { + if (!response.ok) { + throw new Error("Network response was not ok"); + } + console.log("Environment saved successfully!"); + }) + .catch((error) => { + console.error("There was a problem saving the environment:", error); + }); + }; + return (
-

{env.name}

- - +

{envSpecs.name}

+ +

Detailed Env Specs

diff --git a/frontend/src/components/variable_spec.tsx b/frontend/src/components/variable_spec.tsx index 5787d56..ab152d3 100644 --- a/frontend/src/components/variable_spec.tsx +++ b/frontend/src/components/variable_spec.tsx @@ -1,50 +1,112 @@ import React from "react"; import { VectorSpec } from "@/types/environment"; -interface Props { +const VAR_DISP_LIMIT = 50; + +export default function VariableSpec({ + title, + specs, + setSpecs, + onSave, +}: { title: string; - specs?: VectorSpec[]; -} + specs: VectorSpec[]; + setSpecs: React.Dispatch>; + onSave: () => void; +}) { + const [isEditing, setIsEditing] = React.useState( + specs.map(() => false) ?? [] + ); + const handleEditSubmitClick = (i: number) => { + setIsEditing((prevIsEditing) => { + const newIsEditing = [...prevIsEditing]; + newIsEditing[i] = !prevIsEditing[i]; + if (!newIsEditing[i]) { + onSave(); + } + return newIsEditing; + }); + }; -export default function VariableSpec(props: Props) { return (
-

{props.title}

- {props.specs?.map((spec, i) => ( +

{title}

+ {specs.map((spec, i) => (
-

{spec.space}

-
+ {spec.space} +
+ - {spec.var_info?.slice(0, 50).map((var_info, i) => ( - - - - - - ))} + {spec.var_info + ?.slice(0, VAR_DISP_LIMIT) + .map((var_info, j) => ( + + + +
Name Description
{i + 1} - - - -
{j + 1} + {isEditing[j] ? ( + { + setSpecs((prevState) => { + const newState = JSON.parse( + JSON.stringify(prevState) + ); + + newState[i].var_info[j].name = + event.target.value; + return newState; + }); + }} + /> + ) : ( +

{var_info.name}

+ )} +
+ {isEditing[j] ? ( +