Merge branch 'dev' into gruppPP
This commit is contained in:
		
						commit
						4ab23b3c3c
					
				
					 70 changed files with 3279 additions and 1171 deletions
				
			
		|  | @ -49,7 +49,6 @@ interface API { | |||
|    * @returns {Promise<APIResponse<boolean>>} A promise containing the API response indicating if the user is a project manager. | ||||
|    */ | ||||
|   checkIfProjectManager( | ||||
|     username: string, | ||||
|     projectName: string, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<boolean>>; | ||||
|  | @ -87,7 +86,7 @@ interface API { | |||
|   submitWeeklyReport( | ||||
|     weeklyReport: NewWeeklyReport, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<NewWeeklyReport>>; | ||||
|   ): Promise<APIResponse<string>>; | ||||
| 
 | ||||
|   /** Gets a weekly report for a specific user, project and week | ||||
|    * @param {string} projectName The name of the project. | ||||
|  | @ -153,6 +152,23 @@ interface API { | |||
|     user: NewProjMember, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<NewProjMember>>; | ||||
| 
 | ||||
|   removeProject( | ||||
|     projectName: string, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<string>>; | ||||
| 
 | ||||
|   /** | ||||
|    * Signs a report. Keep in mind that the user which the token belongs to must be | ||||
|    * the project manager of the project the report belongs to. | ||||
|    * | ||||
|    * @param {number} reportId The id of the report to sign | ||||
|    * @param {string} token The authentication token | ||||
|    */ | ||||
|   signReport( | ||||
|     reportId: number, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<string>>; | ||||
| } | ||||
| 
 | ||||
| /** An instance of the API */ | ||||
|  | @ -208,19 +224,20 @@ export const api: API = { | |||
|   }, | ||||
| 
 | ||||
|   async checkIfProjectManager( | ||||
|     username: string, | ||||
|     projectName: string, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<boolean>> { | ||||
|     try { | ||||
|       const response = await fetch("/api/checkIfProjectManager", { | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           "Content-Type": "application/json", | ||||
|           Authorization: "Bearer " + token, | ||||
|       const response = await fetch( | ||||
|         `/api/checkIfProjectManager/${projectName}`, | ||||
|         { | ||||
|           method: "GET", | ||||
|           headers: { | ||||
|             "Content-Type": "application/json", | ||||
|             Authorization: "Bearer " + token, | ||||
|           }, | ||||
|         }, | ||||
|         body: JSON.stringify({ username, projectName }), | ||||
|       }); | ||||
|       ); | ||||
| 
 | ||||
|       if (!response.ok) { | ||||
|         return { | ||||
|  | @ -232,7 +249,7 @@ export const api: API = { | |||
|         return { success: true, data }; | ||||
|       } | ||||
|     } catch (e) { | ||||
|       return { success: false, message: "fuck" }; | ||||
|       return { success: false, message: "Failed to check if project manager" }; | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|  | @ -339,7 +356,7 @@ export const api: API = { | |||
|   async submitWeeklyReport( | ||||
|     weeklyReport: NewWeeklyReport, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<NewWeeklyReport>> { | ||||
|   ): Promise<APIResponse<string>> { | ||||
|     try { | ||||
|       const response = await fetch("/api/submitWeeklyReport", { | ||||
|         method: "POST", | ||||
|  | @ -357,8 +374,8 @@ export const api: API = { | |||
|         }; | ||||
|       } | ||||
| 
 | ||||
|       const data = (await response.json()) as NewWeeklyReport; | ||||
|       return { success: true, data }; | ||||
|       const data = await response.text(); | ||||
|       return { success: true, message: data }; | ||||
|     } catch (e) { | ||||
|       return { | ||||
|         success: false, | ||||
|  | @ -553,4 +570,57 @@ export const api: API = { | |||
|       return { success: false, message: "Failed to change username" }; | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   async removeProject( | ||||
|     projectName: string, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<string>> { | ||||
|     try { | ||||
|       const response = await fetch(`/api/projectdelete/${projectName}`, { | ||||
|         method: "DELETE", | ||||
|         headers: { | ||||
|           "Content-Type": "application/json", | ||||
|           Authorization: "Bearer " + token, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       if (!response.ok) { | ||||
|         return Promise.resolve({ | ||||
|           success: false, | ||||
|           message: "Failed to remove project", | ||||
|         }); | ||||
|       } else { | ||||
|         const data = await response.text(); | ||||
|         return Promise.resolve({ success: true, message: data }); | ||||
|       } | ||||
|     } catch (e) { | ||||
|       return Promise.resolve({ | ||||
|         success: false, | ||||
|         message: "Failed to remove project", | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   async signReport( | ||||
|     reportId: number, | ||||
|     token: string, | ||||
|   ): Promise<APIResponse<string>> { | ||||
|     try { | ||||
|       const response = await fetch(`/api/signReport/${reportId}`, { | ||||
|         method: "PUT", | ||||
|         headers: { | ||||
|           "Content-Type": "application/json", | ||||
|           Authorization: "Bearer " + token, | ||||
|         }, | ||||
|       }); | ||||
| 
 | ||||
|       if (!response.ok) { | ||||
|         return { success: false, message: "Failed to sign report" }; | ||||
|       } else { | ||||
|         return { success: true, message: "Report signed" }; | ||||
|       } | ||||
|     } catch (e) { | ||||
|       return { success: false, message: "Failed to sign report" }; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										358
									
								
								frontend/src/API/GenApi.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								frontend/src/API/GenApi.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,358 @@ | |||
| /* eslint-disable */ | ||||
| /* tslint:disable */ | ||||
| /* | ||||
|  * --------------------------------------------------------------- | ||||
|  * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API        ## | ||||
|  * ##                                                           ## | ||||
|  * ## AUTHOR: acacode                                           ## | ||||
|  * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
 | ||||
|  * --------------------------------------------------------------- | ||||
|  */ | ||||
| 
 | ||||
| export interface TypesNewUser { | ||||
|   /** @example "password123" */ | ||||
|   password?: string; | ||||
|   /** @example "username123" */ | ||||
|   username?: string; | ||||
| } | ||||
| 
 | ||||
| export interface TypesToken { | ||||
|   token?: string; | ||||
| } | ||||
| 
 | ||||
| export type QueryParamsType = Record<string | number, any>; | ||||
| export type ResponseFormat = keyof Omit<Body, "body" | "bodyUsed">; | ||||
| 
 | ||||
| export interface FullRequestParams extends Omit<RequestInit, "body"> { | ||||
|   /** set parameter to `true` for call `securityWorker` for this request */ | ||||
|   secure?: boolean; | ||||
|   /** request path */ | ||||
|   path: string; | ||||
|   /** content type of request body */ | ||||
|   type?: ContentType; | ||||
|   /** query params */ | ||||
|   query?: QueryParamsType; | ||||
|   /** format of response (i.e. response.json() -> format: "json") */ | ||||
|   format?: ResponseFormat; | ||||
|   /** request body */ | ||||
|   body?: unknown; | ||||
|   /** base url */ | ||||
|   baseUrl?: string; | ||||
|   /** request cancellation token */ | ||||
|   cancelToken?: CancelToken; | ||||
| } | ||||
| 
 | ||||
| export type RequestParams = Omit<FullRequestParams, "body" | "method" | "query" | "path">; | ||||
| 
 | ||||
| export interface ApiConfig<SecurityDataType = unknown> { | ||||
|   baseUrl?: string; | ||||
|   baseApiParams?: Omit<RequestParams, "baseUrl" | "cancelToken" | "signal">; | ||||
|   securityWorker?: (securityData: SecurityDataType | null) => Promise<RequestParams | void> | RequestParams | void; | ||||
|   customFetch?: typeof fetch; | ||||
| } | ||||
| 
 | ||||
| export interface HttpResponse<D extends unknown, E extends unknown = unknown> extends Response { | ||||
|   data: D; | ||||
|   error: E; | ||||
| } | ||||
| 
 | ||||
| type CancelToken = Symbol | string | number; | ||||
| 
 | ||||
| export enum ContentType { | ||||
|   Json = "application/json", | ||||
|   FormData = "multipart/form-data", | ||||
|   UrlEncoded = "application/x-www-form-urlencoded", | ||||
|   Text = "text/plain", | ||||
| } | ||||
| 
 | ||||
| export class HttpClient<SecurityDataType = unknown> { | ||||
|   public baseUrl: string = "//localhost:8080/api"; | ||||
|   private securityData: SecurityDataType | null = null; | ||||
|   private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"]; | ||||
|   private abortControllers = new Map<CancelToken, AbortController>(); | ||||
|   private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams); | ||||
| 
 | ||||
|   private baseApiParams: RequestParams = { | ||||
|     credentials: "same-origin", | ||||
|     headers: {}, | ||||
|     redirect: "follow", | ||||
|     referrerPolicy: "no-referrer", | ||||
|   }; | ||||
| 
 | ||||
|   constructor(apiConfig: ApiConfig<SecurityDataType> = {}) { | ||||
|     Object.assign(this, apiConfig); | ||||
|   } | ||||
| 
 | ||||
|   public setSecurityData = (data: SecurityDataType | null) => { | ||||
|     this.securityData = data; | ||||
|   }; | ||||
| 
 | ||||
|   protected encodeQueryParam(key: string, value: any) { | ||||
|     const encodedKey = encodeURIComponent(key); | ||||
|     return `${encodedKey}=${encodeURIComponent(typeof value === "number" ? value : `${value}`)}`; | ||||
|   } | ||||
| 
 | ||||
|   protected addQueryParam(query: QueryParamsType, key: string) { | ||||
|     return this.encodeQueryParam(key, query[key]); | ||||
|   } | ||||
| 
 | ||||
|   protected addArrayQueryParam(query: QueryParamsType, key: string) { | ||||
|     const value = query[key]; | ||||
|     return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); | ||||
|   } | ||||
| 
 | ||||
|   protected toQueryString(rawQuery?: QueryParamsType): string { | ||||
|     const query = rawQuery || {}; | ||||
|     const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]); | ||||
|     return keys | ||||
|       .map((key) => (Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key))) | ||||
|       .join("&"); | ||||
|   } | ||||
| 
 | ||||
|   protected addQueryParams(rawQuery?: QueryParamsType): string { | ||||
|     const queryString = this.toQueryString(rawQuery); | ||||
|     return queryString ? `?${queryString}` : ""; | ||||
|   } | ||||
| 
 | ||||
|   private contentFormatters: Record<ContentType, (input: any) => any> = { | ||||
|     [ContentType.Json]: (input: any) => | ||||
|       input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input, | ||||
|     [ContentType.Text]: (input: any) => (input !== null && typeof input !== "string" ? JSON.stringify(input) : input), | ||||
|     [ContentType.FormData]: (input: any) => | ||||
|       Object.keys(input || {}).reduce((formData, key) => { | ||||
|         const property = input[key]; | ||||
|         formData.append( | ||||
|           key, | ||||
|           property instanceof Blob | ||||
|             ? property | ||||
|             : typeof property === "object" && property !== null | ||||
|             ? JSON.stringify(property) | ||||
|             : `${property}`, | ||||
|         ); | ||||
|         return formData; | ||||
|       }, new FormData()), | ||||
|     [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input), | ||||
|   }; | ||||
| 
 | ||||
|   protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams { | ||||
|     return { | ||||
|       ...this.baseApiParams, | ||||
|       ...params1, | ||||
|       ...(params2 || {}), | ||||
|       headers: { | ||||
|         ...(this.baseApiParams.headers || {}), | ||||
|         ...(params1.headers || {}), | ||||
|         ...((params2 && params2.headers) || {}), | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => { | ||||
|     if (this.abortControllers.has(cancelToken)) { | ||||
|       const abortController = this.abortControllers.get(cancelToken); | ||||
|       if (abortController) { | ||||
|         return abortController.signal; | ||||
|       } | ||||
|       return void 0; | ||||
|     } | ||||
| 
 | ||||
|     const abortController = new AbortController(); | ||||
|     this.abortControllers.set(cancelToken, abortController); | ||||
|     return abortController.signal; | ||||
|   }; | ||||
| 
 | ||||
|   public abortRequest = (cancelToken: CancelToken) => { | ||||
|     const abortController = this.abortControllers.get(cancelToken); | ||||
| 
 | ||||
|     if (abortController) { | ||||
|       abortController.abort(); | ||||
|       this.abortControllers.delete(cancelToken); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   public request = async <T = any, E = any>({ | ||||
|     body, | ||||
|     secure, | ||||
|     path, | ||||
|     type, | ||||
|     query, | ||||
|     format, | ||||
|     baseUrl, | ||||
|     cancelToken, | ||||
|     ...params | ||||
|   }: FullRequestParams): Promise<HttpResponse<T, E>> => { | ||||
|     const secureParams = | ||||
|       ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) && | ||||
|         this.securityWorker && | ||||
|         (await this.securityWorker(this.securityData))) || | ||||
|       {}; | ||||
|     const requestParams = this.mergeRequestParams(params, secureParams); | ||||
|     const queryString = query && this.toQueryString(query); | ||||
|     const payloadFormatter = this.contentFormatters[type || ContentType.Json]; | ||||
|     const responseFormat = format || requestParams.format; | ||||
| 
 | ||||
|     return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, { | ||||
|       ...requestParams, | ||||
|       headers: { | ||||
|         ...(requestParams.headers || {}), | ||||
|         ...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}), | ||||
|       }, | ||||
|       signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null, | ||||
|       body: typeof body === "undefined" || body === null ? null : payloadFormatter(body), | ||||
|     }).then(async (response) => { | ||||
|       const r = response as HttpResponse<T, E>; | ||||
|       r.data = null as unknown as T; | ||||
|       r.error = null as unknown as E; | ||||
| 
 | ||||
|       const data = !responseFormat | ||||
|         ? r | ||||
|         : await response[responseFormat]() | ||||
|             .then((data) => { | ||||
|               if (r.ok) { | ||||
|                 r.data = data; | ||||
|               } else { | ||||
|                 r.error = data; | ||||
|               } | ||||
|               return r; | ||||
|             }) | ||||
|             .catch((e) => { | ||||
|               r.error = e; | ||||
|               return r; | ||||
|             }); | ||||
| 
 | ||||
|       if (cancelToken) { | ||||
|         this.abortControllers.delete(cancelToken); | ||||
|       } | ||||
| 
 | ||||
|       if (!response.ok) throw data; | ||||
|       return data; | ||||
|     }); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @title TTime API | ||||
|  * @version 0.0.1 | ||||
|  * @license AGPL (https://www.gnu.org/licenses/agpl-3.0.html)
 | ||||
|  * @baseUrl //localhost:8080/api
 | ||||
|  * @externalDocs https://swagger.io/resources/open-api/
 | ||||
|  * @contact | ||||
|  * | ||||
|  * This is the API for TTime, a time tracking application. | ||||
|  */ | ||||
| export class GenApi<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> { | ||||
|   login = { | ||||
|     /** | ||||
|      * @description Logs in a user and returns a JWT token | ||||
|      * | ||||
|      * @tags Auth | ||||
|      * @name LoginCreate | ||||
|      * @summary Login | ||||
|      * @request POST:/login | ||||
|      */ | ||||
|     loginCreate: (body: TypesNewUser, params: RequestParams = {}) => | ||||
|       this.request<TypesToken, string>({ | ||||
|         path: `/login`, | ||||
|         method: "POST", | ||||
|         body: body, | ||||
|         type: ContentType.Json, | ||||
|         format: "json", | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
|   loginrenew = { | ||||
|     /** | ||||
|      * @description Renews the users token. | ||||
|      * | ||||
|      * @tags Auth | ||||
|      * @name LoginrenewCreate | ||||
|      * @summary LoginRenews | ||||
|      * @request POST:/loginrenew | ||||
|      * @secure | ||||
|      */ | ||||
|     loginrenewCreate: (params: RequestParams = {}) => | ||||
|       this.request<TypesToken, string>({ | ||||
|         path: `/loginrenew`, | ||||
|         method: "POST", | ||||
|         secure: true, | ||||
|         format: "json", | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
|   promoteToAdmin = { | ||||
|     /** | ||||
|      * @description Promote chosen user to site admin | ||||
|      * | ||||
|      * @tags User | ||||
|      * @name PromoteToAdminCreate | ||||
|      * @summary PromoteToAdmin | ||||
|      * @request POST:/promoteToAdmin | ||||
|      * @secure | ||||
|      */ | ||||
|     promoteToAdminCreate: (NewUser: TypesNewUser, params: RequestParams = {}) => | ||||
|       this.request<TypesToken, string>({ | ||||
|         path: `/promoteToAdmin`, | ||||
|         method: "POST", | ||||
|         body: NewUser, | ||||
|         secure: true, | ||||
|         type: ContentType.Json, | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
|   register = { | ||||
|     /** | ||||
|      * @description Register a new user | ||||
|      * | ||||
|      * @tags Auth | ||||
|      * @name RegisterCreate | ||||
|      * @summary Register | ||||
|      * @request POST:/register | ||||
|      */ | ||||
|     registerCreate: (NewUser: TypesNewUser, params: RequestParams = {}) => | ||||
|       this.request<string, string>({ | ||||
|         path: `/register`, | ||||
|         method: "POST", | ||||
|         body: NewUser, | ||||
|         type: ContentType.Json, | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
|   userdelete = { | ||||
|     /** | ||||
|      * @description UserDelete deletes a user from the database | ||||
|      * | ||||
|      * @tags User | ||||
|      * @name UserdeleteDelete | ||||
|      * @summary UserDelete | ||||
|      * @request DELETE:/userdelete/{username} | ||||
|      * @secure | ||||
|      */ | ||||
|     userdeleteDelete: (username: string, params: RequestParams = {}) => | ||||
|       this.request<string, string>({ | ||||
|         path: `/userdelete/${username}`, | ||||
|         method: "DELETE", | ||||
|         secure: true, | ||||
|         type: ContentType.Json, | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
|   users = { | ||||
|     /** | ||||
|      * @description lists all users | ||||
|      * | ||||
|      * @tags User | ||||
|      * @name GetUsers | ||||
|      * @summary ListsAllUsers | ||||
|      * @request GET:/users/all | ||||
|      * @secure | ||||
|      */ | ||||
|     getUsers: (params: RequestParams = {}) => | ||||
|       this.request<string[], string>({ | ||||
|         path: `/users/all`, | ||||
|         method: "GET", | ||||
|         secure: true, | ||||
|         format: "json", | ||||
|         ...params, | ||||
|       }), | ||||
|   }; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Peter KW
						Peter KW