Skip to content
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

Ieee 259 add description box on teams homepage #509

Merged
merged 47 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7675935
incident form init
natapokie Jun 16, 2023
fbcd75a
implementing form components
natapokie Jun 18, 2023
dcfc142
fixing form style
natapokie Jun 18, 2023
e99f1bd
fixing position of menu items
natapokie Jun 18, 2023
dccfb73
implement back button
natapokie Jun 19, 2023
5b0f2a7
adding helper text for radio
natapokie Jun 19, 2023
e6e2728
fixing button
natapokie Jun 19, 2023
59d63f8
cleaning up unused vars
natapokie Jun 19, 2023
11ffa1d
adding report broken lost button
natapokie Jun 19, 2023
c7efa0e
init test
natapokie Jun 19, 2023
9649eaa
fixing link
natapokie Jun 20, 2023
c195a9f
reset form on successful submission
natapokie Jun 20, 2023
05213d4
setting up testing
natapokie Jun 20, 2023
a4207bb
fix test
natapokie Jun 20, 2023
675226e
fixing tests
natapokie Jun 21, 2023
3b36389
removing unused code
natapokie Jun 21, 2023
7a96957
adding name to readme
natapokie Jun 21, 2023
4e0baf4
fix type error
natapokie Jun 21, 2023
c4180b8
padding qty to new page & adding snackbar
natapokie Jun 22, 2023
14b8638
rewriting formik with map
natapokie Jun 26, 2023
ee0039f
fixing responsive issues on form
natapokie Jun 26, 2023
59f3793
fixing checkedout tables style
natapokie Jun 26, 2023
ae22fc6
adding map to radio options
natapokie Jul 2, 2023
94e74a5
using map in form
natapokie Jul 2, 2023
617cb3f
fixing textfield width
natapokie Jul 3, 2023
d589a3a
fixing validation onchange
natapokie Jul 3, 2023
6a36f5f
Merge branch 'develop' into IEEE-272-implement-item-incident-form
Mustaballer Jul 4, 2023
eeee0ee
Merge branch 'develop' into IEEE-272-implement-item-incident-form
Mustaballer Jul 7, 2023
c84c303
adding more unit tests to check for rendering of form components and …
natapokie Jul 13, 2023
84661aa
Merge branch 'IEEE-272-implement-item-incident-form' of https://githu…
natapokie Jul 13, 2023
7f1cd4f
adding more padding between form elements and labels
natapokie Jul 13, 2023
09a135b
removing inline styles (sorry bad habitsgit status)
natapokie Jul 13, 2023
98b8f1f
removing unused code and console.log & changing url format a little b…
natapokie Jul 13, 2023
a9308ec
added yup validation to check if the input string is 0 for qty, is so…
natapokie Jul 15, 2023
c7aaf9a
IEEE-259 add input box on teams homepage
Sep 11, 2023
497cbad
Delete hackathon_site/dashboard/frontend/package-lock.json
KarandeepLubana Sep 11, 2023
183ec38
Merge branch 'develop' into IEEE-259-add-description-box-on-teams-hom…
Sep 11, 2023
d49aef8
IEEE-259 remove unused ErrorMessage
Sep 11, 2023
7e3c9fc
Merge branch 'develop' into IEEE-259-add-description-box-on-teams-hom…
Mustaballer Oct 23, 2023
092f172
IEEE-259 refactor and clean project description component
Jan 16, 2024
aa3b498
Merge branch 'develop' into IEEE-259-add-description-box-on-teams-hom…
Mustaballer Jan 16, 2024
69e0f65
IEEE-259 Add title and project description to admin page
Jan 28, 2024
094bacc
IEEE-259 Clean code in CartSummary.tsx
Jan 28, 2024
b8755ba
IEEE-259 Add project description character limit display and fix tests
Jan 28, 2024
7db2858
IEEE-259 refactor project description component and teamDetail slice
Jan 30, 2024
7d20e6e
IEEE-259 Fix dashboard and teamDetails test cases
Jan 30, 2024
c3eff7b
Merge branch 'develop' into IEEE-259-add-description-box-on-teams-hom…
Mustaballer Feb 1, 2024
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
1 change: 1 addition & 0 deletions hackathon_site/dashboard/frontend/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export interface Team {
created_at: string;
updated_at: string;
profiles: ProfileWithUser[];
project_description: string;
}

