diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..344914d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,49 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +dist +tmp +out-tsc +assets +src\assets +# Only exists if Bazel was run +bazel-out + +# dependencies +node_modules + +# profiling files +chrome-profiler-events*.json +speed-measure-plugin*.json + +# IDEs and editors +.idea +.project +.classpath +.c9 +*.launch +.settings/ +*.sublime-workspace +package-lock.json + +# IDE - VSCode +.vscode + +# misc +.sass-cache +connect.lock +coverage +libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +# Other ignore files +.gitignore +.dockerignore +.gitlab-ci.yml \ No newline at end of file diff --git a/README.md b/README.md index cf08cb1..c5c975b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.7. ## Angular CLI + ### Development server Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. @@ -28,27 +29,32 @@ Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protrac To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). ## Deploy with Docker + > Prerequisite: Docker and/or Docker Compose have to be installed on your system
> The Docker installation instructions for most operation systems can be found here: [https://docs.docker.com/get-docker/](https://docs.docker.com/get-docker/)
> The Docker Compose installation instructions for most operation systems can be found here: [https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/) > To use the prebuild images log into the private registry: docker login -u testuser -p LpH2v1mShPpC8Xeimkd2AISA03zaC+vq scrumdev.azurecr.io ### Quick Deployment with Docker Compose + 1. Clone the git repo 2. Open the cloned repo's folder in a shell of your choice (as long as it supports Docker) 3. Tell Docker Compose to run the app alongside a database with `docker-compose up` Other useful commands: -* Run attached (in the background): `docker-compose up -d` -* Stop: `docker-compose down` -* Restart: `docker-compose restart` + +- Run attached (in the background): `docker-compose up -d` +- Stop: `docker-compose down` +- Restart: `docker-compose restart` ### Build the Container yourself (and run it) + 1. Clone the git repo 2. Open the cloned repo's folder in a shell of your choice (as long as it supports Docker) 3. Tell Docker to build the app under the name "taskboard/frontend" with `docker build -t taskboard/frontend .` 4. Tell Docker to run the app on port 8080 with `docker run -p 8080:80 taskboard/frontend` Other useful commands: -* Run detached: `docker run -d -p 8080:80 taskboard/frontend` -* Run under specified name: `docker run -p 8080:80 --name frontend taskboard/frontend` \ No newline at end of file + +- Run detached: `docker run -d -p 8080:80 taskboard/frontend` +- Run under specified name: `docker run -p 8080:80 --name frontend taskboard/frontend` diff --git a/angular.json b/angular.json index 76ef1da..221d436 100644 --- a/angular.json +++ b/angular.json @@ -20,17 +20,13 @@ "tsConfig": "tsconfig.app.json", "preserveSymlinks": true, "aot": true, - "assets": [ - "src/favicon.ico", - "src/assets" - ], + "assets": ["src/favicon.ico", "src/assets"], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.scss", "src/assets/scss/black-dashboard.scss" ], - "scripts": [ - ] + "scripts": [] }, "configurations": { "production": { @@ -87,13 +83,8 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], "scripts": [] } }, @@ -105,9 +96,7 @@ "tsconfig.spec.json", "e2e/tsconfig.json" ], - "exclude": [ - "**/node_modules/**" - ] + "exclude": ["**/node_modules/**"] } }, "e2e": { @@ -126,4 +115,4 @@ } }, "defaultProject": "frontend" -} \ No newline at end of file +} diff --git a/docker-compose.yml b/docker-compose.yml index 5ea3353..a0883cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ -version: "3" - -services: - app: - image: scrumdev.azurecr.io/taskboard/frontend:latest - restart: unless-stopped - networks: - - default - ports: - - "8080:80" - environment: - API_URL: http://localhost:5001 \ No newline at end of file +version: "3" + +services: + app: + image: scrumdev.azurecr.io/taskboard/frontend:latest + restart: unless-stopped + networks: + - default + ports: + - "8080:80" + environment: + API_URL: http://localhost:5001 diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js index 7c798cf..fab6296 100644 --- a/e2e/protractor.conf.js +++ b/e2e/protractor.conf.js @@ -2,31 +2,31 @@ // Protractor configuration file, see link for more information // https://github.com/angular/protractor/blob/master/lib/config.ts -const { SpecReporter } = require('jasmine-spec-reporter'); +const { SpecReporter } = require("jasmine-spec-reporter"); /** * @type { import("protractor").Config } */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ["./src/**/*.e2e-spec.ts"], capabilities: { - browserName: 'chrome' + browserName: "chrome", }, directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', + baseUrl: "http://localhost:4200/", + framework: "jasmine", jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + require("ts-node").register({ + project: require("path").join(__dirname, "./tsconfig.json"), }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } -}; \ No newline at end of file + jasmine + .getEnv() + .addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + }, +}; diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts index f8b8268..30e1433 100644 --- a/e2e/src/app.e2e-spec.ts +++ b/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts index b68475e..91f5087 100644 --- a/e2e/src/app.po.ts +++ b/e2e/src/app.po.ts @@ -6,6 +6,8 @@ export class AppPage { } getTitleText(): Promise { - return element(by.css('app-root .content span')).getText() as Promise; + return element(by.css('app-root .content span')).getText() as Promise< + string + >; } } diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 39b800f..677f30f 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -4,10 +4,6 @@ "outDir": "../out-tsc/e2e", "module": "commonjs", "target": "es5", - "types": [ - "jasmine", - "jasminewd2", - "node" - ] + "types": ["jasmine", "jasminewd2", "node"] } } diff --git a/karma.conf.js b/karma.conf.js index d26663c..9f54a8f 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -3,30 +3,30 @@ module.exports = function (config) { config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], + basePath: "", + frameworks: ["jasmine", "@angular-devkit/build-angular"], plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma') + require("karma-jasmine"), + require("karma-chrome-launcher"), + require("karma-jasmine-html-reporter"), + require("karma-coverage-istanbul-reporter"), + require("@angular-devkit/build-angular/plugins/karma"), ], client: { - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, coverageIstanbulReporter: { - dir: require('path').join(__dirname, './coverage/frontend'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true + dir: require("path").join(__dirname, "./coverage/frontend"), + reports: ["html", "lcovonly", "text-summary"], + fixWebpackSourcePaths: true, }, - reporters: ['progress', 'kjhtml'], + reporters: ["progress", "kjhtml"], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['Chrome'], + browsers: ["Chrome"], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 0bd7cc2..741dc79 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -4,7 +4,7 @@ import { DashboardComponent } from './components/dashboard/dashboard.component'; import { UserstoryTableComponent } from './components/tabels/userstory/userstory-table.component'; import { TaskTableComponent } from './components/tabels/task/task-table.component'; import { SprintTableComponent } from './components/tabels/sprint/sprint-table.component'; -import {BacklogComponent} from './components/backlog/backlog.component'; +import { BacklogComponent } from './components/backlog/backlog.component'; const routes: Routes = [ { path: 'tasks', component: TaskTableComponent }, diff --git a/src/app/app.component.css b/src/app/app.component.css index 6812812..c80c558 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -8,15 +8,15 @@ } .nav a { - font-size: 1em; + font-size: 1em; } .nav a:hover:not(.active) { - font-size: 1.15em; - } + font-size: 1.15em; +} .content { - position: relative; - float: right; - margin-top: 10px; + position: relative; + float: right; + margin-top: 10px; } diff --git a/src/app/app.component.html b/src/app/app.component.html index 4345092..69c0324 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,80 +1,87 @@ -
- - - - - -
-
-
- - - -
    - -
  • - LIGHT MODE - - - DARK MODE -
  • -
-
-
-
-
+
+ + + + +
+
+
+ + + +
    + +
  • + LIGHT MODE + + + + + DARK MODE +
  • +
+
+
+
+
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 340d7f2..c1b0427 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -5,12 +5,8 @@ import { AppComponent } from './app.component'; describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], + imports: [RouterTestingModule], + declarations: [AppComponent], }).compileComponents(); })); @@ -30,6 +26,8 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain('frontend app is running!'); + expect(compiled.querySelector('.content span').textContent).toContain( + 'frontend app is running!' + ); }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 6efd665..c8c148d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.css'], }) export class AppComponent { /* @@ -21,12 +21,11 @@ export class AppComponent { } } */ - changeDashboardColor(color){ + changeDashboardColor(color) { var body = document.getElementsByTagName('body')[0]; if (body && color === 'white-content') { - body.classList.add(color); - } - else if(body.classList.contains('white-content')) { + body.classList.add(color); + } else if (body.classList.contains('white-content')) { body.classList.remove('white-content'); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 294e574..5273c2d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,45 +1,45 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { HttpClientModule } from '@angular/common/http'; - -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; - -import { BackendService } from './services/backend.service'; -import { TaskFormComponent } from './components/task-form/task-form.component'; -import { UserstoryFormComponent } from './components/userstory-form/userstory-form.component'; -import { SprintFormComponent } from './components/sprint-form/sprint-form.component'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { UserstoryTableComponent } from './components/tabels/userstory/userstory-table.component'; -import { TaskTableComponent } from './components/tabels/task/task-table.component'; -import { SprintTableComponent } from './components/tabels/sprint/sprint-table.component'; -import { DashboardComponent } from './components/dashboard/dashboard.component'; -import { UserstoryInnerTableComponent } from './components/tabels/userstory-inner-table/userstory-inner-table.component'; -import { BacklogComponent } from './components/backlog/backlog.component'; - -@NgModule({ - declarations: [ - AppComponent, - TaskTableComponent, - TaskFormComponent, - UserstoryTableComponent, - UserstoryFormComponent, - UserstoryTableComponent, - SprintFormComponent, - SprintTableComponent, - DashboardComponent, - UserstoryInnerTableComponent, - BacklogComponent - ], - imports: [ - BrowserModule, - AppRoutingModule, - HttpClientModule, - FormsModule, - NgbModule, - ], - providers: [BackendService], - bootstrap: [AppComponent], -}) -export class AppModule {} +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; + +import { BackendService } from './services/backend.service'; +import { TaskFormComponent } from './components/task-form/task-form.component'; +import { UserstoryFormComponent } from './components/userstory-form/userstory-form.component'; +import { SprintFormComponent } from './components/sprint-form/sprint-form.component'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { UserstoryTableComponent } from './components/tabels/userstory/userstory-table.component'; +import { TaskTableComponent } from './components/tabels/task/task-table.component'; +import { SprintTableComponent } from './components/tabels/sprint/sprint-table.component'; +import { DashboardComponent } from './components/dashboard/dashboard.component'; +import { UserstoryInnerTableComponent } from './components/tabels/userstory-inner-table/userstory-inner-table.component'; +import { BacklogComponent } from './components/backlog/backlog.component'; + +@NgModule({ + declarations: [ + AppComponent, + TaskTableComponent, + TaskFormComponent, + UserstoryTableComponent, + UserstoryFormComponent, + UserstoryTableComponent, + SprintFormComponent, + SprintTableComponent, + DashboardComponent, + UserstoryInnerTableComponent, + BacklogComponent, + ], + imports: [ + BrowserModule, + AppRoutingModule, + HttpClientModule, + FormsModule, + NgbModule, + ], + providers: [BackendService], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/src/app/components/backlog/backlog.component.css b/src/app/components/backlog/backlog.component.css index a268ac9..70f7a6e 100644 --- a/src/app/components/backlog/backlog.component.css +++ b/src/app/components/backlog/backlog.component.css @@ -1,3 +1,3 @@ th.sortable:hover { text-decoration: underline; -} \ No newline at end of file +} diff --git a/src/app/components/backlog/backlog.component.html b/src/app/components/backlog/backlog.component.html index d1d1592..441a4db 100644 --- a/src/app/components/backlog/backlog.component.html +++ b/src/app/components/backlog/backlog.component.html @@ -1,97 +1,134 @@
-
-

