From b3d87e3f9a7b0ec49e7dbd8c77ccb08bca28bad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danyi=20D=C3=A1vid?= Date: Fri, 11 May 2018 10:46:27 +0200 Subject: [PATCH] * api stuff started --- src/app/app-routing.module.ts | 6 +- src/app/app.module.ts | 6 +- .../awardee-editor.component.css | 2 +- .../awardee-editor.component.html | 4 +- .../awardee-editor.component.ts | 21 +++---- .../awardee-list/awardee-list.component.ts | 6 +- .../judge-editor/judge-editor.component.css | 16 +++--- .../judge-editor/judge-editor.component.html | 27 ++++++--- .../judge-editor/judge-editor.component.ts | 56 ++++++++++++++++++- .../judge-list-table-datasource.ts | 52 +++++------------ .../judge-list-table.component.html | 6 +- .../judge-list-table.component.ts | 10 +++- src/app/judge-list/judge-list.component.ts | 17 +++++- src/app/navigation/navigation.component.html | 3 +- src/app/shared/judge-title.ts | 5 ++ src/app/shared/judge.service.spec.ts | 15 +++++ src/app/shared/judge.service.ts | 34 +++++++++++ src/app/shared/judge.ts | 7 +++ src/app/shared/judged-year.ts | 4 ++ src/app/shared/year.service.spec.ts | 15 +++++ src/app/shared/year.service.ts | 22 ++++++++ src/environments/environment.prod.ts | 3 +- src/environments/environment.ts | 3 +- 23 files changed, 255 insertions(+), 85 deletions(-) create mode 100644 src/app/shared/judge-title.ts create mode 100644 src/app/shared/judge.service.spec.ts create mode 100644 src/app/shared/judge.service.ts create mode 100644 src/app/shared/judge.ts create mode 100644 src/app/shared/judged-year.ts create mode 100644 src/app/shared/year.service.spec.ts create mode 100644 src/app/shared/year.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 58c9bee..c391fcb 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { AwardeeListComponent } from "./awardee-list/awardee-list.component"; import { JudgeListComponent } from "./judge-list/judge-list.component"; import { AwardeeEditorComponent } from "./awardee-editor/awardee-editor.component"; import { JudgeEditorComponent } from "./judge-editor/judge-editor.component"; +import { JudgeService } from "./shared/judge.service"; const routes: Routes = [ { @@ -17,7 +18,10 @@ const routes: Routes = [ // canActivate: [AuthGuardService, RoleGuardService], }, { path: 'judges', - component: JudgeListComponent + component: JudgeListComponent, + resolve: { + judges: JudgeService, + } // canActivate: [AuthGuardService, RoleGuardService], }, { path: 'judge/new', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e01b130..e8778a2 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,8 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { HttpClientModule } from '@angular/common/http'; +import { FormsModule } from '@angular/forms'; import { LayoutModule } from '@angular/cdk/layout'; import { MatToolbarModule, @@ -40,8 +42,10 @@ import { JudgeEditorComponent } from './judge-editor/judge-editor.component'; ], imports: [ BrowserModule, - AppRoutingModule, BrowserAnimationsModule, + FormsModule, + HttpClientModule, + AppRoutingModule, LayoutModule, MatToolbarModule, MatButtonModule, diff --git a/src/app/awardee-editor/awardee-editor.component.css b/src/app/awardee-editor/awardee-editor.component.css index 72719b5..86d0c3f 100644 --- a/src/app/awardee-editor/awardee-editor.component.css +++ b/src/app/awardee-editor/awardee-editor.component.css @@ -5,7 +5,7 @@ .awardee-form { min-width: 150px; - max-width: 500px; + max-width: 800px; width: 100%; } diff --git a/src/app/awardee-editor/awardee-editor.component.html b/src/app/awardee-editor/awardee-editor.component.html index d8ea208..0625fd8 100644 --- a/src/app/awardee-editor/awardee-editor.component.html +++ b/src/app/awardee-editor/awardee-editor.component.html @@ -9,9 +9,7 @@ - - {{ year }} - + {{ year }} diff --git a/src/app/awardee-editor/awardee-editor.component.ts b/src/app/awardee-editor/awardee-editor.component.ts index d64574a..35de04a 100644 --- a/src/app/awardee-editor/awardee-editor.component.ts +++ b/src/app/awardee-editor/awardee-editor.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import { YearService } from "../shared/year.service"; +import { Title } from "@angular/platform-browser"; @Component({ selector: 'app-awardee-editor', @@ -7,18 +9,17 @@ import { Component, OnInit } from '@angular/core'; }) export class AwardeeEditorComponent implements OnInit { - public years: Array = [ - 2018, - 2017, - 2016, - 2015, - 2014, - 2013, - ]; - - constructor() { } + constructor( + private yearProvider: YearService, + private titleService: Title + ) {} ngOnInit() { + this.titleService.setTitle('Edit awardee'); + } + + get years(): Array { + return this.yearProvider.years; } } diff --git a/src/app/awardee-list/awardee-list.component.ts b/src/app/awardee-list/awardee-list.component.ts index 565f892..9df6664 100644 --- a/src/app/awardee-list/awardee-list.component.ts +++ b/src/app/awardee-list/awardee-list.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Title } from "@angular/platform-browser"; @Component({ selector: 'app-awardee-list', @@ -7,9 +8,12 @@ import { Component, OnInit } from '@angular/core'; }) export class AwardeeListComponent implements OnInit { - constructor() { } + constructor( + private titleService: Title + ) { } ngOnInit() { + this.titleService.setTitle('Awardee list'); } } diff --git a/src/app/judge-editor/judge-editor.component.css b/src/app/judge-editor/judge-editor.component.css index 5effc2f..1cd63ef 100644 --- a/src/app/judge-editor/judge-editor.component.css +++ b/src/app/judge-editor/judge-editor.component.css @@ -5,7 +5,7 @@ .judge-form { min-width: 150px; - max-width: 500px; + max-width: 800px; width: 100%; } @@ -13,17 +13,15 @@ width: 100%; } -.half-width { - width: calc(50% - 10px); - margin-right: 10px; -} - -.half-width:last-of-type { - width: calc(50%); - margin-right: 0; +.year-select { + margin-right: 20px; } button + mat-divider { margin-top: 10px; margin-bottom: 10px; } + +.title-table { + margin-bottom: 20px; +} diff --git a/src/app/judge-editor/judge-editor.component.html b/src/app/judge-editor/judge-editor.component.html index a0b5bf2..26f634d 100644 --- a/src/app/judge-editor/judge-editor.component.html +++ b/src/app/judge-editor/judge-editor.component.html @@ -1,6 +1,6 @@ -
+ - + - - - + + - - + + + {{ year }} + + + + + + + + - Year {{row.year}} diff --git a/src/app/judge-editor/judge-editor.component.ts b/src/app/judge-editor/judge-editor.component.ts index 5fd2449..6191730 100644 --- a/src/app/judge-editor/judge-editor.component.ts +++ b/src/app/judge-editor/judge-editor.component.ts @@ -1,4 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { YearService } from "../shared/year.service"; +import { Title } from "@angular/platform-browser"; +import { JudgedYear } from "../shared/judged-year"; +import { MatTable } from "@angular/material"; +import { ActivatedRoute } from "@angular/router"; +import { Judge } from "../shared/judge"; +import { JudgeService } from "../shared/judge.service"; @Component({ selector: 'app-judge-editor', @@ -6,8 +13,11 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./judge-editor.component.css'] }) export class JudgeEditorComponent implements OnInit { + @ViewChild(MatTable) private table; + + public judgedYearInput: JudgedYear = new JudgedYear(); + public displayedColumns = ['buttons', 'year', 'title']; - public displayedColumns = ['year', 'title']; public judge = { yearlyData: [ { @@ -17,9 +27,49 @@ export class JudgeEditorComponent implements OnInit { ] }; - constructor() {} + constructor( + private yearProvider: YearService, + private judgeService: JudgeService, + private titleService: Title, + private route: ActivatedRoute + ) {} ngOnInit() { + this.titleService.setTitle('Edit judge'); + this.route.data.subscribe((data: { + judges: Array, + }) => { + this.judges = data.judges; + }); } + get judges(): Array { + return this.judgeService.judges; + } + + set judges(judges: Array) { + this.judgeService.judges = judges; + } + + get years(): Array { + return this.yearProvider.years; + } + + get canAdd(): boolean { + return this.judgedYearInput.year != null + && this.judgedYearInput.title.trim().length > 0; + } + + public addToYear() { + let appendable = Object.assign({}, this.judgedYearInput); + this.judge.yearlyData.push(appendable); + this.judgedYearInput = new JudgedYear(); + this.table.renderRows(); + } + + public removeFromYear(year: number) { + this.judge.yearlyData = this.judge.yearlyData.filter( + row => row.year !== year + ); + } } diff --git a/src/app/judge-list-table/judge-list-table-datasource.ts b/src/app/judge-list-table/judge-list-table-datasource.ts index 591df3f..ae65ed1 100644 --- a/src/app/judge-list-table/judge-list-table-datasource.ts +++ b/src/app/judge-list-table/judge-list-table-datasource.ts @@ -2,46 +2,22 @@ import { DataSource } from '@angular/cdk/collections'; import { MatPaginator, MatSort } from '@angular/material'; import { map } from 'rxjs/operators'; import { Observable, of as observableOf, merge } from 'rxjs'; +import { JudgeService } from "../shared/judge.service"; +import { Judge } from "../shared/judge"; -// TODO: Replace this with your own data model type -export interface JudgeListTableItem { - name: string; - id: number; -} - -// TODO: replace this with real data from your application -const EXAMPLE_DATA: JudgeListTableItem[] = [ - {id: 1, name: 'Hydrogen'}, - {id: 2, name: 'Helium'}, - {id: 3, name: 'Lithium'}, - {id: 4, name: 'Beryllium'}, - {id: 5, name: 'Boron'}, - {id: 6, name: 'Carbon'}, - {id: 7, name: 'Nitrogen'}, - {id: 8, name: 'Oxygen'}, - {id: 9, name: 'Fluorine'}, - {id: 10, name: 'Neon'}, - {id: 11, name: 'Sodium'}, - {id: 12, name: 'Magnesium'}, - {id: 13, name: 'Aluminum'}, - {id: 14, name: 'Silicon'}, - {id: 15, name: 'Phosphorus'}, - {id: 16, name: 'Sulfur'}, - {id: 17, name: 'Chlorine'}, - {id: 18, name: 'Argon'}, - {id: 19, name: 'Potassium'}, - {id: 20, name: 'Calcium'}, -]; /** * Data source for the JudgeListTable view. This class should * encapsulate all logic for fetching and manipulating the displayed data * (including sorting, pagination, and filtering). */ -export class JudgeListTableDataSource extends DataSource { - data: JudgeListTableItem[] = EXAMPLE_DATA; +export class JudgeListTableDataSource extends DataSource { - constructor(private paginator: MatPaginator, private sort: MatSort) { + constructor( + private paginator: MatPaginator, + private sort: MatSort, + private judgeService: JudgeService, + ) { super(); } @@ -50,20 +26,20 @@ export class JudgeListTableDataSource extends DataSource { * the returned stream emits new items. * @returns A stream of the items to be rendered. */ - connect(): Observable { + connect(): Observable { // Combine everything that affects the rendered data into one update // stream for the data-table to consume. const dataMutations = [ - observableOf(this.data), + observableOf(this.judgeService.judges), this.paginator.page, this.sort.sortChange ]; // Set the paginators length - this.paginator.length = this.data.length; + this.paginator.length = this.judgeService.judges.length; return merge(...dataMutations).pipe(map(() => { - return this.getPagedData(this.getSortedData([...this.data])); + return this.getPagedData(this.getSortedData([...this.judgeService.judges])); })); } @@ -77,7 +53,7 @@ export class JudgeListTableDataSource extends DataSource { * Paginate the data (client-side). If you're using server-side pagination, * this would be replaced by requesting the appropriate data from the server. */ - private getPagedData(data: JudgeListTableItem[]) { + private getPagedData(data: Judge[]) { const startIndex = this.paginator.pageIndex * this.paginator.pageSize; return data.splice(startIndex, this.paginator.pageSize); } @@ -86,7 +62,7 @@ export class JudgeListTableDataSource extends DataSource { * Sort the data (client-side). If you're using server-side sorting, * this would be replaced by requesting the appropriate data from the server. */ - private getSortedData(data: JudgeListTableItem[]) { + private getSortedData(data: Judge[]) { if (!this.sort.active || this.sort.direction === '') { return data; } diff --git a/src/app/judge-list-table/judge-list-table.component.html b/src/app/judge-list-table/judge-list-table.component.html index 1f0f997..f023ccc 100644 --- a/src/app/judge-list-table/judge-list-table.component.html +++ b/src/app/judge-list-table/judge-list-table.component.html @@ -18,9 +18,9 @@ + [pageSize]="15" + [pageSizeOptions]="[15, 25, 50]"> diff --git a/src/app/judge-list-table/judge-list-table.component.ts b/src/app/judge-list-table/judge-list-table.component.ts index d4b620f..e844ff4 100644 --- a/src/app/judge-list-table/judge-list-table.component.ts +++ b/src/app/judge-list-table/judge-list-table.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { JudgeListTableDataSource } from './judge-list-table-datasource'; +import { JudgeService } from "../shared/judge.service"; +import { Judge } from "../shared/judge"; @Component({ selector: 'judge-list-table', @@ -15,7 +17,13 @@ export class JudgeListTableComponent implements OnInit { /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['id', 'name']; + constructor(private judgeService: JudgeService) {} + ngOnInit() { - this.dataSource = new JudgeListTableDataSource(this.paginator, this.sort); + this.dataSource = new JudgeListTableDataSource(this.paginator, this.sort, this.judgeService); + } + + get judges(): Array { + return this.judgeService.judges; } } diff --git a/src/app/judge-list/judge-list.component.ts b/src/app/judge-list/judge-list.component.ts index 5002445..98a36a3 100644 --- a/src/app/judge-list/judge-list.component.ts +++ b/src/app/judge-list/judge-list.component.ts @@ -1,4 +1,8 @@ import { Component, OnInit } from '@angular/core'; +import { Title } from "@angular/platform-browser"; +import { Judge } from "../shared/judge"; +import { ActivatedRoute } from "@angular/router"; +import { JudgeService } from "../shared/judge.service"; @Component({ selector: 'app-judge-list', @@ -7,9 +11,18 @@ import { Component, OnInit } from '@angular/core'; }) export class JudgeListComponent implements OnInit { - constructor() { } + constructor( + private judgeService: JudgeService, + private titleService: Title, + private route: ActivatedRoute + ) { } ngOnInit() { + this.titleService.setTitle('Judge list'); + this.route.data.subscribe((data: { + judges: Array, + }) => { + this.judgeService.judges = data.judges; + }); } - } diff --git a/src/app/navigation/navigation.component.html b/src/app/navigation/navigation.component.html index ae7dcf4..4797154 100644 --- a/src/app/navigation/navigation.component.html +++ b/src/app/navigation/navigation.component.html @@ -8,9 +8,8 @@ [opened]="!(isHandset | async)!.matches"> Menu - Awardees Judges - Years + Awardees diff --git a/src/app/shared/judge-title.ts b/src/app/shared/judge-title.ts new file mode 100644 index 0000000..e15ff6d --- /dev/null +++ b/src/app/shared/judge-title.ts @@ -0,0 +1,5 @@ +export class JudgeTitle { + id: number; + year: number; + title: string; +} diff --git a/src/app/shared/judge.service.spec.ts b/src/app/shared/judge.service.spec.ts new file mode 100644 index 0000000..d31bfce --- /dev/null +++ b/src/app/shared/judge.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { JudgeService } from './judge.service'; + +describe('JudgeService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [JudgeService] + }); + }); + + it('should be created', inject([JudgeService], (service: JudgeService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/shared/judge.service.ts b/src/app/shared/judge.service.ts new file mode 100644 index 0000000..84069f0 --- /dev/null +++ b/src/app/shared/judge.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from "@angular/router"; +import { HttpClient } from "@angular/common/http"; + +import { Judge } from "./judge"; +import { environment } from '../../environments/environment'; +import { Observable } from "rxjs/internal/Observable"; + +@Injectable({ + providedIn: 'root' +}) +export class JudgeService implements Resolve> { + + private apiEndPoint = `${environment.apiUrl}/judge`; + private cachedJudges: Array = []; + + constructor(private httpClient: HttpClient) {} + + public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise> { + return this.getJudges().toPromise(); + } + + public getJudges(): Observable> { + return this.httpClient.get>(this.apiEndPoint); + } + + get judges(): Array { + return this.cachedJudges; + } + + set judges(judges: Array) { + this.cachedJudges = judges; + } +} diff --git a/src/app/shared/judge.ts b/src/app/shared/judge.ts new file mode 100644 index 0000000..ec3b41c --- /dev/null +++ b/src/app/shared/judge.ts @@ -0,0 +1,7 @@ +import { JudgeTitle } from "./judge-title"; + +export class Judge { + public id: number; + public name: string; + public titles: Array; +} diff --git a/src/app/shared/judged-year.ts b/src/app/shared/judged-year.ts new file mode 100644 index 0000000..9d5ac02 --- /dev/null +++ b/src/app/shared/judged-year.ts @@ -0,0 +1,4 @@ +export class JudgedYear { + public year: number = null; + public title = ''; +} diff --git a/src/app/shared/year.service.spec.ts b/src/app/shared/year.service.spec.ts new file mode 100644 index 0000000..8c7a7a4 --- /dev/null +++ b/src/app/shared/year.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { YearService } from './year.service'; + +describe('YearService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [YearService] + }); + }); + + it('should be created', inject([YearService], (service: YearService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/shared/year.service.ts b/src/app/shared/year.service.ts new file mode 100644 index 0000000..75bebad --- /dev/null +++ b/src/app/shared/year.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class YearService { + + private cachedYears: Array = [ + 2018, + 2017, + 2016, + 2015, + 2014, + 2013, + ]; + + constructor() {} + + get years(): Array { + return this.cachedYears; + } +} diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073..9ea4178 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,4 @@ export const environment = { - production: true + production: true, + apiUrl: 'https://', }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 012182e..9dadab7 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,7 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, + apiUrl: 'http://localhost:8888/api', }; /*