From 9d4769101a85e1d0db03d3bd08a5c4ca61a8723c Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Mon, 20 Apr 2020 15:55:19 +0200 Subject: [PATCH] Add Services folder and use service to interact with API --- app.db | Bin 106496 -> 106496 bytes client/src/VM/UserVM.ts | 4 +- client/src/components/Lists/ProjectList.tsx | 4 +- .../src/components/Modals/NewProjectModal.tsx | 8 +- .../src/components/Modals/NewTicketModal.tsx | 10 +- client/src/components/Panels/UserTabPanel.tsx | 10 +- client/src/controllers/ProjectController.tsx | 100 +++++++++--------- client/src/controllers/TicketController.tsx | 39 ++++--- client/src/controllers/UserController.tsx | 59 ++++------- client/src/pages/UserPage.tsx | 10 +- client/src/services/http.ts | 72 +++++++++++++ client/src/services/index.ts | 13 +++ client/src/services/project.ts | 38 +++++++ client/src/services/ticket.ts | 42 ++++++++ client/src/services/user.ts | 33 ++++++ 15 files changed, 306 insertions(+), 136 deletions(-) create mode 100644 client/src/services/http.ts create mode 100644 client/src/services/index.ts create mode 100644 client/src/services/project.ts create mode 100644 client/src/services/ticket.ts create mode 100644 client/src/services/user.ts diff --git a/app.db b/app.db index a8c3bd0aabfc3814a7263785df14202f6d1a9a1f..562fdf60a4898452d344f0ca2fb381ff27004b24 100644 GIT binary patch delta 159 zcmZoTz}9epZ39aH4-20j1OIG(LB9EXdYc6W63=|AatxSxq3@!BxO$;n7jo~t;3I+yNU^G2ZpHXG= y{5W?(MwaI1`O}~0Gs^O?@HaB>|KY#Pzly&RXlEh+`=xqDJp};IcPnxL delta 66 zcmZoTz}9epZ39aH7c<{{2L9Rnf_(Eg3kpo++dMzcU67Hv`FZ~I=lP7XT+IBd82JD2 WU*=y0l%B&sdA+~J_Dl7QdI|u`$QB>~ diff --git a/client/src/VM/UserVM.ts b/client/src/VM/UserVM.ts index a0e878e..0930e58 100644 --- a/client/src/VM/UserVM.ts +++ b/client/src/VM/UserVM.ts @@ -16,9 +16,8 @@ export class UserVM { public projects: Project[]; public tickets: Ticket[]; public activities: Activity[]; - public allUsers: User[]; - public constructor(user: User, allUsers: User[]) { + public constructor(user: User) { this.id = user.id; this.firstName = user.firstName; this.lastName = user.lastName; @@ -31,6 +30,5 @@ 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 e20cba5..eaea250 100644 --- a/client/src/components/Lists/ProjectList.tsx +++ b/client/src/components/Lists/ProjectList.tsx @@ -27,10 +27,9 @@ const useStyles = makeStyles((theme: Theme) => type IProps = { projects: Project[]; - allUsers: User[]; }; -const ProjectList: FC = ({ projects, allUsers }) => { +const ProjectList: FC = ({ projects }) => { const [filterText, setFilterText] = useState(""); const clearFilterText: (e: MouseEvent) => void = (e: MouseEvent) => { setFilterText(""); @@ -59,7 +58,6 @@ const ProjectList: FC = ({ projects, allUsers }) => { setShowNew(false); }} show={showNew} - allUsers={allUsers} /> void; - allUsers: User[]; } const NewProjectModal: FC = ({ show, handleClose }) => { const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [endingDate, setEndingDate] = useState(""); + const { getTokenSilently, user } = useAuth0(); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); @@ -26,7 +28,9 @@ const NewProjectModal: FC = ({ show, handleClose }) => { managerId: "cd179eb7-3a54-4060-b22c-3e947bdffcbc", // get current User id }; - await post(`${Constants.projectsURI}`, newProject); + const token = await getTokenSilently(); + const Projects = new ProjectService(token); + await Projects.add(newProject); handleClose(); }; diff --git a/client/src/components/Modals/NewTicketModal.tsx b/client/src/components/Modals/NewTicketModal.tsx index bff3858..97ee1be 100644 --- a/client/src/components/Modals/NewTicketModal.tsx +++ b/client/src/components/Modals/NewTicketModal.tsx @@ -13,8 +13,8 @@ import Project from "../../types/Project"; import Category from "../../types/enums/category"; import Impact from "../../types/enums/impact"; import Difficulty from "../../types/enums/difficulty"; -import { post } from "../../utils/http"; -import Constants from "../../utils/Constants"; +import { TicketService } from "../../services"; +import { useAuth0 } from "../../authentication/auth0"; interface IProps { show: boolean; @@ -39,6 +39,7 @@ const NewTicketModal: FC = ({ show, handleClose, allProjects }) => { const [categoryID, setCategoryID] = useState(0); const [impactID, setImpactID] = useState(0); const [difficultyID, setDifficultyID] = useState(0); + const { getTokenSilently, user } = useAuth0(); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); @@ -53,8 +54,9 @@ const NewTicketModal: FC = ({ show, handleClose, allProjects }) => { category: categoryID, }; - // const response: HttpResponse = - await post(`${Constants.ticketsURI}`, newTicket); + const token = await getTokenSilently(); + const Tickets = new TicketService(token); + await Tickets.add(newTicket); handleClose(); }; diff --git a/client/src/components/Panels/UserTabPanel.tsx b/client/src/components/Panels/UserTabPanel.tsx index 8205af7..839a9de 100644 --- a/client/src/components/Panels/UserTabPanel.tsx +++ b/client/src/components/Panels/UserTabPanel.tsx @@ -51,15 +51,9 @@ interface IProps { tabNames: string[]; tickets: Ticket[]; projects: Project[]; - allUsers: User[]; } -const UserTabPanel: FC = ({ - tickets, - tabNames, - projects, - allUsers, -}) => { +const UserTabPanel: FC = ({ tickets, tabNames, projects }) => { const classes = useStyles(); const theme = useTheme(); const [value, setValue] = useState(0); @@ -94,7 +88,7 @@ const UserTabPanel: FC = ({ onChangeIndex={handleChangeIndex} > - + diff --git a/client/src/controllers/ProjectController.tsx b/client/src/controllers/ProjectController.tsx index 52208aa..b439461 100644 --- a/client/src/controllers/ProjectController.tsx +++ b/client/src/controllers/ProjectController.tsx @@ -3,12 +3,11 @@ import { useParams } from "react-router-dom"; import ErrorController from "./ErrorController"; import ProjectPage from "../pages/ProjectPage"; import ProjectVM from "../VM/ProjectVM"; -import HttpResponse from "../types/HttpResponse"; import Project from "../types/Project"; import User from "../types/User"; import Preloader from "../components/Preloader"; -import Constants from "../utils/Constants"; -import { get } from "../utils/http"; +import { ProjectService, UserService } from "../services"; +import { useAuth0 } from "../authentication/auth0"; const ProjectController: FC = () => { const [project, setProject] = useState({} as Project); @@ -18,56 +17,57 @@ const ProjectController: FC = () => { const [hasError, setHasError] = useState(false); const [error, setError] = useState(""); const { id } = useParams(); - - async function httpGetProjects(id: string): Promise { - try { - const response: HttpResponse = await get( - `${Constants.projectsURI}/${id}` - ); - if (response.parsedBody !== undefined) { - setProject(response.parsedBody); - setIsLoading(false); - } - } catch (ex) { - console.error(ex); - setHasError(true); - setError(ex); - } - } - - 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); - } - } - - async function httpGetAllProjects(): Promise { - try { - const response: HttpResponse = await get( - `${Constants.projectsURI}` - ); - if (response.parsedBody !== undefined) { - setAllProjects((response.parsedBody as unknown) as Project[]); - } - } catch (ex) { - setHasError(true); - setError(ex); - } - } + const { getTokenSilently } = useAuth0(); useEffect(() => { + const getProject = async (id: string): Promise => { + const token = await getTokenSilently(); + try { + const Projects = new ProjectService(token); + const project: Project = await Projects.get(id); + if (project !== undefined) { + setProject(project); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + + const getAllUsers = async (): Promise => { + const token = await getTokenSilently(); + try { + const Users = new UserService(token); + const response: User[] = await Users.all(); + if (response !== undefined) { + setAllUsers(response); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + + const getAllProjects = async (): Promise => { + const token = await getTokenSilently(); + try { + const Projects = new ProjectService(token); + const response: Project[] = await Projects.all(); + if (response !== undefined) { + setAllProjects(response); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + if (id !== undefined) { - httpGetProjects(id); - httpGetAllUsers(); - httpGetAllProjects(); + getProject(id); + getAllUsers(); + getAllProjects(); } else { setHasError(true); setError("Bad Request"); diff --git a/client/src/controllers/TicketController.tsx b/client/src/controllers/TicketController.tsx index 8498acb..264c893 100644 --- a/client/src/controllers/TicketController.tsx +++ b/client/src/controllers/TicketController.tsx @@ -3,11 +3,10 @@ import { useParams } from "react-router-dom"; import ErrorController from "./ErrorController"; import TicketPage from "../pages/TicketPage"; import TicketVM from "../VM/TicketVM"; -import HttpResponse from "../types/HttpResponse"; import Ticket from "../types/Ticket"; import Preloader from "../components/Preloader"; -import { get } from "../utils/http"; -import Constants from "../utils/Constants"; +import { useAuth0 } from "../authentication/auth0"; +import { TicketService } from "../services"; const TicketController: FC = () => { const [isLoading, setIsLoading] = useState(true); @@ -15,26 +14,26 @@ const TicketController: FC = () => { const [hasError, setHasError] = useState(false); const [error, setError] = useState(""); const { id } = useParams(); - - async function httpGetTicket(id: string): Promise { - try { - const response: HttpResponse = await get( - `${Constants.ticketsURI}/${id}` - ); - if (response.parsedBody !== undefined) { - setTicket(response.parsedBody); - setIsLoading(false); - } - } catch (ex) { - console.error(ex); - setHasError(true); - setError(ex); - } - } + const { getTokenSilently } = useAuth0(); useEffect(() => { + const getTicket = async (id: string): Promise => { + const token = await getTokenSilently(); + try { + const Tickets = new TicketService(token); + const response: Ticket = await Tickets.get(id); + if (response !== undefined) { + setTicket(response); + setIsLoading(false); + } + } catch (ex) { + setHasError(true); + setError(ex); + } + }; + if (id !== undefined) { - httpGetTicket(id); + getTicket(id); } else { setHasError(true); setError("Bad Request"); diff --git a/client/src/controllers/UserController.tsx b/client/src/controllers/UserController.tsx index 2a4f4f0..8abd9d6 100644 --- a/client/src/controllers/UserController.tsx +++ b/client/src/controllers/UserController.tsx @@ -3,54 +3,39 @@ import { useParams } from "react-router-dom"; import ErrorController from "./ErrorController"; import UserPage from "../pages/UserPage"; import { UserVM } from "../VM/UserVM"; -import HttpResponse from "../types/HttpResponse"; import User from "../types/User"; import Preloader from "../components/Preloader"; -import Constants from "../utils/Constants"; -import { get } from "../utils/http"; +import { UserService } from "../services"; +import { useAuth0 } from "../authentication/auth0"; const UserController: FC = () => { const [isLoading, setIsLoading] = useState(true); 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 { - try { - const response: HttpResponse = await get( - `${Constants.usersURI}/${id}` - ); - if (response.parsedBody !== undefined) { - setUser(response.parsedBody); - setIsLoading(false); - } - } catch (ex) { - console.error(ex); - setHasError(true); - setError(ex); - } - } - - 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); - } - } + const { getTokenSilently } = useAuth0(); useEffect(() => { + const getUser = async (id: string): Promise => { + try { + const token = await getTokenSilently(); + const Users = new UserService(token); + const response: User = await Users.get(id); + + if (response !== undefined) { + setUser(response); + setIsLoading(false); + } + } catch (ex) { + console.error(ex); + setHasError(true); + setError(ex); + } + }; + if (id !== undefined) { - httpGetUser(id); - httpGetAllUsers(); + getUser(id); } else { setHasError(true); setError("Bad Request"); @@ -61,7 +46,7 @@ const UserController: FC = () => { return ; } - const viewModel = new UserVM(user, allUsers); + const viewModel = new UserVM(user); return isLoading ? : ; }; diff --git a/client/src/pages/UserPage.tsx b/client/src/pages/UserPage.tsx index 35960e7..fc358e0 100644 --- a/client/src/pages/UserPage.tsx +++ b/client/src/pages/UserPage.tsx @@ -9,14 +9,7 @@ interface IProps { } const UserPage: FC = ({ viewModel }) => { - const { - fullName, - presentation, - picture, - projects, - tickets, - allUsers, - } = viewModel; + const { fullName, presentation, picture, projects, tickets } = viewModel; const tabNames: string[] = ["Projects", "Tickets"]; return ( @@ -33,7 +26,6 @@ const UserPage: FC = ({ viewModel }) => { tabNames={tabNames} projects={projects} tickets={tickets} - allUsers={allUsers} /> } /> diff --git a/client/src/services/http.ts b/client/src/services/http.ts new file mode 100644 index 0000000..7908950 --- /dev/null +++ b/client/src/services/http.ts @@ -0,0 +1,72 @@ +import HttpResponse from "../types/HttpResponse"; + +export default class HttpHandler { + private newHeaders = async (token: string) => { + // const { getTokenSilently } = useAuth0(); + // const token = await getTokenSilently(); + + return new Headers({ + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }); + }; + + private execute = async (request: RequestInfo): Promise> => { + const response: HttpResponse = await fetch(request); + try { + response.parsedBody = await response.json(); + } catch (ex) {} + if (!response.ok) { + throw response.statusText; + } + return response; + }; + + get = async (path: string, token: string): Promise> => { + const args: RequestInit = { + method: "get", + headers: await this.newHeaders(token), + }; + return await this.execute(new Request(path, args)); + }; + + post = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "post", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; + + put = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "put", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; + + patch = async ( + path: string, + body: any, + token: string + ): Promise> => { + const args: RequestInit = { + method: "patch", + headers: await this.newHeaders(token), + body: JSON.stringify(body), + }; + return await this.execute(new Request(path, args)); + }; +} diff --git a/client/src/services/index.ts b/client/src/services/index.ts new file mode 100644 index 0000000..7266453 --- /dev/null +++ b/client/src/services/index.ts @@ -0,0 +1,13 @@ +import ProjectService from "./project"; +import TicketService from "./ticket"; +import UserService from "./user"; + +export default interface IService { + all(): Promise; + get(id: string): Promise; + add(item: any): Promise; + update(id: string, item: T): Promise; + delete(id: string): Promise; +} + +export { ProjectService, TicketService, UserService }; diff --git a/client/src/services/project.ts b/client/src/services/project.ts new file mode 100644 index 0000000..178e489 --- /dev/null +++ b/client/src/services/project.ts @@ -0,0 +1,38 @@ +import IService from "."; +import Project from "../types/Project"; +import HttpHandler from "./http"; + +interface NewProject { + title: string; + description: string; + endingDate: string; + managerId: string; +} +export default class ProjectService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/projects"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as Project[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as Project); + }; + + add = async (item: NewProject): Promise => { + await this.http.post(this.path, item, this.key); + }; + + update(id: string, item: Project): Promise { + throw new Error("Method not implemented."); + } + delete(id: string): Promise { + throw new Error("Method not implemented."); + } +} diff --git a/client/src/services/ticket.ts b/client/src/services/ticket.ts new file mode 100644 index 0000000..37382a0 --- /dev/null +++ b/client/src/services/ticket.ts @@ -0,0 +1,42 @@ +import IService from "."; +import Ticket from "../types/Ticket"; +import HttpHandler from "./http"; + +interface NewTicket { + title: string; + description: string; + endingDate: string; + creatorId: string; + projectId: number; + impact: number; + difficulty: number; + category: number; +} +export default class TicketService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/tickets"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as Ticket[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as Ticket); + }; + + add = async (item: NewTicket): Promise => { + await this.http.post(this.path, item, this.key); + }; + + update(id: string, item: Ticket): Promise { + throw new Error("Method not implemented."); + } + delete(id: string): Promise { + throw new Error("Method not implemented."); + } +} diff --git a/client/src/services/user.ts b/client/src/services/user.ts new file mode 100644 index 0000000..5eec469 --- /dev/null +++ b/client/src/services/user.ts @@ -0,0 +1,33 @@ +import IService from "."; +import User from "../types/User"; +import HttpHandler from "./http"; + +export default class UserService implements IService { + constructor(private key: string) {} + + private http = new HttpHandler(); + private path: string = "/api/v1/users"; + + all = async (): Promise => { + const response = await this.http.get(this.path, this.key); + return (response.parsedBody as unknown) as User[]; + }; + + get = async (id: string): Promise => { + const response = await this.http.get(`${this.path}/${id}`, this.key); + const body = response.parsedBody; + return body ?? ({} as User); + }; + + add = async (item: User): Promise => { + await this.http.post(this.path, item, this.key); + }; + + update = async (id: string, item: User): Promise => { + throw new Error("Method not implemented."); + }; + + delete = async (id: string): Promise => { + throw new Error("Method not implemented."); + }; +}