From 1368859860ed3bf3c4825b80e5849fcf7528a5fd Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Sat, 18 Apr 2020 11:47:25 +0200 Subject: [PATCH] Created NewProjectModal not implemented yet --- README.md | 2 +- client/src/VM/UserVM.ts | 4 +- client/src/components/Lists/ProjectList.tsx | 110 +++++---- .../src/components/Modals/NewProjectModal.tsx | 214 ++++++++++++++++++ client/src/components/Panels/UserTabPanel.tsx | 11 +- .../src/components/Panels/UserTabRouter.tsx | 2 +- client/src/controllers/UserController.tsx | 18 +- client/src/pages/UserPage.tsx | 10 +- 8 files changed, 321 insertions(+), 50 deletions(-) create mode 100644 client/src/components/Modals/NewProjectModal.tsx diff --git a/README.md b/README.md index 7be337c..59de80e 100644 --- a/README.md +++ b/README.md @@ -56,5 +56,5 @@ - [ ] Refactor Lists code - [ ] Query project members in UserPage - [ ] Query progression info in UserPage -- [ ] Add info fields in New Ticket Form +- [x] Add info fields in New Ticket Form - [ ] Filter users in Users Modal diff --git a/client/src/VM/UserVM.ts b/client/src/VM/UserVM.ts index 5152faf..0ddbfcf 100644 --- a/client/src/VM/UserVM.ts +++ b/client/src/VM/UserVM.ts @@ -16,8 +16,9 @@ export class UserVM { public projects: Project[]; public tickets: Ticket[]; public activities: Activity[]; + public allUsers: User[]; - public constructor(user: User) { + public constructor(user: User, allUsers: User[]) { this.id = user.id; this.firstName = user.firstName; this.lastName = user.lastName; @@ -30,5 +31,6 @@ export class UserVM { this.projects = user.projects; this.tickets = user.tickets; this.activities = user.activities; + this.allUsers = allUsers; } } diff --git a/client/src/components/Lists/ProjectList.tsx b/client/src/components/Lists/ProjectList.tsx index a7ca012..873e83a 100644 --- a/client/src/components/Lists/ProjectList.tsx +++ b/client/src/components/Lists/ProjectList.tsx @@ -8,26 +8,38 @@ import { } from "@material-ui/core"; import { FilterBar } from "../FilterBar"; import ProjectCard from "../Cards/ProjectCard"; +import { FloatingButton } from "../Buttons/FloatingButton"; +import { NewProjectModal } from "../Modals/NewProjectModal"; import { Project } from "../../types/Project"; +import { User } from "../../types/User"; const useStyles = makeStyles((theme: Theme) => createStyles({ header: { paddingBottom: theme.spacing(2), }, + addButton: { + position: "relative", + marginLeft: "20px", + }, }) ); type IProps = { projects: Project[]; + allUsers: User[]; }; -export const ProjectList: FC = ({ projects }) => { +export const ProjectList: FC = ({ projects, allUsers }) => { const [filterText, setFilterText] = useState(""); const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); }; - + const [showNew, setShowNew] = useState(false); + const onClick = (e: MouseEvent): void => { + e.preventDefault(); + setShowNew(true); + }; const handleChange = (e: ChangeEvent): void => { setFilterText(e.target.value); }; @@ -41,47 +53,59 @@ export const ProjectList: FC = ({ projects }) => { const classes = useStyles(); return ( - - - - Projects - - + <> + { + setShowNew(false); + }} + show={showNew} + allUsers={allUsers} + /> + + + + Projects + + + + + + + +
+ {filteredProjects.length === 0 ? ( + + ) : ( + filteredProjects.map((t: Project) => ( + t.status === "Done").length + } + /> + )) + )} +
+
- -
- {filteredProjects.length === 0 ? ( - - ) : ( - filteredProjects.map((t: Project) => ( - t.status === "Done").length - } - /> - )) - )} -
-
-
+ ); }; diff --git a/client/src/components/Modals/NewProjectModal.tsx b/client/src/components/Modals/NewProjectModal.tsx new file mode 100644 index 0000000..94476ec --- /dev/null +++ b/client/src/components/Modals/NewProjectModal.tsx @@ -0,0 +1,214 @@ +import React, { FC, useState, FormEvent } from "react"; +import { useRouteMatch } from "react-router-dom"; +import { + TextField, + MenuItem, + Grid, + makeStyles, + Theme, + createStyles, +} from "@material-ui/core"; +import { Modal } from "./Modal"; +import { Ticket } from "../../types/Ticket"; +import { User } from "../../types/User"; +import { post } from "../../utils/http"; +import { Constants } from "../../utils/Constants"; +import Category from "../../types/enums/category"; +import Impact from "../../types/enums/impact"; +import Difficulty from "../../types/enums/difficulty"; + +interface IProps { + show: boolean; + handleClose: () => void; + allUsers: User[]; +} + +const useStyles = makeStyles((theme: Theme) => ({ + select: { + width: 120, + }, +})); + +export const NewProjectModal: FC = ({ + show, + handleClose, + allUsers, +}) => { + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [endingDate, setEndingDate] = useState(""); + + const { url } = useRouteMatch(); + const id = url.split("/")[2]; + const [projectId, setProjectId] = useState(id); + const [categoryID, setCategoryID] = useState(0); + const [impactID, setImpactID] = useState(0); + const [difficultyID, setDifficultyID] = useState(0); + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + let newTicket = { + title: title, + description: description, + endingDate: new Date(endingDate).toISOString(), + creatorId: "20bf4b2a-7209-4826-96cd-29c2bc937a94", // get current User id + projectId: parseInt(projectId), + impact: impactID, + difficulty: difficultyID, + category: categoryID, + }; + + // const response: HttpResponse = + await post(`${Constants.ticketsURI}`, newTicket); + handleClose(); + }; + + const classes = useStyles(); + return ( + + ) => + setTitle(e.target.value) + } + autoFocus + /> + + ) => + setDescription(e.target.value) + } + multiline + /> + + ) => { + e.preventDefault(); + setProjectId(e.target.value); + }} + // helperText="Please select your currency" + variant="outlined" + margin="normal" + > + {allUsers.map((p) => ( + + {p} + + ))} + + + ) => + setEndingDate(e.target.value) + } + /> + + + ) => { + e.preventDefault(); + setCategoryID(parseInt(e.target.value)); + }} + variant="outlined" + margin="normal" + className={classes.select} + > + {Category.map((c: string, i: number) => ( + + {c} + + ))} + + + ) => { + e.preventDefault(); + setImpactID(parseInt(e.target.value)); + }} + variant="outlined" + margin="normal" + > + {Impact.map((c: string, i: number) => ( + + {c} + + ))} + + + ) => { + e.preventDefault(); + setDifficultyID(parseInt(e.target.value)); + }} + variant="outlined" + margin="normal" + > + {Difficulty.map((c: string, i: number) => ( + + {c} + + ))} + + + + ); +}; diff --git a/client/src/components/Panels/UserTabPanel.tsx b/client/src/components/Panels/UserTabPanel.tsx index 17123cf..c23b783 100644 --- a/client/src/components/Panels/UserTabPanel.tsx +++ b/client/src/components/Panels/UserTabPanel.tsx @@ -10,6 +10,7 @@ import { Ticket } from "../../types/Ticket"; import { Project } from "../../types/Project"; import { ProjectList } from "../Lists/ProjectList"; import { TicketList } from "../Lists/TicketList"; +import { User } from "../../types/User"; interface TabProps { children?: ReactNode; @@ -53,9 +54,15 @@ interface IProps { tabNames: string[]; tickets: Ticket[]; projects: Project[]; + allUsers: User[]; } -export const UserTabPanel: FC = ({ tickets, tabNames, projects }) => { +export const UserTabPanel: FC = ({ + tickets, + tabNames, + projects, + allUsers, +}) => { const classes = useStyles(); const theme = useTheme(); const [value, setValue] = useState(0); @@ -94,7 +101,7 @@ export const UserTabPanel: FC = ({ tickets, tabNames, projects }) => { onChangeIndex={handleChangeIndex} > - + diff --git a/client/src/components/Panels/UserTabRouter.tsx b/client/src/components/Panels/UserTabRouter.tsx index dd3fea1..6a45d4d 100644 --- a/client/src/components/Panels/UserTabRouter.tsx +++ b/client/src/components/Panels/UserTabRouter.tsx @@ -23,7 +23,7 @@ export const UserTabRouter: FC = ({ tickets, tabNames, projects }) => { - + {/* */} diff --git a/client/src/controllers/UserController.tsx b/client/src/controllers/UserController.tsx index 181a3fa..fc31881 100644 --- a/client/src/controllers/UserController.tsx +++ b/client/src/controllers/UserController.tsx @@ -14,6 +14,7 @@ export const UserController: FC = () => { const [user, setUser] = useState({} as User); const [hasError, setHasError] = useState(false); const [error, setError] = useState(""); + const [allUsers, setAllUsers] = useState([]); const { id } = useParams(); async function httpGetUser(id: string): Promise { @@ -32,9 +33,24 @@ export const UserController: FC = () => { } } + async function httpGetAllUsers(): Promise { + try { + const response: HttpResponse = await get( + `${Constants.usersURI}` + ); + if (response.parsedBody !== undefined) { + setAllUsers((response.parsedBody as unknown) as User[]); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + } + useEffect(() => { if (id !== undefined) { httpGetUser(id); + httpGetAllUsers(); } else { setHasError(true); setError("Bad Request"); @@ -45,6 +61,6 @@ export const UserController: FC = () => { return ; } - const viewModel = new UserVM(user); + const viewModel = new UserVM(user, allUsers); return isLoading ? : ; }; diff --git a/client/src/pages/UserPage.tsx b/client/src/pages/UserPage.tsx index b528959..b3d8e2c 100644 --- a/client/src/pages/UserPage.tsx +++ b/client/src/pages/UserPage.tsx @@ -9,7 +9,14 @@ interface IProps { } export const UserPage: FC = ({ viewModel }) => { - const { fullName, presentation, picture, projects, tickets } = viewModel; + const { + fullName, + presentation, + picture, + projects, + tickets, + allUsers, + } = viewModel; const tabNames: string[] = ["Projects", "Tickets"]; return ( @@ -26,6 +33,7 @@ export const UserPage: FC = ({ viewModel }) => { tabNames={tabNames} projects={projects} tickets={tickets} + allUsers={allUsers} /> } />