Backlog

-
-
-
- -
-
- -
-
-

Backlog

-
-
-
- -

- Aktuell läuft kein Sprint. - Zur Sprint Übersicht -

-
- -

Aktueller Sprint:

-

Sprint:

- -
-
-
-
- -
-
-
-
-
-

{{story.title}}

-
Prio: - {{story.priority}}
-

{{story.content}}

-
- Category: - {{story.categoryid || "N/A"}} - Status: - {{story.statusid || "N/A"}} -
-
- -
-
-
-
-
- -
-
-
-
-

{{story.title}}

-
Prio: - {{story.priority}}
-

{{story.content}}

-
- Category: - {{story.categoryid || "N/A"}} - Status: - {{story.statusid || "N/A"}} -
-
- -
-
-
-
-
-
+
+

Backlog

+
+
+
+ +
-
\ No newline at end of file + +
+
+

Backlog

+
+
+
+ +

+ Aktuell läuft kein Sprint. + Zur Sprint Übersicht +

+
+ +

Aktueller Sprint:

+

Sprint:

+ +
+
+
+
+ +
+
+
+
+
+

{{ story.title }}

+
+ Prio: {{ story.priority }} +
+

{{ story.content }}

+
+ Category: {{ story.categoryid || "N/A" }} + Status: {{ story.statusid || "N/A" }} +
+
+ +
+
+
+
+
+ +
+
+
+
+

