Users can now be added and deleted
This commit is contained in:
parent
b502f7cfe6
commit
12e60097bd
|
@ -1,232 +1,261 @@
|
|||
<!--Popup form to create and modify a task-->
|
||||
|
||||
<div class="card" style="width: 100%;">
|
||||
<div class="container">
|
||||
<div class="card-body">
|
||||
<div style="text-align: right;">
|
||||
<i class="fa fa-times fa-2x" (click)="onClose()"></i>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8" style="text-align: left;">
|
||||
<h4 *ngIf="editing" class="card-title">Task bearbeiten</h4>
|
||||
<h4 *ngIf="!editing" class="card-title">Neuen Task anlegen</h4>
|
||||
<div ngbDropdown class="dropdown card-text">
|
||||
<span
|
||||
ngbDropdownToggle
|
||||
class="dropdown"
|
||||
id="dropdownMenuUserstory"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Gehört zu Story:
|
||||
{{ getUserstoryTitleById(task.userstoryId) || "Keine" }}
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</span>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenuUserstory"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let userstory of userstories"
|
||||
(click)="task.userstoryId = userstory.id"
|
||||
>{{ userstory.title }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4"></div>
|
||||
</div>
|
||||
<form (ngSubmit)="onSubmit()">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<label for="Title">Titel</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Title"
|
||||
required
|
||||
name="title"
|
||||
[(ngModel)]="task.title"
|
||||
id="titleField"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Inhalt">What to do?</label>
|
||||
<textarea
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Story"
|
||||
required
|
||||
name="story"
|
||||
rows="5"
|
||||
[(ngModel)]="task.content"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div ngbDropdown class="dropdown">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Prio: {{ task.priority }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let p of getAllPriorities()"
|
||||
(click)="task.priority = p"
|
||||
>
|
||||
{{ p }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu3"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Status: {{ getStatusTitleById(task.statusId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Status wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let status of allStatus"
|
||||
(click)="task.statusId = status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer Status</div>
|
||||
<input
|
||||
#statusname
|
||||
type="text"
|
||||
id="statusname"
|
||||
class="dropdown-item"
|
||||
(change)="status.title = statusname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createTaskStatus(status)"
|
||||
>
|
||||
Status anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteStatus(task.statusId)"
|
||||
>
|
||||
Status löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="status"
|
||||
required
|
||||
name="status"
|
||||
[(ngModel)]="task.statusId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let status of allStatus"
|
||||
[value]="status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="true">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu4"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Bearbeiter: {{ getAuthorById(task.assignedtoId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">User wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let user of allUser"
|
||||
(click)="task.assignedtoId = user.id"
|
||||
>{{ user.name }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="assignedto"
|
||||
required
|
||||
name="assignedto"
|
||||
[(ngModel)]="task.assignedtoId"
|
||||
>
|
||||
<option *ngFor="let user of allUser" [value]="user.id">{{
|
||||
user.name
|
||||
}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button
|
||||
(click)="onClose()"
|
||||
type="dismiss"
|
||||
class="btn btn-secondary"
|
||||
data-dismiss="modal"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button *ngIf="editing" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button *ngIf="!editing" type="submit" class="btn btn-primary">Erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Popup form to create and modify a task-->
|
||||
|
||||
<div class="card" style="width: 100%;">
|
||||
<div class="container">
|
||||
<div class="card-body">
|
||||
<div style="text-align: right;">
|
||||
<i class="fa fa-times fa-2x" (click)="onClose()"></i>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8" style="text-align: left;">
|
||||
<h4 *ngIf="editing" class="card-title">Task bearbeiten</h4>
|
||||
<h4 *ngIf="!editing" class="card-title">Neuen Task anlegen</h4>
|
||||
<div ngbDropdown class="dropdown card-text">
|
||||
<span
|
||||
ngbDropdownToggle
|
||||
class="dropdown"
|
||||
id="dropdownMenuUserstory"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Gehört zu Story:
|
||||
{{ getUserstoryTitleById(task.userstoryId) || "Keine" }}
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</span>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenuUserstory"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let userstory of userstories"
|
||||
(click)="task.userstoryId = userstory.id"
|
||||
>{{ userstory.title }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4"></div>
|
||||
</div>
|
||||
<form (ngSubmit)="onSubmit()">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<label for="Title">Titel</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Title"
|
||||
required
|
||||
name="title"
|
||||
[(ngModel)]="task.title"
|
||||
id="titleField"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Inhalt">What to do?</label>
|
||||
<textarea
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Story"
|
||||
required
|
||||
name="story"
|
||||
rows="5"
|
||||
[(ngModel)]="task.content"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div ngbDropdown class="dropdown">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Prio: {{ task.priority }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let p of getAllPriorities()"
|
||||
(click)="task.priority = p"
|
||||
>
|
||||
{{ p }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu3"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Status: {{ getStatusTitleById(task.statusId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Status wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let status of allStatus"
|
||||
(click)="task.statusId = status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer Status</div>
|
||||
<input
|
||||
#statusname
|
||||
type="text"
|
||||
id="statusname"
|
||||
class="dropdown-item"
|
||||
(change)="status.title = statusname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createTaskStatus(status)"
|
||||
>
|
||||
Status anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteStatus(task.statusId)"
|
||||
>
|
||||
Status löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="status"
|
||||
required
|
||||
name="status"
|
||||
[(ngModel)]="task.statusId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let status of allStatus"
|
||||
[value]="status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu4"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Bearbeiter: {{ getAuthorById(task.assignedtoId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">User wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let user of allUser"
|
||||
(click)="task.assignedtoId = user.id"
|
||||
>{{ user.name }}</option
|
||||
>
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer User</div>
|
||||
<input
|
||||
#username
|
||||
type="text"
|
||||
id="username"
|
||||
class="dropdown-item"
|
||||
(change)="user.name = username.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUser(user)"
|
||||
>
|
||||
User anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteUser(task.assignedtoId)"
|
||||
>
|
||||
User löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="assignedto"
|
||||
required
|
||||
name="assignedto"
|
||||
[(ngModel)]="task.assignedtoId"
|
||||
>
|
||||
<option *ngFor="let user of allUser" [value]="user.id">{{
|
||||
user.name
|
||||
}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button
|
||||
(click)="onClose()"
|
||||
type="dismiss"
|
||||
class="btn btn-secondary"
|
||||
data-dismiss="modal"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button *ngIf="editing" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button *ngIf="!editing" type="submit" class="btn btn-primary">Erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,234 +1,271 @@
|
|||
// Importing necessary components and interfaces.
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import {
|
||||
BackendService,
|
||||
ScrumTask,
|
||||
Priority,
|
||||
ScrumStatus,
|
||||
ScrumCategory,
|
||||
ScrumUser,
|
||||
ScrumProject,
|
||||
ScrumUserstory
|
||||
} from '../../../services/backend.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpResponse } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
selector: 'app-task-form',
|
||||
templateUrl: './task-form.component.html',
|
||||
styleUrls: [ './task-form.component.css' ]
|
||||
})
|
||||
export // Class implements the logic for a popup window form to create and modify tasks.
|
||||
class TaskFormComponent implements OnInit {
|
||||
@Input() public task: ScrumTask;
|
||||
public editing: boolean;
|
||||
public creating: boolean;
|
||||
public userstoryId: string;
|
||||
public userstories: any[] = [];
|
||||
public allStatus: any[] = [];
|
||||
public status: ScrumStatus = { title: '', description: '' };
|
||||
public allUser: any[] = [];
|
||||
public user: ScrumUser = { name: '' };
|
||||
|
||||
constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) {
|
||||
this.getUserStories();
|
||||
this.getTaskStatus();
|
||||
this.getAllUsers();
|
||||
}
|
||||
|
||||
/**
|
||||
* If no task exists a new on will be created.
|
||||
* In other cases the task exists and gets modifiable.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.task === null || this.task === undefined) {
|
||||
this.task = { title: '' };
|
||||
this.editing = false;
|
||||
this.creating = false;
|
||||
} else if (this.task.userstoryId) {
|
||||
this.editing = true;
|
||||
} else {
|
||||
this.creating = true;
|
||||
}
|
||||
document.getElementById('titleField').focus();
|
||||
this.getRelatedStory();
|
||||
}
|
||||
|
||||
/**
|
||||
* A new created task will be saved in the backend (POST).
|
||||
* If a task already exists, modifying results an update (PUT) to the backend.
|
||||
*/
|
||||
onSubmit() {
|
||||
if (this.editing) {
|
||||
this.backendService.putTask(this.task).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.backendService.postTask(this.task).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
// Copy properties returned by the API
|
||||
Object.assign(this.task, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Closes the popup window after submitting/canceling.
|
||||
this.activeModalService.close(this.task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup form window (by clicking "close button").
|
||||
*/
|
||||
onClose() {
|
||||
this.activeModalService.dismiss(this.task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the userstory which is related to a task.
|
||||
* The related story will be shown in popup window of a task.
|
||||
*/
|
||||
getRelatedStory() {
|
||||
if (!this.task.userstoryId) {
|
||||
return null;
|
||||
}
|
||||
this.backendService.getUserstory(this.task.userstoryId).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.userstoryId = response.body.title;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all userstories from backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getUserStories() {
|
||||
this.backendService.getUserstories().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.userstories.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available status from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getTaskStatus() {
|
||||
this.backendService.getAllStatus().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary status (such as "Waiting") can be created, which will be stored in an array.
|
||||
* The new status is available to all tasks.
|
||||
* @param status Scrumstatus to store in the database
|
||||
*/
|
||||
createTaskStatus(status: ScrumStatus) {
|
||||
this.backendService.postStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// A custom status can even be deleted if not used anymore.
|
||||
// This will remove the status from status-array.
|
||||
/**
|
||||
* A custom status can even be deleted if not used anymore.
|
||||
* This will remove the status from status-array
|
||||
* @param id the id of the chosen status
|
||||
*/
|
||||
deleteStatus(id: number) {
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
this.backendService.deleteStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allStatus.indexOf(status);
|
||||
if (index !== -1) {
|
||||
this.allStatus.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.task.statusId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the value of the priority enum to be shown in a dropdown in popup window.
|
||||
*/
|
||||
getAllPriorities(): Priority[] {
|
||||
return Object.values(Priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen userstory in the userstory-field in the popup window
|
||||
* @param id reference to the userstory object
|
||||
*/
|
||||
getUserstoryTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var story = this.userstories.find((x) => x.id === id);
|
||||
if (!story) {
|
||||
return null;
|
||||
}
|
||||
return story.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen status in the status-field in the popup window.
|
||||
* @param id reference to the status object
|
||||
*/
|
||||
getStatusTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
return status.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all taskboard users from the backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getAllUsers() {
|
||||
this.backendService.getUsers().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before assigned user in the author-field in the popup window.
|
||||
* @param id reference to the author object
|
||||
*/
|
||||
getAuthorById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
return user.name;
|
||||
}
|
||||
}
|
||||
// Importing necessary components and interfaces.
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import {
|
||||
BackendService,
|
||||
ScrumTask,
|
||||
Priority,
|
||||
ScrumStatus,
|
||||
ScrumCategory,
|
||||
ScrumUser,
|
||||
ScrumProject,
|
||||
ScrumUserstory
|
||||
} from '../../../services/backend.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpResponse } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
selector: 'app-task-form',
|
||||
templateUrl: './task-form.component.html',
|
||||
styleUrls: [ './task-form.component.css' ]
|
||||
})
|
||||
export // Class implements the logic for a popup window form to create and modify tasks.
|
||||
class TaskFormComponent implements OnInit {
|
||||
@Input() public task: ScrumTask;
|
||||
public editing: boolean;
|
||||
public creating: boolean;
|
||||
public userstoryId: string;
|
||||
public userstories: any[] = [];
|
||||
public allStatus: any[] = [];
|
||||
public status: ScrumStatus = { title: '', description: '' };
|
||||
public allUser: any[] = [];
|
||||
public user: ScrumUser = { name: '' };
|
||||
|
||||
constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) {
|
||||
this.getUserStories();
|
||||
this.getTaskStatus();
|
||||
this.getAllUsers();
|
||||
}
|
||||
|
||||
/**
|
||||
* If no task exists a new on will be created.
|
||||
* In other cases the task exists and gets modifiable.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.task === null || this.task === undefined) {
|
||||
this.task = { title: '' };
|
||||
this.editing = false;
|
||||
this.creating = false;
|
||||
} else if (this.task.userstoryId) {
|
||||
this.editing = true;
|
||||
} else {
|
||||
this.creating = true;
|
||||
}
|
||||
document.getElementById('titleField').focus();
|
||||
this.getRelatedStory();
|
||||
}
|
||||
|
||||
/**
|
||||
* A new created task will be saved in the backend (POST).
|
||||
* If a task already exists, modifying results an update (PUT) to the backend.
|
||||
*/
|
||||
onSubmit() {
|
||||
if (this.editing) {
|
||||
this.backendService.putTask(this.task).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.backendService.postTask(this.task).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
// Copy properties returned by the API
|
||||
Object.assign(this.task, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Closes the popup window after submitting/canceling.
|
||||
this.activeModalService.close(this.task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup form window (by clicking "close button").
|
||||
*/
|
||||
onClose() {
|
||||
this.activeModalService.dismiss(this.task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the userstory which is related to a task.
|
||||
* The related story will be shown in popup window of a task.
|
||||
*/
|
||||
getRelatedStory() {
|
||||
if (!this.task.userstoryId) {
|
||||
return null;
|
||||
}
|
||||
this.backendService.getUserstory(this.task.userstoryId).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.userstoryId = response.body.title;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all userstories from backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getUserStories() {
|
||||
this.backendService.getUserstories().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.userstories.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available status from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getTaskStatus() {
|
||||
this.backendService.getAllStatus().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary status (such as "Waiting") can be created, which will be stored in an array.
|
||||
* The new status is available to all tasks.
|
||||
* @param status Scrumstatus to store in the database
|
||||
*/
|
||||
createTaskStatus(status: ScrumStatus) {
|
||||
this.backendService.postStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary user (such as "Testuser") can be created, which will be stored in an array.
|
||||
* The new user is available to all tasks.
|
||||
* @param user ScrumUser to store in the database
|
||||
*/
|
||||
createUser(user: ScrumUser) {
|
||||
this.backendService.postUser(user).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// A custom status can even be deleted if not used anymore.
|
||||
// This will remove the status from status-array.
|
||||
/**
|
||||
* A custom status can even be deleted if not used anymore.
|
||||
* This will remove the status from status-array
|
||||
* @param id the id of the chosen status
|
||||
*/
|
||||
deleteStatus(id: number) {
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
this.backendService.deleteStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allStatus.indexOf(status);
|
||||
if (index !== -1) {
|
||||
this.allStatus.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.task.statusId = null;
|
||||
});
|
||||
}
|
||||
|
||||
// A custom user can even be deleted if not used anymore.
|
||||
// This will remove the user from user-array.
|
||||
/**
|
||||
* A custom user can even be deleted if not used anymore.
|
||||
* This will remove the user from user-array
|
||||
* @param id the id of the chosen user
|
||||
*/
|
||||
deleteUser(id: number) {
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
this.backendService.deleteUser(user).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allUser.indexOf(user);
|
||||
if (index !== -1) {
|
||||
this.allUser.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.task.assignedtoId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the value of the priority enum to be shown in a dropdown in popup window.
|
||||
*/
|
||||
getAllPriorities(): Priority[] {
|
||||
return Object.values(Priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen userstory in the userstory-field in the popup window
|
||||
* @param id reference to the userstory object
|
||||
*/
|
||||
getUserstoryTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var story = this.userstories.find((x) => x.id === id);
|
||||
if (!story) {
|
||||
return null;
|
||||
}
|
||||
return story.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen status in the status-field in the popup window.
|
||||
* @param id reference to the status object
|
||||
*/
|
||||
getStatusTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
return status.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all taskboard users from the backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getAllUsers() {
|
||||
this.backendService.getUsers().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before assigned user in the author-field in the popup window.
|
||||
* @param id reference to the author object
|
||||
*/
|
||||
getAuthorById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
return user.name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,280 +1,309 @@
|
|||
<!--Popup form to create and modify a task-->
|
||||
|
||||
<div class="card" style="width: 100%;">
|
||||
<div class="container">
|
||||
<div class="card-body">
|
||||
<div style="text-align: right;">
|
||||
<i class="fa fa-times fa-2x" (click)="onClose()"></i>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8" style="text-align: left;">
|
||||
<h4 *ngIf="editing" class="card-title">Userstory #{{ userstory.id }} bearbeiten</h4>
|
||||
<h4 *ngIf="!editing" class="card-title">Neue Userstory anlegen</h4>
|
||||
</div>
|
||||
<div class="col-4"></div>
|
||||
</div>
|
||||
<form (ngSubmit)="onSubmit()">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<label for="Title">Titel</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Title"
|
||||
required
|
||||
name="title"
|
||||
[(ngModel)]="userstory.title"
|
||||
id="titleField"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Inhalt">Story</label>
|
||||
<textarea
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Story"
|
||||
required
|
||||
name="story"
|
||||
rows="5"
|
||||
[(ngModel)]="userstory.content"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div ngbDropdown class="dropdown">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Prio: {{ userstory.priority }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let p of getAllPriorities()"
|
||||
(click)="userstory.priority = p"
|
||||
>
|
||||
{{ p }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Status: {{ getStatusTitleById(userstory.statusId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Status wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let status of allStatus"
|
||||
(click)="userstory.statusId = status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer Status</div>
|
||||
<input
|
||||
#statusname
|
||||
type="text"
|
||||
id="statusname"
|
||||
class="dropdown-item"
|
||||
(change)="status.title = statusname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUserstoryStatus(status)"
|
||||
>
|
||||
Status anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteStatus(userstory.statusId)"
|
||||
>
|
||||
Status löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.statusId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let status of allStatus"
|
||||
[value]="status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Kategorie: {{ getCategoryById(userstory.categoryId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Kategorie wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let category of allCategories"
|
||||
(click)="userstory.categoryId = category.id"
|
||||
>{{ category.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neue Kategorie</div>
|
||||
<input
|
||||
#categoryname
|
||||
type="text"
|
||||
id="categoryname"
|
||||
class="dropdown-item"
|
||||
(change)="category.title = categoryname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUserstoryCategory(category)"
|
||||
>
|
||||
Kategorie anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteCategory(userstory.categoryId)"
|
||||
>
|
||||
Kategorie löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.categoryId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let category of allCategories"
|
||||
[value]="category.id"
|
||||
>{{ category.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="true">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Autor: {{ getAuthorById(userstory.createdbyId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">User wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let user of allUser"
|
||||
(click)="userstory.createdbyId = user.id"
|
||||
>{{ user.name }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.createdbyId"
|
||||
>
|
||||
<option *ngFor="let user of allUser" [value]="user.id">{{
|
||||
user.name
|
||||
}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button
|
||||
(click)="onClose()"
|
||||
type="dismiss"
|
||||
class="btn btn-secondary"
|
||||
data-dismiss="modal"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button *ngIf="editing" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button *ngIf="!editing" type="submit" class="btn btn-primary">Erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Popup form to create and modify a task-->
|
||||
|
||||
<div class="card" style="width: 100%;">
|
||||
<div class="container">
|
||||
<div class="card-body">
|
||||
<div style="text-align: right;">
|
||||
<i class="fa fa-times fa-2x" (click)="onClose()"></i>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8" style="text-align: left;">
|
||||
<h4 *ngIf="editing" class="card-title">Userstory #{{ userstory.id }} bearbeiten</h4>
|
||||
<h4 *ngIf="!editing" class="card-title">Neue Userstory anlegen</h4>
|
||||
</div>
|
||||
<div class="col-4"></div>
|
||||
</div>
|
||||
<form (ngSubmit)="onSubmit()">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<label for="Title">Titel</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Title"
|
||||
required
|
||||
name="title"
|
||||
[(ngModel)]="userstory.title"
|
||||
id="titleField"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Inhalt">Story</label>
|
||||
<textarea
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="Story"
|
||||
required
|
||||
name="story"
|
||||
rows="5"
|
||||
[(ngModel)]="userstory.content"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div ngbDropdown class="dropdown">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Prio: {{ userstory.priority }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<option
|
||||
ngbDropdownItem
|
||||
*ngFor="let p of getAllPriorities()"
|
||||
(click)="userstory.priority = p"
|
||||
>
|
||||
{{ p }}</option
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Status: {{ getStatusTitleById(userstory.statusId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Status wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let status of allStatus"
|
||||
(click)="userstory.statusId = status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer Status</div>
|
||||
<input
|
||||
#statusname
|
||||
type="text"
|
||||
id="statusname"
|
||||
class="dropdown-item"
|
||||
(change)="status.title = statusname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUserstoryStatus(status)"
|
||||
>
|
||||
Status anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteStatus(userstory.statusId)"
|
||||
>
|
||||
Status löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.statusId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let status of allStatus"
|
||||
[value]="status.id"
|
||||
>{{ status.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu2"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Kategorie: {{ getCategoryById(userstory.categoryId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">Kategorie wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let category of allCategories"
|
||||
(click)="userstory.categoryId = category.id"
|
||||
>{{ category.title }}</option
|
||||
>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neue Kategorie</div>
|
||||
<input
|
||||
#categoryname
|
||||
type="text"
|
||||
id="categoryname"
|
||||
class="dropdown-item"
|
||||
(change)="category.title = categoryname.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUserstoryCategory(category)"
|
||||
>
|
||||
Kategorie anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteCategory(userstory.categoryId)"
|
||||
>
|
||||
Kategorie löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.categoryId"
|
||||
>
|
||||
<option
|
||||
*ngFor="let category of allCategories"
|
||||
[value]="category.id"
|
||||
>{{ category.title }}</option
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div ngbDropdown class="dropdown" [autoClose]="false">
|
||||
<button
|
||||
ngbDropdownToggle
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
id="dropdownMenu4"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Bearbeiter: {{ getAuthorById(userstory.createdbyId) }}
|
||||
</button>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="dropdownMenu2"
|
||||
>
|
||||
<div class="card-text" for="Inhalt">User wählen</div>
|
||||
<option
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
*ngFor="let user of allUser"
|
||||
(click)="userstory.createdbyId = user.id"
|
||||
>{{ user.name }}</option
|
||||
>
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="card-text" for="Inhalt">Neuer User</div>
|
||||
<input
|
||||
#username
|
||||
type="text"
|
||||
id="username"
|
||||
class="dropdown-item"
|
||||
(change)="user.name = username.value"
|
||||
placeholder="New Title..."
|
||||
style="background-color: rgba(211, 211, 211, 0.342);"
|
||||
/>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="createUser(user)"
|
||||
>
|
||||
User anlegen
|
||||
</button>
|
||||
<button
|
||||
disable-auto-close
|
||||
ngbDropdownItem
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
(click)="deleteUser(task.assignedtoId)"
|
||||
>
|
||||
User löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<select
|
||||
class="form-control custom-select mr-sm-2"
|
||||
id="prio"
|
||||
required
|
||||
name="prio"
|
||||
[(ngModel)]="userstory.createdbyId"
|
||||
>
|
||||
<option *ngFor="let user of allUser" [value]="user.id">{{
|
||||
user.name
|
||||
}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button
|
||||
(click)="onClose()"
|
||||
type="dismiss"
|
||||
class="btn btn-secondary"
|
||||
data-dismiss="modal"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button *ngIf="editing" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button *ngIf="!editing" type="submit" class="btn btn-primary">Erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,238 +1,275 @@
|
|||
// Importing necessary components and interfaces.
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BackendService, ScrumUserstory, Priority, ScrumStatus, ScrumCategory, ScrumUser } from '../../../services/backend.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-userstory-form',
|
||||
templateUrl: './userstory-form.component.html',
|
||||
styleUrls: [ './userstory-form.component.css' ]
|
||||
})
|
||||
export // Class implements the logic for a popup window form to create and modify userstories.
|
||||
class UserstoryFormComponent implements OnInit {
|
||||
@Input() public userstory: ScrumUserstory;
|
||||
public allStatus: any[] = [];
|
||||
public status: ScrumStatus = { title: '', description: '' };
|
||||
public allUser: any[] = [];
|
||||
public user: ScrumUser = { name: '' };
|
||||
public allCategories: any[] = [];
|
||||
public category: ScrumCategory = { title: '' };
|
||||
public editing: boolean;
|
||||
|
||||
constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) {
|
||||
this.getUserstoryStatus();
|
||||
this.getAllUsers();
|
||||
this.getUserstoryCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* If no userstory exists a new one will be created.
|
||||
* In other cases the userstory exists and gets modifiable.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.userstory === null || this.userstory === undefined) {
|
||||
this.userstory = { title: '' };
|
||||
this.editing = false;
|
||||
} else {
|
||||
this.editing = true;
|
||||
}
|
||||
document.getElementById('titleField').focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* A new created userstory will be saved in the backend (POST).
|
||||
* If a userstory already exists, modifying results an update (PUT) to the backend.
|
||||
*/
|
||||
onSubmit() {
|
||||
if (this.editing) {
|
||||
this.backendService.putUserstory(this.userstory).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.backendService.postUserstory(this.userstory).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
// Copy properties returned by the API
|
||||
Object.assign(this.userstory, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Closes the popup window after submitting/canceling.
|
||||
this.activeModalService.close(this.userstory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup form window (by clicking "close button").
|
||||
*/
|
||||
onClose() {
|
||||
this.activeModalService.dismiss(this.userstory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available status from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getUserstoryStatus() {
|
||||
this.backendService.getAllStatus().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary status (such as "Waiting") can be created, which will be stored in an array.
|
||||
* The new status is available to all userstories.
|
||||
* @param status the status object which will be created
|
||||
*/
|
||||
createUserstoryStatus(status: ScrumStatus) {
|
||||
this.backendService.postStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom status can even be deleted if not used anymore.
|
||||
* This will remove the status from status-array
|
||||
* @param id reference to the deletable status object
|
||||
*/
|
||||
deleteStatus(id: number) {
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
this.backendService.deleteStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allStatus.indexOf(status);
|
||||
if (index !== -1) {
|
||||
this.allStatus.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.userstory.statusId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the values of the Priority enum to be shown in a dropdown in popup window.
|
||||
*/
|
||||
getAllPriorities(): Priority[] {
|
||||
return Object.values(Priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen status in the status-field in the popup window.
|
||||
* @param id reference to the status object
|
||||
*/
|
||||
getStatusTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
return status.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all taskboard users from backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getAllUsers() {
|
||||
this.backendService.getUsers().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before assigned user in the author-field in the popup window.
|
||||
* @param id reference to the author object
|
||||
*/
|
||||
getAuthorById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
return user.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available categories from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getUserstoryCategory() {
|
||||
this.backendService.getCategories().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allCategories.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If desired a new arbitrary category can be created, which will be stored in an array.
|
||||
// The new category is available to all userstories.
|
||||
/**
|
||||
* If desired a new arbitrary category can be created, which will be stored in an array.
|
||||
* The new category is available to all userstories.
|
||||
* @param category the category object which will be created
|
||||
*/
|
||||
createUserstoryCategory(category: ScrumCategory) {
|
||||
this.backendService.postCategory(category).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allCategories.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// A custom category can even be deleted if not used anymore.
|
||||
// This will remove the category from category-array.
|
||||
/**
|
||||
* A custom category can even be deleted if not used anymore.
|
||||
* This will remove the category from category-array.
|
||||
* @param id reference to the deletable category
|
||||
*/
|
||||
deleteCategory(id: number) {
|
||||
var category = this.allCategories.find((x) => x.id === id);
|
||||
this.backendService.deleteCategory(category).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allCategories.indexOf(category);
|
||||
if (index !== -1) {
|
||||
this.allCategories.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.userstory.categoryId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen category in the category-field in the popup window.
|
||||
* @param id reference to the category
|
||||
*/
|
||||
getCategoryById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var category = this.allCategories.find((x) => x.id === id);
|
||||
if (!category) {
|
||||
return null;
|
||||
}
|
||||
return category.title;
|
||||
}
|
||||
}
|
||||
// Importing necessary components and interfaces.
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BackendService, ScrumUserstory, Priority, ScrumStatus, ScrumCategory, ScrumUser } from '../../../services/backend.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-userstory-form',
|
||||
templateUrl: './userstory-form.component.html',
|
||||
styleUrls: [ './userstory-form.component.css' ]
|
||||
})
|
||||
export // Class implements the logic for a popup window form to create and modify userstories.
|
||||
class UserstoryFormComponent implements OnInit {
|
||||
@Input() public userstory: ScrumUserstory;
|
||||
public allStatus: any[] = [];
|
||||
public status: ScrumStatus = { title: '', description: '' };
|
||||
public allUser: any[] = [];
|
||||
public user: ScrumUser = { name: '' };
|
||||
public allCategories: any[] = [];
|
||||
public category: ScrumCategory = { title: '' };
|
||||
public editing: boolean;
|
||||
|
||||
constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) {
|
||||
this.getUserstoryStatus();
|
||||
this.getAllUsers();
|
||||
this.getUserstoryCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* If no userstory exists a new one will be created.
|
||||
* In other cases the userstory exists and gets modifiable.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.userstory === null || this.userstory === undefined) {
|
||||
this.userstory = { title: '' };
|
||||
this.editing = false;
|
||||
} else {
|
||||
this.editing = true;
|
||||
}
|
||||
document.getElementById('titleField').focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* A new created userstory will be saved in the backend (POST).
|
||||
* If a userstory already exists, modifying results an update (PUT) to the backend.
|
||||
*/
|
||||
onSubmit() {
|
||||
if (this.editing) {
|
||||
this.backendService.putUserstory(this.userstory).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.backendService.postUserstory(this.userstory).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
// Copy properties returned by the API
|
||||
Object.assign(this.userstory, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Closes the popup window after submitting/canceling.
|
||||
this.activeModalService.close(this.userstory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup form window (by clicking "close button").
|
||||
*/
|
||||
onClose() {
|
||||
this.activeModalService.dismiss(this.userstory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available status from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getUserstoryStatus() {
|
||||
this.backendService.getAllStatus().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary status (such as "Waiting") can be created, which will be stored in an array.
|
||||
* The new status is available to all userstories.
|
||||
* @param status the status object which will be created
|
||||
*/
|
||||
createUserstoryStatus(status: ScrumStatus) {
|
||||
this.backendService.postStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allStatus.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom status can even be deleted if not used anymore.
|
||||
* This will remove the status from status-array
|
||||
* @param id reference to the deletable status object
|
||||
*/
|
||||
deleteStatus(id: number) {
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
this.backendService.deleteStatus(status).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allStatus.indexOf(status);
|
||||
if (index !== -1) {
|
||||
this.allStatus.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.userstory.statusId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the values of the Priority enum to be shown in a dropdown in popup window.
|
||||
*/
|
||||
getAllPriorities(): Priority[] {
|
||||
return Object.values(Priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen status in the status-field in the popup window.
|
||||
* @param id reference to the status object
|
||||
*/
|
||||
getStatusTitleById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var status = this.allStatus.find((x) => x.id === id);
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
return status.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all taskboard users from backend to show in a dropdown in popup window.
|
||||
*/
|
||||
getAllUsers() {
|
||||
this.backendService.getUsers().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before assigned user in the author-field in the popup window.
|
||||
* @param id reference to the author object
|
||||
*/
|
||||
getAuthorById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
return user.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all available categories from backend to list it in status-dropdown in popup window.
|
||||
*/
|
||||
getUserstoryCategory() {
|
||||
this.backendService.getCategories().subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allCategories.push(...response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If desired a new arbitrary category can be created, which will be stored in an array.
|
||||
// The new category is available to all userstories.
|
||||
/**
|
||||
* If desired a new arbitrary category can be created, which will be stored in an array.
|
||||
* The new category is available to all userstories.
|
||||
* @param category the category object which will be created
|
||||
*/
|
||||
createUserstoryCategory(category: ScrumCategory) {
|
||||
this.backendService.postCategory(category).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allCategories.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If desired a new arbitrary user (such as "Testuser") can be created, which will be stored in an array.
|
||||
* The new user is available to all userstories.
|
||||
* @param user ScrumUser to store in the database
|
||||
*/
|
||||
createUser(user: ScrumUser) {
|
||||
this.backendService.postUser(user).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
this.allUser.push(response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// A custom category can even be deleted if not used anymore.
|
||||
// This will remove the category from category-array.
|
||||
/**
|
||||
* A custom category can even be deleted if not used anymore.
|
||||
* This will remove the category from category-array.
|
||||
* @param id reference to the deletable category
|
||||
*/
|
||||
deleteCategory(id: number) {
|
||||
var category = this.allCategories.find((x) => x.id === id);
|
||||
this.backendService.deleteCategory(category).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allCategories.indexOf(category);
|
||||
if (index !== -1) {
|
||||
this.allCategories.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.userstory.categoryId = null;
|
||||
});
|
||||
}
|
||||
|
||||
// A custom user can even be deleted if not used anymore.
|
||||
// This will remove the user from user-array.
|
||||
/**
|
||||
* A custom user can even be deleted if not used anymore.
|
||||
* This will remove the user from user-array
|
||||
* @param id the id of the chosen user
|
||||
*/
|
||||
deleteUser(id: number) {
|
||||
var user = this.allUser.find((x) => x.id === id);
|
||||
this.backendService.deleteUser(user).subscribe((response) => {
|
||||
if (response.status > 399) {
|
||||
alert('Fehler');
|
||||
} else {
|
||||
const index = this.allUser.indexOf(user);
|
||||
if (index !== -1) {
|
||||
this.allUser.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.userstory.createdbyId = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the before choosen category in the category-field in the popup window.
|
||||
* @param id reference to the category
|
||||
*/
|
||||
getCategoryById(id: number): string {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
var category = this.allCategories.find((x) => x.id === id);
|
||||
if (!category) {
|
||||
return null;
|
||||
}
|
||||
return category.title;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue