-
Notifications
You must be signed in to change notification settings - Fork 73
GS Onboarding (backend and frontend) #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
6240c7b
c463b13
dcd195b
bde659e
dafe1d4
cb2bfe6
957b4cc
2fa2963
1ff2486
db6bb39
2822edb
cc0b376
1f2e9a2
fe95383
4a5fc21
54c6b5f
b8fae64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| export interface CommandRequest { | ||
| name: string | ||
| command_type: number, | ||
| params: string | null | ||
| format: string | null | ||
| //format: string | null | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,120 @@ | ||
| import "./command_input.css" | ||
| import { useState, useEffect } from "react" | ||
| import { MainCommandResponse } from "../data/response" | ||
| import { createCommand, getMainCommands } from "./input_api" | ||
|
|
||
|
|
||
| const CommandInput = () => { | ||
| // TODO: (Member) Setup state and useEffect calls here | ||
| const [mainCommands, setMainCommands] = useState<MainCommandResponse[]>([]) | ||
| const [commandType, setCommandType] = useState<MainCommandResponse | null>(null) | ||
| const [params, setParams] = useState<Map<string, string>>(new Map()); | ||
|
|
||
| useEffect(() => { | ||
| const setMainCommandsFn = async () => { | ||
| const data = await getMainCommands() | ||
| if(data.data.length == 0) { | ||
|
||
| alert("Error occurred. Please try again later.") | ||
| return | ||
| } | ||
| setMainCommands(data.data) | ||
| setCommandType(data.data[0]) | ||
Yarik-Popov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const parameters = data.data[0].params?.split(",") || [] | ||
| let paramsObject : Map<string, string> = new Map() | ||
|
|
||
| for(const param of parameters) { | ||
| paramsObject.set(param, "") | ||
| } | ||
| setParams(paramsObject); | ||
| } | ||
| setMainCommandsFn(); | ||
| }, []) | ||
|
|
||
|
|
||
| const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { | ||
| // TODO:(Member) Submit to your post endpoint | ||
| e.preventDefault(); | ||
|
|
||
| //Check if parameters are valid | ||
| const allParams = commandType?.params?.split(",") || []; | ||
| const paramsList = [] | ||
|
|
||
| const missingParams = [] | ||
| for (const param of allParams) { | ||
| if (!params.get(param)) { | ||
| missingParams.push(param) | ||
| } | ||
| paramsList.push(params.get(param)) | ||
| } | ||
| if(missingParams.length != 0) { | ||
|
||
| alert(`Parameters missing: ${missingParams.join(", ")}`) | ||
| return; | ||
| } | ||
|
|
||
|
|
||
| const reqBody = { | ||
| command_type: commandType?.id || 0, | ||
| params: paramsList.join(",") | ||
| }; | ||
|
|
||
|
|
||
| const createCommandFn = async () => { | ||
| await createCommand(reqBody); | ||
| window.location.reload(); | ||
| } | ||
| createCommandFn(); | ||
| } | ||
|
|
||
| const changeCommandType = (e: React.ChangeEvent<HTMLSelectElement>) => { | ||
| const cmdType = mainCommands.find(cmd => cmd.id == +e.target.value) | ||
| if(!cmdType) { | ||
| alert("Error occurred. Please try again later.") | ||
| return | ||
| } | ||
| setCommandType(cmdType) | ||
| const parameters = cmdType?.params?.split(",") || [] | ||
| let paramsObject : Map<string, string> = new Map() | ||
| for(const param of parameters) { | ||
| paramsObject.set(param, "") | ||
| } | ||
| setParams(paramsObject) | ||
| } | ||
|
|
||
| const changeParam = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
| const param = e.target.id | ||
| const value = e.target.value | ||
|
|
||
| const handleSubmit = () => { | ||
| // TODO:(Member) Submit to your post endpoint | ||
| setParams(prevParams => { | ||
| const newParams = new Map(prevParams); | ||
| newParams.set(param, value); | ||
| return newParams; | ||
| }) | ||
| } | ||
|
|
||
| return ( | ||
| <> | ||
| <form> | ||
| <form onSubmit={handleSubmit}> | ||
| <div className="spreader"> | ||
| <div> | ||
| <label>Command Type: </label> | ||
| <select>{/* TODO: (Member) Display the list of commands based on the get commands request*/} | ||
| <option value={"1"}>Command 1</option> | ||
| <option value={"2"}>Command 2</option> | ||
| <option value={"3"}>Command 3</option> | ||
| {/* TODO: (Member) Display the list of commands based on the get commands request*/} | ||
| <select | ||
| value={commandType?.id} | ||
| onChange={changeCommandType}> | ||
| {mainCommands.map(cmd => (<option value={cmd.id}>{cmd.name}</option>))} | ||
| </select> | ||
| </div> | ||
| <input /> {/* TODO: (Member) Add input handling here if the selected command has a param input*/} | ||
| <button onClick={handleSubmit}>Submit</button> | ||
|
|
||
| {/* TODO: (Member) Add input handling here if the selected command has a param input*/} | ||
| {commandType && | ||
| commandType.params?.split(",").map((param) => (<input value={params.get(param)} id={param} placeholder={`Enter ${param}`} onChange={changeParam}/>))} | ||
|
|
||
| <button type="submit">Submit</button> | ||
| </div> | ||
| </form> | ||
| </> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| export default CommandInput; | ||
| export default CommandInput; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ | |
| from backend.data.enums import CommandStatus | ||
| from backend.utils.time import to_unix_time | ||
|
|
||
| from datetime import datetime | ||
|
|
||
|
|
||
| def test_get_commands(fastapi_test_client: TestClient, commands_json): | ||
| with fastapi_test_client as client: | ||
|
|
@@ -24,8 +26,10 @@ def test_create_command(fastapi_test_client: TestClient): | |
| assert result.get("status") == CommandStatus.PENDING.value | ||
| assert result.get("params") == "123456789" | ||
| # TODO: Figure out a better way to check the times | ||
| assert result.get("created_on") | ||
| assert result.get("updated_on") | ||
| created_on_dt = datetime.fromisoformat(result.get("created_on")) | ||
| updated_on_dt = datetime.fromisoformat(result.get("updated_on")) | ||
| assert isinstance(created_on_dt, datetime) | ||
| assert isinstance(updated_on_dt, datetime) | ||
|
Comment on lines
28
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Not a part of the onboarding but definitely something that can be improved. Ill link this in the task to improve the gs onboarding. |
||
|
|
||
| def test_delete_command_fail(fastapi_test_client: TestClient): | ||
| with fastapi_test_client as client: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.