export interface ProfileWithUser extends ProfileWithoutTeamNumber {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useState } from "react";
import { Formik, Form, Field, FormikValues } from "formik";
import * as Yup from "yup";
import { TextField, Button, Box, Grid } from "@material-ui/core";
import { useDispatch } from "react-redux";
import { updateProjectDescription } from "slices/event/teamDetailSlice";

interface ProjectDescriptionProps {
teamCode: string;
}

const ProjectDescription = ({ teamCode }: ProjectDescriptionProps) => {
const dispatch = useDispatch();
const initialProjectDescription = "Write your project description here";
const [isEditing, setIsEditing] = useState(false);
const projectDescriptionSchema = Yup.object().shape({
projectDescription: Yup.string()
.max(500)
.required("Project description is required"),
});

const handleSubmit = async (values: FormikValues, { setSubmitting }: any) => {
try {
await dispatch(
updateProjectDescription({
teamCode: teamCode,
projectDescription: values.projectDescription,
})
);
} catch (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should probably throw an error snackbar in case of an error, and also make a unit test for this snackbar

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually is it necessary to have this try and catch block here? Doesn't the thunk already handle the asynchronous logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I believe it's not necessary

} finally {
setSubmitting(false);
}
};

return (
<div>
<Formik
initialValues={{ projectDescription: initialProjectDescription }}
validationSchema={projectDescriptionSchema}
onSubmit={handleSubmit}
>
{({ isSubmitting, isValid }) => (
<Form>
<Field
as={TextField}
name="projectDescription"
multiline
fullWidth
variant="outlined"
disabled={!isEditing}
rows={4}
style={{ margin: "20px 5px 0 0" }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put the styling in this file in ProjectDescription.module.scss. Reminder for scss you need to compile in order for the css to show, refer to README.md on how to do that.

/>
<Box mt={2}>
<Grid container justifyContent="flex-end">
{isEditing ? (
<>
<Button
type="submit"
variant="contained"
disabled={!isValid || isSubmitting}
style={{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put in ProjectDescription.module.scss

width: "120px",
marginRight: "10px",
}}
>
SUBMIT
</Button>
<Button
type="button"
variant="contained"
color="secondary"
style={{ width: "120px" }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put in ProjectDescription.module.scss

onClick={() => setIsEditing(false)}
>
CANCEL
</Button>
</>
) : (
<Button
type="button"
variant="contained"
color="primary"
style={{ width: "120px" }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put in ProjectDescription.module.scss

onClick={() => setIsEditing(true)}
>
EDIT
</Button>
)}
</Grid>
</Box>
</Form>
)}
</Formik>
</div>
);
};

export default ProjectDescription;
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import AlertBox from "components/general/AlertBox/AlertBox";
import { openTeamModalItem } from "slices/ui/uiSlice";
import EditTeam from "components/dashboard/EditTeam/EditTeam";
import DateRestrictionAlert from "components/general/DateRestrictionAlert/DateRestrictionAlert";
import ProjectDescription from "components/teamDetail/ProjectDescription/ProjectDescription";

const Dashboard = () => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -122,6 +123,9 @@ const Dashboard = () => {
{fetchOrderError && <AlertBox error={fetchOrderError} />}
{/* TODO: add back in when incident reports are completed on the frontend */}
{/* <BrokenTable items={itemsBroken} openReportAlert={openBrokenTable} /> */}
<ProjectDescription
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do <ProjectDescription teamCode={team_code ?? "None"} /> to make it cleaner

teamCode={team_code == null ? "None" : team_code}
/>
<PendingTables />
<CheckedOutTables />
<ReturnedTable />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
teamInfoErrorSelector,
updateParticipantIdErrorSelector,
updateParticipantIdProvided,
updateProjectDescription,
} from "slices/event/teamDetailSlice";

import { get, patch } from "api/api";
Expand Down Expand Up @@ -216,3 +217,58 @@ describe("updateParticipantIdProvided thunk", () => {
);
});
});

