Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Purpose
Completed the GS on-boarding task. Include a screenshot of the front-end of the application.

- [ ] I have added my name to the onboarding title (required)
- [ ] I have added a screenshot of the logs printed by the logger middleware (required)
- [ ] I am interested to work on the frontend (optional)

# New Changes
- Explain new changes

# Testing
- Explain tests that you ran to verify code functionality.
- Any functions that can be unit-tested should include a unit test in the PR. Otherwise, explain why it cannot be unit-tested.

# Outstanding Changes
- If there are non-critical changes (i.e. additional features) that can be made to this feature in the future, indicate them here.
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ All function and method parameters (except for the `self` and `cls` parameters)
```python
def my_add(num1: int, num2: int) -> int:
"""
@brief Adds two numbers together
Adds two numbers together

@param num1 - The first number to add.
@param num2 - The second number to add.
@return Returns the sum of the two numbers.
:param num1: The first number to add.
:param num2: The second number to add.
:return: Returns the sum of the two numbers.
"""
return num1 + num2
```
Expand Down Expand Up @@ -72,21 +72,21 @@ Function and method comments using `""" """` should exist below the function dec
```python
def my_add(num1: int, num2: int) -> int:
"""
@brief Adds two numbers together
Adds two numbers together

@param num1 - The first number to add.
@param num2 - The second number to add.
@return Returns the sum of the two numbers.
:param num1: The first number to add.
:param num2: The second number to add.
:return: Returns the sum of the two numbers.
"""
return num1 + num2
```

```python
def increase_x(self, count: int) -> None:
"""
@brief Increases the x attribute by the count.
Increases the x attribute by the count.

@param count - Count to increase the x attribute by.
:param count: Count to increase the x attribute by.
"""
self.x += count
```
Expand All @@ -105,9 +105,11 @@ File comments are not required
```python
class PointTwoDimension:
"""
@brief Class for storing a 2D point
@attribute x (int) - x coordinate of the point
@attribute y (int) - y coordinate of the point
Class for storing a 2D point
:param x: x coordinate of the point
:type x: int
:param y: y coordinate of the point
:type y: int
"""

def __init__(x: int, y: int):
Expand All @@ -117,9 +119,11 @@ class PointTwoDimension:
@dataclasses.dataclass
class PointTwoDimension:
"""
@brief Class for storing a 2D point
@attribute x (int) - x coordinate of the point
@attribute y (int) - y coordinate of the point
Class for storing a 2D point
:param x: x coordinate of the point
:type x: int
:param y: y coordinate of the point
:type y: int
"""

x: int
Expand Down
11 changes: 5 additions & 6 deletions backend/api/endpoints/command.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from fastapi import APIRouter, Depends
from fastapi.exceptions import HTTPException
from sqlmodel import Session, select

from backend.api.models.request_model import CommandRequest
Expand All @@ -16,7 +15,7 @@ def get_commands(db: Session = Depends(get_db)):
"""
Gets all the items

@return Returns a list of commands
:return: Returns a list of commands
"""
query = select(Command)
items = db.exec(query).all()
Expand All @@ -28,8 +27,8 @@ def create_command(payload: CommandRequest):
"""
Creates an item with the given payload in the database and returns this payload after pulling it from the database

@param payload: The data used to create an item
@return returns a json object with field of "data" under which there is the payload now pulled from the database
:param payload: The data used to create an item
:return: returns a json object with field of "data" under which there is the payload now pulled from the database
"""
# TODO:(Member) Implement this endpoint

Expand All @@ -40,7 +39,7 @@ def delete_command(id: int):
"""
Deletes the item with the given id if it exists. Otherwise raises a 404 error.

@param id: The id of the item to delete
@return returns the list of commands after deleting the item
:param id: The id of the item to delete
:return: returns the list of commands after deleting the item
"""
# TODO:(Member) Implement this endpoint
2 changes: 1 addition & 1 deletion backend/api/endpoints/main_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def get_main_commands(db: Session = Depends(get_db)):
"""
Gets all the main commands that can be created.

@return Returns a list of main commands
:return: Returns a list of main commands
"""
query = select(MainCommand)
items = db.exec(query).all()
Expand Down
2 changes: 1 addition & 1 deletion backend/api/middlewares/cors_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def add_cors_middleware(app: FastAPI) -> None:
"""
Adds the cors middleware to the FastAPI app

@param app: FastAPI app to add the middleware to
:param app: FastAPI app to add the middleware to
"""
app.add_middleware(
CORSMiddleware,
Expand Down
6 changes: 3 additions & 3 deletions backend/api/middlewares/logger_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ async def dispatch(
datetime of request, duration of execution. Logs should be printed using the custom logging module provided.
Logs should be printed so that they are easily readable and understandable.

@param request: Request received to this middleware from client (it is supplied by FastAPI)
@param call_next: Endpoint or next middleware to be called (if any, this is the next middleware in the chain of middlewares, it is supplied by FastAPI)
@return Response from endpoint
:param request: Request received to this middleware from client (it is supplied by FastAPI)
:param call_next: Endpoint or next middleware to be called (if any, this is the next middleware in the chain of middlewares, it is supplied by FastAPI)
:return: Response from endpoint
"""
# TODO:(Member) Finish implementing this method
response = await call_next(request)
Expand Down
3 changes: 2 additions & 1 deletion backend/data/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

class BaseSQLModel(SQLModel):
"""
Base SQL Model class. It performs validation on the model unlike the default SQLModel class with table=True.
Base SQL Model class.
It performs validation on the model unlike the default SQLModel class with table=True.
"""

def __init__(self, **data):
Expand Down
2 changes: 1 addition & 1 deletion backend/data/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class CommandStatus(Enum):
"""
Enum representing the command status.

@warning This enum shouldn't be modified
:warning: This enum shouldn't be modified
"""

PENDING = auto()
Expand Down
7 changes: 3 additions & 4 deletions backend/utils/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@

def logger_setup(*, enqueue: bool = False, diagnose: bool = True) -> None:
"""
Set up the global logger
Set up the global logger. It modifies the global logger object.
The logger will log everything to a file, info to stdout, and warnings and above to stderr.
@param enqueue - Whether to enqueue messages for asynchronous processing.
@param diagnose - Whether to enable diagnostic mode.
@return None - Modifies the global logger object
:param enqueue: Whether to enqueue messages for asynchronous processing.
:param diagnose: Whether to enable diagnostic mode.
"""
# Remove any existing sinks
logger.remove()
Expand Down
23 changes: 21 additions & 2 deletions frontend/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import { useEffect, useState } from 'react'
import './app.css'
import CommandTable from './display/table'
import CommandInput from './input/command_input'
import { CommandResponse } from './data/response'
import { getCommands } from './display/command_api'

function App() {
const [commands, setCommands] = useState<CommandResponse[]>([])

useEffect(() => {
const getCommandsFn = async () => {
try {
const data = await getCommands();
setCommands(data.data)
} catch (error) {
console.error(error)
alert("Error fetching commands")
}
}

getCommandsFn();
}, [])

return (
<>
<CommandInput />
<CommandInput setCommands={setCommands} />
<p>Command List:</p>
<CommandTable />
<CommandTable commands={commands} setCommands={setCommands} />
</>
)
}
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/data/request.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export interface CommandRequest {
name: string
command_type: number
params: string | null
format: string | null
}

4 changes: 4 additions & 0 deletions frontend/src/data/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface CommandResponse {
updated_on: string
}

export interface CommandSingleResponse {
data: CommandResponse
}

export interface CommandListResponse {
data: CommandResponse[]
}
2 changes: 1 addition & 1 deletion frontend/src/display/command_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const getCommands = async (): Promise<CommandListResponse> => {
const { data } = await axios.get<CommandListResponse>(`${API_URL}/commands/`)
return data;
} catch (error) {
console.error(error)
console.error(`Error getting commands: ${error}`);
throw error
}
}
Expand Down
30 changes: 13 additions & 17 deletions frontend/src/display/table.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { useEffect, useState } from "react"
import { CommandResponse } from "../data/response"
import { getCommands } from "./command_api"
import CommandRow from "./row"

const CommandTable = () => {
const [commands, setCommands] = useState<CommandResponse[]>([])

useEffect(() => {
const getCommandsFn = async () => {
const data = await getCommands();
setCommands(data.data)
}
interface CommandTableProp {
commands: CommandResponse[],
setCommands: React.Dispatch<React.SetStateAction<CommandResponse[]>>
}

getCommandsFn();
}, [])
const CommandTable = ({
commands,
setCommands
}: CommandTableProp) => {

const handleDelete = (id: number) => {
return () => {
// TODO: (Member) Handle delete logic here
// You will need to create a function in `command_api.ts` before you can finish this part.

return async () => {
// TODO: (Member) You will need to create a function in `command_api.ts` so you can delete a command.
const data = await deleteCommand(id)
setCommands(data.data)
}
}

Expand All @@ -37,7 +33,7 @@ const CommandTable = () => {
</tr>
</thead>
<thead>
{commands.map(value => (<CommandRow {...value} handleDelete={handleDelete(value.id)} />))}
{commands.map(value => (<CommandRow key={value.id} {...value} handleDelete={handleDelete(value.id)} />))}
</thead>
</table>
)
Expand Down
43 changes: 36 additions & 7 deletions frontend/src/input/command_input.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,55 @@
import { useState } from "react";
import { CommandResponse, MainCommandResponse } from "../data/response"
import "./command_input.css"

const CommandInput = () => {
// TODO: (Member) Setup state and useEffect calls here
interface CommandInputProp {
setCommands: React.Dispatch<React.SetStateAction<CommandResponse[]>>
}

const CommandInput = ({ setCommands }: CommandInputProp) => {
const [selectedCommand, setSelectedCommand] = useState<MainCommandResponse | null>(null);
const [parameters, setParameters] = useState<{ [key: string]: string }>({});
// TODO: (Member) Setup anymore states if necessary

// TODO: (Member) Fetch MainCommands in a useEffect

const handleParameterChange = (param: string, value: string): void => {
setParameters((prev) => ({
...prev,
[param]: value,
}));
}

const handleSubmit = () => {
const handleSubmit = async (e: React.FormEvent) => {
// TODO:(Member) Submit to your post endpoint
}

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*/}
<select>{/* TODO: (Member) Display the list of commands based on the get commands request.
It should update the `selectedCommand` field when selecting one.*/}
<option value={"1"}>Command 1</option>
<option value={"2"}>Command 2</option>
<option value={"3"}>Command 3</option>
</select>
</div>
<input /> {/* TODO: (Member) Add input handling here if the selected command has a param input*/}
<button onClick={handleSubmit}>Submit</button>
{selectedCommand?.params?.split(",").map((param) => (
<div key={param}>
<label htmlFor={`param-${param}`}>{param}: </label>
<input
id={`param-${param}`}
type="text"
value={parameters[param] || ""}
onChange={(e) => handleParameterChange(param, e.target.value)}
placeholder={`Enter ${param}`}
/>
</div>
))}
<button type="submit">Submit</button>
</div>
</form>
</>
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/input/input_api.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { API_URL } from "../environment";
import { CommandRequest } from "../data/request";
import axios from "axios";
import { CommandResponse, MainCommandListResponse } from "../data/response";
import { CommandSingleResponse, MainCommandListResponse } from "../data/response";

export const createCommand = async (requestData: CommandRequest): Promise<CommandResponse> => {
export const createCommand = async (requestData: CommandRequest): Promise<CommandSingleResponse> => {
try {
const { data } = await axios.post<CommandResponse>(`${API_URL}/commands`, requestData);
const { data } = await axios.post<CommandSingleResponse>(`${API_URL}/commands`, requestData);
return data
} catch (error) {
console.error(error);
console.error(`Error creating command: ${error}`);
throw error;
}
}
Expand All @@ -19,7 +19,7 @@ export const getMainCommands = async (): Promise<MainCommandListResponse> => {
console.log(data)
return data;
} catch (error) {
console.error(error)
console.error(`Error getting main commands: ${error}`);
throw error;
}
}
Loading
Loading