diff --git a/src/app/services/backend.service.ts b/src/app/services/backend.service.ts index 9761298..ef79bad 100644 --- a/src/app/services/backend.service.ts +++ b/src/app/services/backend.service.ts @@ -1,282 +1,435 @@ -import { Injectable } from '@angular/core'; -import { HttpClient, HttpResponse } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { environment } from '../../environments/environment'; - -@Injectable() -export class BackendService { - constructor(private httpClient: HttpClient) {} - - // Tasks - public getTasks(): Observable> { - const url = `${environment.apiUrl}/tasks`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getTask(id: number): Observable> { - const url = `${environment.apiUrl}/tasks/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postTask(task: ScrumTask): Observable> { - const url = `${environment.apiUrl}/tasks`; - return this.httpClient.post(url, task, { observe: 'response' }); - } - - public putTask(task: ScrumTask): Observable> { - const url = `${environment.apiUrl}/tasks/${task.id}`; - return this.httpClient.put(url, task, { observe: 'response' }); - } - - public deleteTask(task: ScrumTask): Observable> { - const url = `${environment.apiUrl}/tasks/${task.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Userstories - public getUserstories(): Observable> { - const url = `${environment.apiUrl}/userstories`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getUserstory(id: number): Observable> { - const url = `${environment.apiUrl}/userstories/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postUserstory( - userstory: ScrumUserstory - ): Observable> { - const url = `${environment.apiUrl}/userstories`; - return this.httpClient.post(url, userstory, { - observe: 'response', - }); - } - - public putUserstory( - userstory: ScrumUserstory - ): Observable> { - const url = `${environment.apiUrl}/userstories/${userstory.id}`; - return this.httpClient.put(url, userstory, { observe: 'response' }); - } - - public deleteUserstory( - userstory: ScrumUserstory - ): Observable> { - const url = `${environment.apiUrl}/userstories/${userstory.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Sprints - public getSprints(): Observable> { - const url = `${environment.apiUrl}/sprints`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getSprint(id: number): Observable> { - const url = `${environment.apiUrl}/sprints/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postSprint( - sprint: ScrumSprint - ): Observable> { - const url = `${environment.apiUrl}/sprints`; - return this.httpClient.post(url, sprint, { - observe: 'response', - }); - } - - public putSprint(sprint: ScrumSprint): Observable> { - const url = `${environment.apiUrl}/sprints/${sprint.id}`; - return this.httpClient.put(url, sprint, { observe: 'response' }); - } - - public deleteSprint(sprint: ScrumSprint): Observable> { - const url = `${environment.apiUrl}/sprints/${sprint.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Categories - public getCategories(): Observable> { - const url = `${environment.apiUrl}/categories`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getCategory(id: number): Observable> { - const url = `${environment.apiUrl}/categories/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postCategory( - category: ScrumCategory - ): Observable> { - const url = `${environment.apiUrl}/categories`; - return this.httpClient.post(url, category, { - observe: 'response', - }); - } - - public putCategory(category: ScrumCategory): Observable> { - const url = `${environment.apiUrl}/categories/${category.id}`; - return this.httpClient.put(url, category, { observe: 'response' }); - } - - public deleteCategory( - category: ScrumCategory - ): Observable> { - const url = `${environment.apiUrl}/categories/${category.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Status - public getAllStatus(): Observable> { - const url = `${environment.apiUrl}/status`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getStatus(id: number): Observable> { - const url = `${environment.apiUrl}/status/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postStatus( - status: ScrumStatus - ): Observable> { - const url = `${environment.apiUrl}/status`; - return this.httpClient.post(url, status, { - observe: 'response', - }); - } - - public putStatus(status: ScrumStatus): Observable> { - const url = `${environment.apiUrl}/status/${status.id}`; - return this.httpClient.put(url, status, { observe: 'response' }); - } - - public deleteStatus(status: ScrumStatus): Observable> { - const url = `${environment.apiUrl}/status/${status.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Users - public getUsers(): Observable> { - const url = `${environment.apiUrl}/users`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getUser(id: number): Observable> { - const url = `${environment.apiUrl}/users/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postUser(user: ScrumUser): Observable> { - const url = `${environment.apiUrl}/users`; - return this.httpClient.post(url, user, { observe: 'response' }); - } - - public putUser(user: ScrumUser): Observable> { - const url = `${environment.apiUrl}/users/${user.id}`; - return this.httpClient.put(url, user, { observe: 'response' }); - } - - public deleteUser(user: ScrumUser): Observable> { - const url = `${environment.apiUrl}/users/${user.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } - - // Projects - public getProjects(): Observable> { - const url = `${environment.apiUrl}/projects`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public getProject(id: number): Observable> { - const url = `${environment.apiUrl}/projects/${id}`; - return this.httpClient.get(url, { observe: 'response' }); - } - - public postProject( - project: ScrumProject - ): Observable> { - const url = `${environment.apiUrl}/projects`; - return this.httpClient.post(url, project, { - observe: 'response', - }); - } - - public putProject(project: ScrumProject): Observable> { - const url = `${environment.apiUrl}/projects/${project.id}`; - return this.httpClient.put(url, project, { observe: 'response' }); - } - - public deleteProject(project: ScrumProject): Observable> { - const url = `${environment.apiUrl}/projects/${project.id}`; - return this.httpClient.delete(url, { observe: 'response' }); - } -} - -export enum Priority { - High = 'high', - Medium = 'medium', - Low = 'low', -} - -export interface ScrumTask { - id?: number; - title: string; - content?: string; - statusid?: number; - categoryid?: number; - assignedtoid?: number; - sprintid?: number; - projectid?: number; - userstoryid?: number; - priority?: Priority; -} - -export interface ScrumUserstory { - id?: number; - title: string; - content?: string; - priority?: Priority; - statusid?: number; - categoryid?: number; - sprintid?: number; - createdbyid?: number; - projectid?: number; -} - -export interface ScrumSprint { - id?: number; - title: string; - description?: string; - startDate: string; - endDate: string; - projectid?: number; -} - -export interface ScrumCategory { - id?: number; - title: string; - description?: string; - color?: string; - project?: number; -} - -export interface ScrumStatus { - id?: number; - title: string; - description: string; -} - -export interface ScrumUser { - id?: number; - name: string; -} - -export interface ScrumProject { - id?: number; - title: string; - isprivate: boolean; -} +import { Injectable } from '@angular/core'; +import { HttpClient, HttpResponse } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { environment } from '../../environments/environment'; + +/** + * Provides access to the backend via HTTP. + */ +@Injectable() +export class BackendService { + constructor(private httpClient: HttpClient) {} + + // Tasks + + /** + * Return all tasks. + */ + public getTasks(): Observable> { + const url = `${environment.apiUrl}/tasks`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the task with a specific id. + */ + public getTask(id: number): Observable> { + const url = `${environment.apiUrl}/tasks/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new task, if successful, the newly created task will be returned. + */ + public postTask(task: ScrumTask): Observable> { + const url = `${environment.apiUrl}/tasks`; + return this.httpClient.post(url, task, { observe: 'response' }); + } + + /** + * Replace an existing task with a new one. + */ + public putTask(task: ScrumTask): Observable> { + const url = `${environment.apiUrl}/tasks/${task.id}`; + return this.httpClient.put(url, task, { observe: 'response' }); + } + + /** + * Delete a task. + */ + public deleteTask(task: ScrumTask): Observable> { + const url = `${environment.apiUrl}/tasks/${task.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Userstories + + /** + * Return all userstories. + */ + public getUserstories(): Observable> { + const url = `${environment.apiUrl}/userstories`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the userstory with a specific id. + */ + public getUserstory(id: number): Observable> { + const url = `${environment.apiUrl}/userstories/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new userstory, if successful, the newly created userstory will be returned. + */ + public postUserstory( + userstory: ScrumUserstory + ): Observable> { + const url = `${environment.apiUrl}/userstories`; + return this.httpClient.post(url, userstory, { + observe: 'response', + }); + } + + /** + * Replace an existing userstory with a new one. + */ + public putUserstory( + userstory: ScrumUserstory + ): Observable> { + const url = `${environment.apiUrl}/userstories/${userstory.id}`; + return this.httpClient.put(url, userstory, { observe: 'response' }); + } + + /** + * Delete a userstory. + */ + public deleteUserstory( + userstory: ScrumUserstory + ): Observable> { + const url = `${environment.apiUrl}/userstories/${userstory.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Sprints + + /** + * Return all sprints. + */ + public getSprints(): Observable> { + const url = `${environment.apiUrl}/sprints`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the sprint with a specific id. + */ + public getSprint(id: number): Observable> { + const url = `${environment.apiUrl}/sprints/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new sprint, if successful, the newly created sprint will be returned. + */ + public postSprint( + sprint: ScrumSprint + ): Observable> { + const url = `${environment.apiUrl}/sprints`; + return this.httpClient.post(url, sprint, { + observe: 'response', + }); + } + + /** + * Replace an existing sprint with a new one. + */ + public putSprint(sprint: ScrumSprint): Observable> { + const url = `${environment.apiUrl}/sprints/${sprint.id}`; + return this.httpClient.put(url, sprint, { observe: 'response' }); + } + + /** + * Delete a sprint. + */ + public deleteSprint(sprint: ScrumSprint): Observable> { + const url = `${environment.apiUrl}/sprints/${sprint.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Categories + + /** + * Return all categories. + */ + public getCategories(): Observable> { + const url = `${environment.apiUrl}/categories`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the category with a specific id. + */ + public getCategory(id: number): Observable> { + const url = `${environment.apiUrl}/categories/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new category, if successful, the newly created category will be returned. + */ + public postCategory( + category: ScrumCategory + ): Observable> { + const url = `${environment.apiUrl}/categories`; + return this.httpClient.post(url, category, { + observe: 'response', + }); + } + + /** + * Replace an existing category with a new one. + */ + public putCategory(category: ScrumCategory): Observable> { + const url = `${environment.apiUrl}/categories/${category.id}`; + return this.httpClient.put(url, category, { observe: 'response' }); + } + + /** + * Delete a category. + */ + public deleteCategory( + category: ScrumCategory + ): Observable> { + const url = `${environment.apiUrl}/categories/${category.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Status + + /** + * Return all status. + */ + public getAllStatus(): Observable> { + const url = `${environment.apiUrl}/status`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the status with a specific id. + */ + public getStatus(id: number): Observable> { + const url = `${environment.apiUrl}/status/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new status, if successful, the newly created status will be returned. + */ + public postStatus( + status: ScrumStatus + ): Observable> { + const url = `${environment.apiUrl}/status`; + return this.httpClient.post(url, status, { + observe: 'response', + }); + } + + /** + * Replace an existing status with a new one. + */ + public putStatus(status: ScrumStatus): Observable> { + const url = `${environment.apiUrl}/status/${status.id}`; + return this.httpClient.put(url, status, { observe: 'response' }); + } + + /** + * Delete a status. + */ + public deleteStatus(status: ScrumStatus): Observable> { + const url = `${environment.apiUrl}/status/${status.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Users + + /** + * Return all users. + */ + public getUsers(): Observable> { + const url = `${environment.apiUrl}/users`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the user with a specific id. + */ + public getUser(id: number): Observable> { + const url = `${environment.apiUrl}/users/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new user, if successful, the newly created user will be returned. + */ + public postUser(user: ScrumUser): Observable> { + const url = `${environment.apiUrl}/users`; + return this.httpClient.post(url, user, { observe: 'response' }); + } + + /** + * Replace an existing user with a new one. + */ + public putUser(user: ScrumUser): Observable> { + const url = `${environment.apiUrl}/users/${user.id}`; + return this.httpClient.put(url, user, { observe: 'response' }); + } + + /** + * Delete a user. + */ + public deleteUser(user: ScrumUser): Observable> { + const url = `${environment.apiUrl}/users/${user.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } + + // Projects + + /** + * Return all projects. + */ + public getProjects(): Observable> { + const url = `${environment.apiUrl}/projects`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Return the project with a specific id. + */ + public getProject(id: number): Observable> { + const url = `${environment.apiUrl}/projects/${id}`; + return this.httpClient.get(url, { observe: 'response' }); + } + + /** + * Create a new project, if successful, the newly created project will be returned. + */ + public postProject( + project: ScrumProject + ): Observable> { + const url = `${environment.apiUrl}/projects`; + return this.httpClient.post(url, project, { + observe: 'response', + }); + } + + /** + * Replace an existing project with a new one. + */ + public putProject(project: ScrumProject): Observable> { + const url = `${environment.apiUrl}/projects/${project.id}`; + return this.httpClient.put(url, project, { observe: 'response' }); + } + + /** + * Delete a project. + */ + public deleteProject(project: ScrumProject): Observable> { + const url = `${environment.apiUrl}/projects/${project.id}`; + return this.httpClient.delete(url, { observe: 'response' }); + } +} + +/** + * @summary Represents the priority of a task or userstory. + */ +export enum Priority { + High = 'high', + Medium = 'medium', + Low = 'low', +} + +/** + * @summary Represents a task in an agile work process. + * @description A task is a small piece of work, associated with a larger userstory. + */ +export interface ScrumTask { + id?: number; + title: string; + content?: string; + statusid?: number; + categoryid?: number; + assignedtoid?: number; + sprintid?: number; + projectid?: number; + userstoryid?: number; + priority?: Priority; +} + +/** + * @summary Represents a userstory in an agile work process. + * @description A userstory is a piece of work that can be done in one sprint. + * It can be further divided into multiple tasks. + */ +export interface ScrumUserstory { + id?: number; + title: string; + content?: string; + priority?: Priority; + statusid?: number; + categoryid?: number; + sprintid?: number; + createdbyid?: number; + projectid?: number; +} + +/** + * @summary Represents an agile sprint. + * @description A sprint is typically one to four weeks long. + * Userstories are started and completed during one sprint. + * + */ +export interface ScrumSprint{ + id?: number; + title: string; + description?: string; + startDate: string; + endDate: string; + projectid?: number; +} + +/** + * @summary Represents a category of userstories. + * @description Every userstory can optionally be associated with a single category. + * This can be helpful to organize work in larger teams. + */ +export interface ScrumCategory { + id?: number; + title: string; + description?: string; + color?: string; + project?: number; +} + +/** + * @summary Represents the status of a task or userstory. + * @description Classic status are "Backlog", "In Progress" and "Done", but + * teams can create others to fit their individual workflow. + */ +export interface ScrumStatus { + id?: number; + title: string; + description: string; +} + +/** + * @summary Represents a team member that can work on userstories. + * @description This allows teams to track who is working on a userstory + * at a given time. + */ +export interface ScrumUser { + id?: number; + name: string; +} + +/** + * @summary Represents a project that the team works on. + * @description Userstories and sprints can be categorized into projects, + * to help organization for larger teams. + */ +export interface ScrumProject { + id?: number; + title: string; + isprivate: boolean; +} diff --git a/src/app/services/sorting.service.ts b/src/app/services/sorting.service.ts index 7907ad9..a3e471f 100644 --- a/src/app/services/sorting.service.ts +++ b/src/app/services/sorting.service.ts @@ -1,24 +1,45 @@ -import { Priority } from './backend.service'; - -export function sortByNumberAscending(items: T[], key: (T) => number) { - return items.sort((a, b) => key(a) - key(b)); -} - -export function sortByStringAscending(items: T[], key: (T) => string) { - return items.sort((a, b) => key(a).localeCompare(key(b))); -} - -export function sortByDateAscending(items: T[], key: (T) => Date) { - return items.sort((a, b) => (key(a) as any) - (key(b) as any)); -} - -export function getNumberForPriority(priority: Priority): number { - switch (priority) { - case Priority.High: - return 2; - case Priority.Medium: - return 1; - case Priority.Low: - return 0; - } -} +import {Priority} from './backend.service'; + +/** + * Sort an array in place by a number associated with that item. + * @param items The items to sort. + * @param key Returns the number associated with an item. + */ +export function sortByNumberAscending(items: T[], key: (T) => number) { + return items.sort((a, b) => key(a) - key(b)); +} + +/** + * Sort an array in place by a string associated with that item. + * Strings will be sorted in alphabetic order. + * @param items The items to sort. + * @param key Returns the string associated with an item. + */ +export function sortByStringAscending(items: T[], key: (T) => string) { + return items.sort((a, b) => key(a).localeCompare(key(b))); +} + +/** + * Sort an array in place by a date associated with that item. + * Dates will be sorted from old to new. + * @param items The items to sort. + * @param key Returns the date associated with an item. + */ +export function sortByDateAscending(items: T[], key: (T) => Date) { + return items.sort((a, b) => (key(b) as any) - (key(a) as any)); +} + +/** + * Converts a priority enum member to a number. + * @returns high -> 2, medium -> 1, low -> 0 + */ +export function getNumberForPriority(priority: Priority): number { + switch (priority) { + case Priority.High: + return 2; + case Priority.Medium: + return 1; + case Priority.Low: + return 0; + } +}