describe("updateProjectDescription thunk", () => {
it("Updates the store on API success", async () => {
const store = mockStore(); // Initialize mock store

// Define the parameters for the thunk
const params = {
teamCode: "A48E5",
projectDescription: "Updated project description",
};

const mockApiResponse = { ...mockTeam };
mockApiResponse.project_description = "Updated project description";
let mockResponse = makeMockApiResponse(mockApiResponse);
mockedPatch.mockResolvedValueOnce(mockResponse);

await store.dispatch(updateProjectDescription(params));

await waitFor(() => {
expect(mockedPatch).toHaveBeenCalledWith(
`/api/event/teams/${mockTeam.team_code}`,
{
project_description: "Updated project description",
}
);
});
});
it("Dispatches snackbar on API failure", async () => {
const store = mockStore();

const params = {
teamCode: "A48E5",
projectDescription: "Updated project description",
};

mockedPatch.mockRejectedValueOnce(teamFailureResponse);
await store.dispatch(updateProjectDescription(params));

expect(mockedPatch).toHaveBeenCalledWith(
`/api/event/teams/${mockTeam.team_code}`,
{
project_description: "Updated project description",
}
);

const actions = store.getActions();

expect(actions).toContainEqual(
displaySnackbar({
message: "Could not update project description: Error 404",
options: { variant: "error" },
})
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ interface idProvidedParameters {
idProvided: boolean;
}

interface UpdateProjectDescriptionParams {
teamCode: string;
projectDescription: string;
}

export const updateParticipantIdProvided = createAsyncThunk<
Profile,
idProvidedParameters,
Expand Down Expand Up @@ -103,6 +108,39 @@ export const getTeamInfoData = createAsyncThunk<
}
);

export const updateProjectDescription = createAsyncThunk<
Team,
UpdateProjectDescriptionParams,
{ state: RootState; rejectValue: RejectValue; dispatch: AppDispatch }
>(
`${teamDetailReducerName}/updateProjectDescription`,
async ({ teamCode, projectDescription }, { rejectWithValue, dispatch }) => {
try {
const response = await patch<Team>(`/api/event/teams/${teamCode}`, {
project_description: projectDescription,
});
return response.data;
} catch (e: any) {
const message =
e.response.statusText === "Not Found"
? `Could not update project description: Error ${e.response.status}`
: `Something went wrong: Error ${e.response.status}`;
dispatch(
displaySnackbar({
message,
options: {
variant: "error",
},
})
);
return rejectWithValue({
status: e.response.status,
message,
});
}
}
);

const teamDetailSlice = createSlice({
name: teamDetailReducerName,
initialState,
Expand Down Expand Up @@ -142,6 +180,19 @@ const teamDetailSlice = createSlice({
state.isParticipantIdLoading = false;
state.participantIdError = payload?.message ?? "Something went wrong";
});

builder.addCase(updateProjectDescription.pending, (state) => {
state.isTeamInfoLoading = true;
state.teamInfoError = null;
});
builder.addCase(updateProjectDescription.fulfilled, (state, { payload }) => {
state.isTeamInfoLoading = false;
state.teamInfoError = null;
});
builder.addCase(updateProjectDescription.rejected, (state, { payload }) => {
state.isTeamInfoLoading = false;
state.teamInfoError = payload?.message ?? "Something went wrong";
});
},
});

Expand Down
3 changes: 3 additions & 0 deletions hackathon_site/dashboard/frontend/src/testing/mockData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export const mockTeam: Team = {
},
},
],
project_description: "",
};

export const mockTeamMultiple = {
Expand Down Expand Up @@ -370,6 +371,7 @@ export const mockValidTeam: Team = {
},
},
],
project_description: "",
};

// Team with too many members
Expand Down Expand Up @@ -450,6 +452,7 @@ export const mockLargeTeam: Team = {
},
},
],
project_description: "",
};

export const mockHardware: Hardware[] = [
Expand Down
Loading