{{ story.title }}

+
+ Prio: {{ story.priority }} +
+

{{ story.content }}

+
+ Category: {{ story.categoryid || "N/A" }} + Status: {{ story.statusid || "N/A" }} +
+
+ +
+
+
+
+
+
+
+
diff --git a/src/app/components/backlog/backlog.component.ts b/src/app/components/backlog/backlog.component.ts index 6581fae..110058a 100644 --- a/src/app/components/backlog/backlog.component.ts +++ b/src/app/components/backlog/backlog.component.ts @@ -9,15 +9,12 @@ import { import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { SprintFormComponent } from '../sprint-form/sprint-form.component'; - @Component({ selector: 'app-backlog', templateUrl: './backlog.component.html', styleUrls: ['./backlog.component.css'], }) - - -export class BacklogComponent{ +export class BacklogComponent { public status: ScrumStatus[] = []; public categories: ScrumCategory[] = []; public sprints: ScrumSprint[] = []; @@ -26,12 +23,12 @@ export class BacklogComponent{ /** * Constructor of the class that initialized the communication with the backend - * @param backendService - * @param modalService + * @param backendService + * @param modalService */ constructor( private backendService: BackendService, - private modalService: NgbModal, + private modalService: NgbModal ) { backendService.getSprints().subscribe((response) => { if (response.status > 399) { @@ -80,19 +77,19 @@ export class BacklogComponent{ * The relation to the sprint is determined by the userstory's sprintid. * If no sprint is selected it just returns an empty array. */ - public get choosen(): ScrumUserstory[] - { - if(this.selectedSprint === undefined){return null;} - return this.storys.filter(u => u.sprintid == this.selectedSprint.id); + public get choosen(): ScrumUserstory[] { + if (this.selectedSprint === undefined) { + return null; + } + return this.storys.filter((u) => u.sprintid == this.selectedSprint.id); } /** * Getter that returns an array with all userstories that aren't in any sprint. * The relation to no sprint is determined by the userstory's sprintid being undefined. */ - public get backlog(): ScrumUserstory[] - { - return this.storys.filter(u => u.sprintid === undefined); + public get backlog(): ScrumUserstory[] { + return this.storys.filter((u) => u.sprintid === undefined); } /** @@ -101,7 +98,9 @@ export class BacklogComponent{ */ public get currentSprint(): ScrumSprint { const now = Date.now(); - return this.sprints.find(s => Date.parse(s.startDate) < now && Date.parse(s.endDate) > now); + return this.sprints.find( + (s) => Date.parse(s.startDate) < now && Date.parse(s.endDate) > now + ); } //#endregion getters @@ -121,11 +120,11 @@ export class BacklogComponent{ }); } - /** + /** * Deletes a userstory from the currently selected sprint by changing it's sprintid to undefined * @param userstory userstory object that shall be removed from the selected sprint's backlog */ - public deleteFromSprintBacklog(userstory: ScrumUserstory){ + public deleteFromSprintBacklog(userstory: ScrumUserstory) { userstory.sprintid = undefined; this.backendService.putUserstory(userstory).subscribe((response) => { if (response.status > 399) { @@ -145,12 +144,12 @@ export class BacklogComponent{ const modalRef = this.modalService.open(SprintFormComponent, { backdrop: 'static', keyboard: true, - size: "md", + size: 'md', }); - modalRef.result.then(result => { + modalRef.result.then((result) => { this.sprints.push(result); }); - } + } //#endregion modals } diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html index 4c62d00..eb8fa71 100644 --- a/src/app/components/dashboard/dashboard.component.html +++ b/src/app/components/dashboard/dashboard.component.html @@ -1,36 +1,57 @@
-

Dashboard

-
-

Alle Userstories

- Lege einen Sprint an, um Userstories zu organisieren. + Lege einen Sprint an, um Userstories zu organisieren.
- -

Aktueller Sprint:

-

Sprint:

-

{{selectedSprint.title}}

-

{{toDateString(selectedSprint.startDate)}} - {{toDateString(selectedSprint.endDate)}}

+

+ Aktueller Sprint: +

+

+ Sprint: +

+

{{ selectedSprint.title }}

+

+ {{ toDateString(selectedSprint.startDate) }} - + {{ toDateString(selectedSprint.endDate) }} +

-
-
- - Userstories - + + Userstories +
-
- Zum Sprint "{{selectedSprint.title}}" sind aktuell keine Userstories vorhanden. +
+ Zum Sprint "{{ selectedSprint.title }}" sind aktuell keine + Userstories vorhanden.
-
+
- - {{status.title}} - + + {{ status.title }} +
- - {{getNumberOfUserstoriesByStatus(status)}} - + + {{ getNumberOfUserstoriesByStatus(status) }} +
@@ -89,13 +107,13 @@
- +
-
-
diff --git a/src/app/components/dashboard/dashboard.component.ts b/src/app/components/dashboard/dashboard.component.ts index b47f895..8dd697c 100644 --- a/src/app/components/dashboard/dashboard.component.ts +++ b/src/app/components/dashboard/dashboard.component.ts @@ -1,31 +1,44 @@ -import {Component, OnChanges} from '@angular/core'; -import {forkJoin} from 'rxjs'; +import { Component, OnChanges } from '@angular/core'; +import { forkJoin } from 'rxjs'; import Chart from 'chart.js'; -import {BackendService, ScrumSprint, ScrumStatus, ScrumUserstory} from '../../services/backend.service'; +import { + BackendService, + ScrumSprint, + ScrumStatus, + ScrumUserstory, +} from '../../services/backend.service'; @Component({ selector: 'app-dashboard', templateUrl: 'dashboard.component.html', - styleUrls: ['./dashboard.component.css'] + styleUrls: ['./dashboard.component.css'], }) export class DashboardComponent { /** * Returns the status that are used by at least one userstory. */ public get usedStatus(): ScrumStatus[] { - return this.status.filter(s => this.selectedSprintUserstories.find(us => us.statusid === s.id) !== undefined); + return this.status.filter( + (s) => + this.selectedSprintUserstories.find((us) => us.statusid === s.id) !== + undefined + ); } public get selectedSprintUserstories(): ScrumUserstory[] { if (this.selectedSprint === undefined) { return this.userstories; } - return this.userstories.filter(us => us.sprintid === this.selectedSprint.id); + return this.userstories.filter( + (us) => us.sprintid === this.selectedSprint.id + ); } public get currentSprint(): ScrumSprint { const now = Date.now(); - return this.sprints.find(s => Date.parse(s.startDate) < now && Date.parse(s.endDate) > now); + return this.sprints.find( + (s) => Date.parse(s.startDate) < now && Date.parse(s.endDate) > now + ); } private _selectedSprint: ScrumSprint; @@ -53,18 +66,25 @@ export class DashboardComponent { constructor(private backendService: BackendService) { // download userstories, status and sprints and update // the chart whenever a new response is there - forkJoin([backendService.getUserstories(), backendService.getAllStatus(), backendService.getSprints()]) - .subscribe(results => { - const [userstoryResponse, statusResponse, sprintResponse] = results; - if (userstoryResponse.status > 399 || statusResponse.status > 399 || sprintResponse.status > 399) { - alert('Fehler'); - } else { - this.userstories.push(...userstoryResponse.body); - this.status.push(...statusResponse.body); - this.sprints.push(...sprintResponse.body); - this.createChart(); - } - }); + forkJoin([ + backendService.getUserstories(), + backendService.getAllStatus(), + backendService.getSprints(), + ]).subscribe((results) => { + const [userstoryResponse, statusResponse, sprintResponse] = results; + if ( + userstoryResponse.status > 399 || + statusResponse.status > 399 || + sprintResponse.status > 399 + ) { + alert('Fehler'); + } else { + this.userstories.push(...userstoryResponse.body); + this.status.push(...statusResponse.body); + this.sprints.push(...sprintResponse.body); + this.createChart(); + } + }); } /** @@ -77,31 +97,35 @@ export class DashboardComponent { private createChart() { // @ts-ignore - const context = document.getElementById('done-stories-chart').getContext('2d'); + const context = document + .getElementById('done-stories-chart') + .getContext('2d'); if (this.usedStatus.length === 0) { this.chart.destroy(); - } - - else { + } else { this.chart = new Chart(context, { type: 'pie', data: { - labels: this.usedStatus.map(s => s.title), - datasets: [{ - data: this.usedStatus.map(s => this.getNumberOfUserstoriesByStatus(s)), - backgroundColor: this.getBackgroundColors(), - options: { - legend: { - display: true, - position: 'right', - labels: { - fontColor: 'rgba(255, 255, 255, 0.8)' - } - } - } - }] - } + labels: this.usedStatus.map((s) => s.title), + datasets: [ + { + data: this.usedStatus.map((s) => + this.getNumberOfUserstoriesByStatus(s) + ), + backgroundColor: this.getBackgroundColors(), + options: { + legend: { + display: true, + position: 'right', + labels: { + fontColor: 'rgba(255, 255, 255, 0.8)', + }, + }, + }, + }, + ], + }, }); this.chart.update(); this.chart.render(); @@ -133,14 +157,18 @@ export class DashboardComponent { } public getNumberOfUserstoriesByStatus(status: ScrumStatus): number { - return this.selectedSprintUserstories.filter(us => us.statusid === status.id).length; + return this.selectedSprintUserstories.filter( + (us) => us.statusid === status.id + ).length; } public getRemainingDaysInSprint(): number { if (this.selectedSprint === undefined) { return undefined; } - return Math.floor((Date.parse(this.selectedSprint.endDate) - Date.now()) / 86400000); + return Math.floor( + (Date.parse(this.selectedSprint.endDate) - Date.now()) / 86400000 + ); } /** @@ -154,7 +182,8 @@ export class DashboardComponent { return undefined; } const deltaFromNow = Date.parse(sprint.endDate) - now; - const deltaFromStart = Date.parse(sprint.endDate) - Date.parse(sprint.startDate); - return Math.floor(3 * deltaFromNow / deltaFromStart); + const deltaFromStart = + Date.parse(sprint.endDate) - Date.parse(sprint.startDate); + return Math.floor((3 * deltaFromNow) / deltaFromStart); } } diff --git a/src/app/components/sprint-form/sprint-form.component.css b/src/app/components/sprint-form/sprint-form.component.css index 717de4c..cf0cdf8 100644 --- a/src/app/components/sprint-form/sprint-form.component.css +++ b/src/app/components/sprint-form/sprint-form.component.css @@ -1,4 +1,4 @@ .modal-footer { - border-top: 0px solid; - padding-top: 5%; -} \ No newline at end of file + border-top: 0px solid; + padding-top: 5%; +} diff --git a/src/app/components/sprint-form/sprint-form.component.html b/src/app/components/sprint-form/sprint-form.component.html index fcb9fa8..1b886c2 100644 --- a/src/app/components/sprint-form/sprint-form.component.html +++ b/src/app/components/sprint-form/sprint-form.component.html @@ -10,26 +10,56 @@
- +
- +
- +
-
-
\ No newline at end of file + diff --git a/src/app/components/sprint-form/sprint-form.component.ts b/src/app/components/sprint-form/sprint-form.component.ts index bac0d22..06e2b3f 100644 --- a/src/app/components/sprint-form/sprint-form.component.ts +++ b/src/app/components/sprint-form/sprint-form.component.ts @@ -1,60 +1,60 @@ // Importing necessary components and interfaces. import { Component, OnInit, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; -import { - BackendService, - ScrumSprint -} from '../../services/backend.service'; +import { BackendService, ScrumSprint } from '../../services/backend.service'; @Component({ - selector: 'app-task-form', - templateUrl: './sprint-form.component.html', - styleUrls: ['./sprint-form.component.css'] + selector: 'app-task-form', + templateUrl: './sprint-form.component.html', + styleUrls: ['./sprint-form.component.css'], }) // Class implements the logic for a popup window form to create and modify sprints. export class SprintFormComponent implements OnInit { - @Input() public sprint: ScrumSprint; - public editing: Boolean; - public sprintid: string; + @Input() public sprint: ScrumSprint; + public editing: Boolean; + public sprintid: string; - constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) { } + constructor( + private backendService: BackendService, + private activeModalService: NgbActiveModal + ) {} - // If no sprint exists a new one will be created. - // In other cases the sprint exists and gets modifiable. - ngOnInit(): void { - if (this.sprint === null || this.sprint === undefined) { - this.sprint = { title: '', startDate: '', endDate: '' }; - this.editing = false; - } else { - this.editing = true; - } - document.getElementById('titleField').focus(); - } + // If no sprint exists a new one will be created. + // In other cases the sprint exists and gets modifiable. + ngOnInit(): void { + if (this.sprint === null || this.sprint === undefined) { + this.sprint = { title: '', startDate: '', endDate: '' }; + this.editing = false; + } else { + this.editing = true; + } + document.getElementById('titleField').focus(); + } - // A new created sprint will be saved in backend (POST). - // If a sprint already exists, modifying results an update (PUT) to the backend. - onSubmit() { - if (this.editing) { - this.backendService.putSprint(this.sprint).subscribe((response) => { - if (response.status > 399) { - alert('Fehler'); - } - }); - } else { - this.backendService.postSprint(this.sprint).subscribe((response) => { - console.log('Sprint gespeichert!'); - if (response.status > 399) { - alert('Fehler'); - } - }); - } - // Closes the popup window after submitting/canceling. - this.activeModalService.close(this.sprint); - } + // A new created sprint will be saved in backend (POST). + // If a sprint already exists, modifying results an update (PUT) to the backend. + onSubmit() { + if (this.editing) { + this.backendService.putSprint(this.sprint).subscribe((response) => { + if (response.status > 399) { + alert('Fehler'); + } + }); + } else { + this.backendService.postSprint(this.sprint).subscribe((response) => { + console.log('Sprint gespeichert!'); + if (response.status > 399) { + alert('Fehler'); + } + }); + } + // Closes the popup window after submitting/canceling. + this.activeModalService.close(this.sprint); + } - // Closes the popup form window (by clicking "close button"). - onClose() { - this.activeModalService.dismiss(this.sprint); - } + // Closes the popup form window (by clicking "close button"). + onClose() { + this.activeModalService.dismiss(this.sprint); + } } diff --git a/src/app/components/tabels/sprint/sprint-table.component.html b/src/app/components/tabels/sprint/sprint-table.component.html index bc9b627..f4d8784 100644 --- a/src/app/components/tabels/sprint/sprint-table.component.html +++ b/src/app/components/tabels/sprint/sprint-table.component.html @@ -4,40 +4,66 @@ Sprints - + @@ -45,22 +71,34 @@ - - - - - + + + + + -
ID - - - + + + Titel - - - + + + Start - - - + + + End - - - + + +
{{sprint.id}}{{sprint.title}}{{sprint.startDate | date:'dd.MM.yyyy'}}{{sprint.endDate | date:'dd.MM.yyyy'}}
{{ sprint.id }}{{ sprint.title }}{{ sprint.startDate | date: "dd.MM.yyyy" }}{{ sprint.endDate | date: "dd.MM.yyyy" }} - -
diff --git a/src/app/components/tabels/sprint/sprint-table.component.ts b/src/app/components/tabels/sprint/sprint-table.component.ts index d95b0b0..904df3b 100644 --- a/src/app/components/tabels/sprint/sprint-table.component.ts +++ b/src/app/components/tabels/sprint/sprint-table.component.ts @@ -89,4 +89,4 @@ export class SprintTableComponent extends TableComponentBase { modalRef.componentInstance.sprint = editSprint; } //#endregion modals -} \ No newline at end of file +} diff --git a/src/app/components/tabels/task/task-table.component.html b/src/app/components/tabels/task/task-table.component.html index c089e9f..ebe6f20 100644 --- a/src/app/components/tabels/task/task-table.component.html +++ b/src/app/components/tabels/task/task-table.component.html @@ -1,8 +1,11 @@
- + @@ -19,66 +24,118 @@ @@ -86,41 +143,53 @@ - - - + + + - + -
ID - - - + + + Titel - - - + + + Userstory - - - + + + Status - - - + + +
Priorität:
- {{filterPriority || "All"}} + {{ + filterPriority || "All" + }}
- - + +
- - - + + +
Assigned To - - - + + + Category - - - + + +
{{task.id}}{{task.title}}
{{ task.id }}{{ task.title }} - - US #{{task.userstoryid}} + + US #{{ task.userstoryid }} - - {{getStatusTitleById(task.statusid)}} + + {{ getStatusTitleById(task.statusid) }} {{task.priority}}{{ task.priority }} - - {{getUserNameById(task.assignedtoid)}} + + {{ getUserNameById(task.assignedtoid) }} - - {{getCategoryTitleById(task.categoryid)}} + + {{ getCategoryTitleById(task.categoryid) }} - -
diff --git a/src/app/components/tabels/task/task-table.component.ts b/src/app/components/tabels/task/task-table.component.ts index ad9c0bb..87442c0 100644 --- a/src/app/components/tabels/task/task-table.component.ts +++ b/src/app/components/tabels/task/task-table.component.ts @@ -195,4 +195,4 @@ export class TaskTableComponent extends TableComponentBase { modalRef.componentInstance.task = editTask; } //#endregion modals -} \ No newline at end of file +} diff --git a/src/app/components/tabels/userstory-inner-table/userstory-inner-table.component.html b/src/app/components/tabels/userstory-inner-table/userstory-inner-table.component.html index 633f714..ea775a7 100644 --- a/src/app/components/tabels/userstory-inner-table/userstory-inner-table.component.html +++ b/src/app/components/tabels/userstory-inner-table/userstory-inner-table.component.html @@ -1,99 +1,155 @@ - + - - + - - + - + - + - + - + - + + + + + + - + - - - - - + + + + - + - - + + - + + - - -
+ ID - - - - - + + + + + Titel - - - + + + - + Tasks - - - - - + + + + + Status - - - - - + + + + +
- Priorität: -
- {{filterPriority || "All"}} -
- - -
+ Priorität: +
+ {{ + filterPriority || "All" + }} +
+ +
- - - - -
-
+ + + + + + + Category - - - - -
{{userstory.id}}{{userstory.title}} - - {{getNumberOfTasks(userstory)}} Tasks +
{{ userstory.id }}{{ userstory.title }} + + {{ getNumberOfTasks(userstory) }} Tasks - - - {{getStatusTitleById(userstory.statusid)}} + + + {{ getStatusTitleById(userstory.statusid) }} - {{userstory.priority}} - - {{getCategoryTitleById(userstory.categoryid)}} + {{ userstory.priority }} + + {{ getCategoryTitleById(userstory.categoryid) }} - - - - + + +
\ No newline at end of file + + diff --git a/src/app/components/tabels/userstory/userstory-table.component.html b/src/app/components/tabels/userstory/userstory-table.component.html index 870d468..0b4d5a8 100644 --- a/src/app/components/tabels/userstory/userstory-table.component.html +++ b/src/app/components/tabels/userstory/userstory-table.component.html @@ -3,4 +3,4 @@

Userstories

- \ No newline at end of file + diff --git a/src/app/components/task-form/task-form.component.css b/src/app/components/task-form/task-form.component.css index 3089d6a..9044d26 100644 --- a/src/app/components/task-form/task-form.component.css +++ b/src/app/components/task-form/task-form.component.css @@ -1,3 +1,3 @@ .modal .modal-content { - display: contents; -} \ No newline at end of file + display: contents; +} diff --git a/src/app/components/task-form/task-form.component.html b/src/app/components/task-form/task-form.component.html index 680ec5a..fcb670b 100644 --- a/src/app/components/task-form/task-form.component.html +++ b/src/app/components/task-form/task-form.component.html @@ -1,118 +1,230 @@
-
-
-
- +
+
+
+ +
+
+
+

Neuen Task anlegen

+
+
+
+
+
+
+
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ + +
+
+
+
+
+ + +
+
+
-
\ No newline at end of file +
+
diff --git a/src/app/components/task-form/task-form.component.spec.ts b/src/app/components/task-form/task-form.component.spec.ts index 1a3a1d0..6f3b6c1 100644 --- a/src/app/components/task-form/task-form.component.spec.ts +++ b/src/app/components/task-form/task-form.component.spec.ts @@ -8,9 +8,8 @@ describe('TaskFormComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ TaskFormComponent ] - }) - .compileComponents(); + declarations: [TaskFormComponent], + }).compileComponents(); })); beforeEach(() => { diff --git a/src/app/components/task-form/task-form.component.ts b/src/app/components/task-form/task-form.component.ts index 8da2775..af92610 100644 --- a/src/app/components/task-form/task-form.component.ts +++ b/src/app/components/task-form/task-form.component.ts @@ -2,199 +2,202 @@ import { Component, OnInit, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { - BackendService, - ScrumTask, - Priority, - ScrumStatus, - ScrumCategory, - ScrumUser, - ScrumProject, - ScrumUserstory + 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'] + selector: 'app-task-form', + templateUrl: './task-form.component.html', + styleUrls: ['./task-form.component.css'], }) // Class implements the logic for a popup window form to create and modify tasks. export 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: "" }; + @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(); - } + constructor( + private backendService: BackendService, + private activeModalService: NgbActiveModal + ) { + this.getUserStories(); + this.getTaskStatus(); + this.getAllUsers(); + } - // If no task exists a new one 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 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'); - } - }); - } - // Closes the popup window after submitting/canceling. - this.activeModalService.close(this.task); - } + // If no task exists a new one 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 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'); + } + }); + } + // 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); - } + // 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 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 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); - } - }); - } + // 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. - 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 status (such as "Waiting") can be created, which will be stored in an array. + // The new status is available to all tasks. + 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. - 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 status can even be deleted if not used anymore. + // This will remove the status from status-array. + 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 values of the Priority enum to be shown in a dropdown in popup window. - getAllPriorities(): Priority[] { - return Object.values(Priority); - } + // Getting the values of the Priority enum to be shown in a dropdown in popup window. + getAllPriorities(): Priority[] { + return Object.values(Priority); + } - // necessary????????????????????????????????????????????????????? - getUserstoryTitleById(id: number): string { - if (!id) { - return null; - } - var story = this.userstories.find((x) => x.id === id); - if (!story) { - return null; - } - return story.title; - } + // necessary????????????????????????????????????????????????????? + 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. - getStatusTitleById(id: number): string { - if (!id) { - return null; - } - var status = this.allStatus.find((x) => x.id === id); - if (!status) { - return null; - } - return status.title; - } + // Shows the before choosen status in the status-field in the popup window. + 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); - } - }); - } + // 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. - getAuthorById(id: number): string { - if (!id) { - return null; - } - var user = this.allUser.find((x) => x.id === id); - if (!user) { - return null; - } - return user.name; - } + // Shows the before assigned user in the author-field in the popup window. + getAuthorById(id: number): string { + if (!id) { + return null; + } + var user = this.allUser.find((x) => x.id === id); + if (!user) { + return null; + } + return user.name; + } } diff --git a/src/app/components/userstory-form/userstory-form.component.css b/src/app/components/userstory-form/userstory-form.component.css index 3089d6a..9044d26 100644 --- a/src/app/components/userstory-form/userstory-form.component.css +++ b/src/app/components/userstory-form/userstory-form.component.css @@ -1,3 +1,3 @@ .modal .modal-content { - display: contents; -} \ No newline at end of file + display: contents; +} diff --git a/src/app/components/userstory-form/userstory-form.component.html b/src/app/components/userstory-form/userstory-form.component.html index 0acc5bb..6923853 100644 --- a/src/app/components/userstory-form/userstory-form.component.html +++ b/src/app/components/userstory-form/userstory-form.component.html @@ -1,140 +1,278 @@
-
-
-
- -
-
-
-

Neue Userstory anlegen

-
-
-
-
-
-
-
- - -
-
- - -
-
-
- -
- - -
-
- - -
-
- - -
-
-
-
-
- - -
-
-
+
+
+
+ +
+
+
+

Neue Userstory anlegen

+
+
+
+
+
+
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+
-
\ No newline at end of file +
+
diff --git a/src/app/components/userstory-form/userstory-form.component.ts b/src/app/components/userstory-form/userstory-form.component.ts index 9838fe7..b0dc92b 100644 --- a/src/app/components/userstory-form/userstory-form.component.ts +++ b/src/app/components/userstory-form/userstory-form.component.ts @@ -1,207 +1,212 @@ // Importing necessary components and interfaces. import { Component, OnInit, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; -import { BackendService, ScrumUserstory, Priority } from '../../services/backend.service'; import { - ScrumTask, - ScrumStatus, - ScrumCategory, - ScrumUser, - ScrumProject, + BackendService, + ScrumUserstory, + Priority, +} from '../../services/backend.service'; +import { + ScrumTask, + ScrumStatus, + ScrumCategory, + ScrumUser, + ScrumProject, } from '../../services/backend.service'; @Component({ - selector: 'app-userstory-form', - templateUrl: './userstory-form.component.html', - styleUrls: ['./userstory-form.component.css'] + selector: 'app-userstory-form', + templateUrl: './userstory-form.component.html', + styleUrls: ['./userstory-form.component.css'], }) // Class implements the logic for a popup window form to create and modify userstories. export 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: "" }; - private editing: boolean; + @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: '' }; + private editing: boolean; - constructor(private backendService: BackendService, private activeModalService: NgbActiveModal) { - this.getUserstoryStatus(); - this.getAllUsers(); - this.getUserstoryCategory(); - } + 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(); - } + // 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 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'); - } - }); - } - // Closes the popup window after submitting/canceling. - this.activeModalService.close(this.userstory); - } + // A new created userstory will be saved in 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'); + } + }); + } + // 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); - } + // 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); - } - }); - } + // 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. - createUserstoryStatus(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 status (such as "Waiting") can be created, which will be stored in an array. + // The new status is available to all userstories. + 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. - 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; - }); - } + // A custom status can even be deleted if not used anymore. + // This will remove the status from status-array. + 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); - } + // 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. - getStatusTitleById(id: number): string { - if (!id) { - return null; - } - var status = this.allStatus.find((x) => x.id === id); - if (!status) { - return null; - } - return status.title; - } + // Shows the before choosen status in the status-field in the popup window. + 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); - } - }); - } + // 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. - getAuthorById(id: number): string { - if (!id) { - return null; - } - var user = this.allUser.find((x) => x.id === id); - if (!user) { - return null; - } - return user.name; - } + // Shows the before assigned user in the author-field in the popup window. + 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); - } - }); - } + // 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. - 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 category can be created, which will be stored in an array. + // The new category is available to all userstories. + 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. - 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. - getCategoryById(id: number): string { - if (!id) { - return null; - } - var category = this.allCategories.find((x) => x.id === id); - if (!category) { - return null; - } - return category.title; - } + // A custom category can even be deleted if not used anymore. + // This will remove the category from category-array. + 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. + getCategoryById(id: number): string { + if (!id) { + return null; + } + var category = this.allCategories.find((x) => x.id === id); + if (!category) { + return null; + } + return category.title; + } } diff --git a/src/app/services/backend.service.ts b/src/app/services/backend.service.ts index 3816388..9761298 100644 --- a/src/app/services/backend.service.ts +++ b/src/app/services/backend.service.ts @@ -1,282 +1,282 @@ -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'; + +@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; +} diff --git a/src/app/services/sorting.service.ts b/src/app/services/sorting.service.ts index 59b90e6..4231c91 100644 --- a/src/app/services/sorting.service.ts +++ b/src/app/services/sorting.service.ts @@ -1,4 +1,4 @@ -import {Priority} from './backend.service'; +import { Priority } from './backend.service'; export function sortByNumberAscending(items: T[], key: (T) => number) { return items.sort((a, b) => key(a) - key(b)); @@ -9,7 +9,7 @@ export function sortByStringAscending(items: T[], key: (T) => string) { } export function sortByDateAscending(items: T[], key: (T) => Date) { - return items.sort((a, b) => key(b) - key(a)); + return items.sort((a, b) => key(b) - key(a)); } export function getNumberForPriority(priority: Priority): number { @@ -21,4 +21,4 @@ export function getNumberForPriority(priority: Priority): number { case Priority.Low: return 0; } -}; +} diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073..c966979 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index b802079..1d2b103 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -4,8 +4,8 @@ export const environment = { production: false, - apiUrl: window["env"]["apiUrl"] || "default", - debug: window["env"]["debug"] || false + apiUrl: window['env']['apiUrl'] || 'default', + debug: window['env']['debug'] || false, }; /* diff --git a/src/index.html b/src/index.html index f02b301..465957e 100644 --- a/src/index.html +++ b/src/index.html @@ -1,18 +1,23 @@ - + - - - Frontend - - - - - - - - - - - + + + Frontend + + + + + + + + + + + - diff --git a/src/main.ts b/src/main.ts index c7b673c..d9a2e7e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts index 7c9e495..0a3281c 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -59,8 +59,7 @@ import '@angular/localize/init'; /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/src/styles.css b/src/styles.css index 0fe5df0..83bbb38 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,9 +1,8 @@ /* You can add global styles to this file, and also import other style files */ .custom-text-secondary { - color: white; - } - - .white-content .custom-text-secondary { - color: black !important; - } - \ No newline at end of file + color: white; +} + +.white-content .custom-text-secondary { + color: black !important; +} diff --git a/src/styles.scss b/src/styles.scss index 7fefb6f..110804b 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,17 +1,17 @@ -@import "~bootstrap/scss/bootstrap"; - -.modal .modal-content { - display: contents; -} - -th.sortable:hover { - text-decoration: underline; -} - -.content { - position: relative; - float: left; - margin-top: 10px; - margin-left: 20px; - width: 80%; -} +@import "~bootstrap/scss/bootstrap"; + +.modal .modal-content { + display: contents; +} + +th.sortable:hover { + text-decoration: underline; +} + +.content { + position: relative; + float: left; + margin-top: 10px; + margin-left: 20px; + width: 80%; +} diff --git a/src/test.ts b/src/test.ts index 1631789..9f69a57 100644 --- a/src/test.ts +++ b/src/test.ts @@ -4,7 +4,7 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, - platformBrowserDynamicTesting + platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; declare const require: any; diff --git a/tsconfig.app.json b/tsconfig.app.json index f758d98..29f5f58 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -4,11 +4,6 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 8c4ef3b..8cbc5cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,10 +11,7 @@ "moduleResolution": "node", "importHelpers": true, "target": "es2015", - "lib": [ - "es2018", - "dom" - ] + "lib": ["es2018", "dom"] }, "angularCompilerOptions": { "fullTemplateTypeCheck": true, diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 6400fde..430cf75 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -2,17 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/tslint.json b/tslint.json index d92ff5d..41c5486 100644 --- a/tslint.json +++ b/tslint.json @@ -2,10 +2,7 @@ "extends": "tslint:recommended", "rules": { "align": { - "options": [ - "parameters", - "statements" - ] + "options": ["parameters", "statements"] }, "array-type": false, "arrow-return-shorthand": true, @@ -16,34 +13,16 @@ "component-class-suffix": true, "contextual-lifecycle": true, "directive-class-suffix": true, - "directive-selector": [ - true, - "attribute", - "app", - "camelCase" - ], - "component-selector": [ - true, - "element", - "app", - "kebab-case" - ], + "directive-selector": [true, "attribute", "app", "camelCase"], + "component-selector": [true, "element", "app", "kebab-case"], "eofline": true, - "import-blacklist": [ - true, - "rxjs/Rx" - ], + "import-blacklist": [true, "rxjs/Rx"], "import-spacing": true, "indent": { - "options": [ - "spaces" - ] + "options": ["spaces"] }, "max-classes-per-file": false, - "max-line-length": [ - true, - 140 - ], + "max-line-length": [true, 140], "member-ordering": [ true, { @@ -55,35 +34,17 @@ ] } ], - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], + "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], "no-empty": false, - "no-inferrable-types": [ - true, - "ignore-params" - ], + "no-inferrable-types": [true, "ignore-params"], "no-non-null-assertion": true, "no-redundant-jsdoc": true, "no-switch-case-fall-through": true, "no-var-requires": false, - "object-literal-key-quotes": [ - true, - "as-needed" - ], - "quotemark": [ - true, - "single" - ], + "object-literal-key-quotes": [true, "as-needed"], + "quotemark": [true, "single"], "semicolon": { - "options": [ - "always" - ] + "options": ["always"] }, "space-before-function-paren": { "options": { @@ -113,11 +74,7 @@ ] }, "variable-name": { - "options": [ - "ban-keywords", - "check-format", - "allow-pascal-case" - ] + "options": ["ban-keywords", "check-format", "allow-pascal-case"] }, "whitespace": { "options": [ @@ -142,7 +99,5 @@ "use-lifecycle-interface": true, "use-pipe-transform-interface": true }, - "rulesDirectory": [ - "codelyzer" - ] -} \ No newline at end of file + "rulesDirectory": ["codelyzer"] +}