diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index c391fcb..bc5bccc 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -6,15 +6,33 @@ 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";
+import { JudgeResolverService } from "./shared/judge-resolver.service";
+import { AwardeeService } from "./shared/awardee.service";
+import { AwardeeResolverService } from "./shared/awardee-resolver.service";
+import { YearResolverService } from "./shared/year-resolver.service";
const routes: Routes = [
{
path: 'awardees',
- component: AwardeeListComponent
+ component: AwardeeListComponent,
+ resolve: {
+ awardees: AwardeeService,
+ }
// canActivate: [AuthGuardService, RoleGuardService],
}, {
path: 'awardee/new',
- component: AwardeeEditorComponent
+ component: AwardeeEditorComponent,
+ resolve: {
+ years: YearResolverService,
+ }
+ // canActivate: [AuthGuardService, RoleGuardService],
+ }, {
+ path: 'awardee/edit/:id',
+ component: AwardeeEditorComponent,
+ resolve: {
+ awardee: AwardeeResolverService,
+ years: YearResolverService,
+ }
// canActivate: [AuthGuardService, RoleGuardService],
}, {
path: 'judges',
@@ -25,7 +43,14 @@ const routes: Routes = [
// canActivate: [AuthGuardService, RoleGuardService],
}, {
path: 'judge/new',
- component: JudgeEditorComponent
+ component: JudgeEditorComponent,
+ // canActivate: [AuthGuardService, RoleGuardService],
+ }, {
+ path: 'judge/edit/:id',
+ component: JudgeEditorComponent,
+ resolve: {
+ judge: JudgeResolverService,
+ }
// canActivate: [AuthGuardService, RoleGuardService],
}
];
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index e8778a2..c6ad88b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -17,6 +17,11 @@ import {
MatInputModule,
MatSelectModule,
MatOptionModule,
+ MatCardModule,
+ MatRadioModule,
+ MatExpansionModule,
+ MatTooltipModule,
+ MatDialogModule,
} from '@angular/material';
import { AppRoutingModule } from './app-routing.module';
@@ -28,6 +33,7 @@ import { JudgeListTableComponent } from './judge-list-table/judge-list-table.com
import { AwardeeListTableComponent } from './awardee-list-table/awardee-list-table.component';
import { AwardeeEditorComponent } from './awardee-editor/awardee-editor.component';
import { JudgeEditorComponent } from './judge-editor/judge-editor.component';
+import { ConfirmDialogComponent } from './confirm-dialog/confirm-dialog.component';
@NgModule({
declarations: [
@@ -38,7 +44,11 @@ import { JudgeEditorComponent } from './judge-editor/judge-editor.component';
JudgeListTableComponent,
AwardeeListTableComponent,
AwardeeEditorComponent,
- JudgeEditorComponent
+ JudgeEditorComponent,
+ ConfirmDialogComponent,
+ ],
+ entryComponents: [
+ ConfirmDialogComponent,
],
imports: [
BrowserModule,
@@ -59,6 +69,11 @@ import { JudgeEditorComponent } from './judge-editor/judge-editor.component';
MatInputModule,
MatSelectModule,
MatOptionModule,
+ MatCardModule,
+ MatRadioModule,
+ MatExpansionModule,
+ MatTooltipModule,
+ MatDialogModule,
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/awardee-editor/awardee-editor.component.html b/src/app/awardee-editor/awardee-editor.component.html
index 0625fd8..1cc0ff6 100644
--- a/src/app/awardee-editor/awardee-editor.component.html
+++ b/src/app/awardee-editor/awardee-editor.component.html
@@ -1,6 +1,6 @@
-
diff --git a/src/app/awardee-editor/awardee-editor.component.ts b/src/app/awardee-editor/awardee-editor.component.ts
index 35de04a..5d463a9 100644
--- a/src/app/awardee-editor/awardee-editor.component.ts
+++ b/src/app/awardee-editor/awardee-editor.component.ts
@@ -1,6 +1,9 @@
import { Component, OnInit } from '@angular/core';
-import { YearService } from "../shared/year.service";
import { Title } from "@angular/platform-browser";
+import { ActivatedRoute, Router } from "@angular/router";
+
+import { Awardee } from "../shared/awardee";
+import { AwardeeService } from "../shared/awardee.service";
@Component({
selector: 'app-awardee-editor',
@@ -9,17 +12,38 @@ import { Title } from "@angular/platform-browser";
})
export class AwardeeEditorComponent implements OnInit {
+ public years: Array = [];
+ public awardee: Awardee;
+
constructor(
- private yearProvider: YearService,
- private titleService: Title
+ private titleService: Title,
+ private route: ActivatedRoute,
+ private router: Router,
+ private awardeeService: AwardeeService,
) {}
ngOnInit() {
this.titleService.setTitle('Edit awardee');
+ this.route.data.subscribe((data: {
+ years: Array,
+ awardee: Awardee,
+ }) => {
+ this.years = data.years ? data.years : [];
+ this.awardee = data.awardee ? data.awardee : new Awardee();
+ });
}
- get years(): Array {
- return this.yearProvider.years;
+ public saveAwardee() {
+ if (this.canSave) {
+ this.awardeeService.persist(this.awardee).subscribe(() => this.router.navigate(['/awardees']));
+ }
}
+ get canSave(): boolean {
+ return [
+ this.awardee.name,
+ this.awardee.text,
+ this.awardee.imageLabel].every(textField => textField.length > 0)
+ && this.awardee.year !== null;
+ }
}
diff --git a/src/app/awardee-list-table/awardee-list-table-datasource.ts b/src/app/awardee-list-table/awardee-list-table-datasource.ts
index 4bdf537..82bcadb 100644
--- a/src/app/awardee-list-table/awardee-list-table-datasource.ts
+++ b/src/app/awardee-list-table/awardee-list-table-datasource.ts
@@ -2,46 +2,21 @@ 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';
-
-// TODO: Replace this with your own data model type
-export interface AwardeeListTableItem {
- name: string;
- id: number;
-}
-
-// TODO: replace this with real data from your application
-const EXAMPLE_DATA: AwardeeListTableItem[] = [
- {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'},
-];
+import { AwardeeService } from "../shared/awardee.service";
+import { Awardee } from "../shared/awardee";
/**
* Data source for the AwardeeListTable view. This class should
* encapsulate all logic for fetching and manipulating the displayed data
* (including sorting, pagination, and filtering).
*/
-export class AwardeeListTableDataSource extends DataSource {
- data: AwardeeListTableItem[] = EXAMPLE_DATA;
+export class AwardeeListTableDataSource extends DataSource {
- constructor(private paginator: MatPaginator, private sort: MatSort) {
+ constructor(
+ private paginator: MatPaginator,
+ private sort: MatSort,
+ private awardeeService: AwardeeService
+ ) {
super();
}
@@ -50,20 +25,21 @@ export class AwardeeListTableDataSource 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.awardeeService.awardees),
+ this.awardeeService.changed,
this.paginator.page,
this.sort.sortChange
];
// Set the paginators length
- this.paginator.length = this.data.length;
+ this.paginator.length = this.awardeeService.awardees.length;
return merge(...dataMutations).pipe(map(() => {
- return this.getPagedData(this.getSortedData([...this.data]));
+ return this.getPagedData(this.getSortedData([...this.awardeeService.awardees]));
}));
}
@@ -77,7 +53,7 @@ export class AwardeeListTableDataSource 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: AwardeeListTableItem[]) {
+ private getPagedData(data: Awardee[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
return data.splice(startIndex, this.paginator.pageSize);
}
@@ -86,7 +62,7 @@ export class AwardeeListTableDataSource 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: AwardeeListTableItem[]) {
+ private getSortedData(data: Awardee[]) {
if (!this.sort.active || this.sort.direction === '') {
return data;
}
@@ -95,7 +71,6 @@ export class AwardeeListTableDataSource extends DataSource
const isAsc = this.sort.direction === 'asc';
switch (this.sort.active) {
case 'name': return compare(a.name, b.name, isAsc);
- case 'id': return compare(+a.id, +b.id, isAsc);
default: return 0;
}
});
diff --git a/src/app/awardee-list-table/awardee-list-table.component.css b/src/app/awardee-list-table/awardee-list-table.component.css
index d4a9b17..d3f73aa 100644
--- a/src/app/awardee-list-table/awardee-list-table.component.css
+++ b/src/app/awardee-list-table/awardee-list-table.component.css
@@ -2,3 +2,7 @@
display: block;
margin-top: 20px;
}
+
+.mat-column-buttons {
+ flex: 0 0 100px;
+}
diff --git a/src/app/awardee-list-table/awardee-list-table.component.html b/src/app/awardee-list-table/awardee-list-table.component.html
index 1105442..050e493 100644
--- a/src/app/awardee-list-table/awardee-list-table.component.html
+++ b/src/app/awardee-list-table/awardee-list-table.component.html
@@ -1,26 +1,39 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
- Id
- {{row.id}}
-
+
+
+ Name
+ {{row.name}}
+
-
-
- Name
- {{row.name}}
-
+
+
+ Year
+ {{row.year}}
+
-
-
-
+
+
+
-
-
+
+
\ No newline at end of file
diff --git a/src/app/awardee-list-table/awardee-list-table.component.ts b/src/app/awardee-list-table/awardee-list-table.component.ts
index d4aa2e2..239d48d 100644
--- a/src/app/awardee-list-table/awardee-list-table.component.ts
+++ b/src/app/awardee-list-table/awardee-list-table.component.ts
@@ -1,6 +1,9 @@
import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatPaginator, MatSort } from '@angular/material';
+import { MatDialog, MatPaginator, MatSort } from '@angular/material';
import { AwardeeListTableDataSource } from './awardee-list-table-datasource';
+import { AwardeeService } from "../shared/awardee.service";
+import { Awardee } from "../shared/awardee";
+import { ConfirmDialogComponent } from "../confirm-dialog/confirm-dialog.component";
@Component({
selector: 'awardee-list-table',
@@ -13,9 +16,39 @@ export class AwardeeListTableComponent implements OnInit {
dataSource: AwardeeListTableDataSource;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
- displayedColumns = ['id', 'name'];
+ displayedColumns = ['buttons', 'name', 'year'];
+
+ constructor(
+ private awardeeService: AwardeeService,
+ private dialog: MatDialog,
+ ) {}
ngOnInit() {
- this.dataSource = new AwardeeListTableDataSource(this.paginator, this.sort);
+ this.dataSource = new AwardeeListTableDataSource(this.paginator, this.sort, this.awardeeService);
+ }
+
+ get awardees(): Array {
+ return this.awardeeService.awardees;
+ }
+
+ public deleteAwardee(awardee: Awardee) {
+ let dialogRef = this.dialog.open(ConfirmDialogComponent, {
+ width: '300px',
+ data: {
+ question: `This will delete ${awardee.name}`,
+ }
+ });
+
+ let idx = this.awardees.indexOf(awardee);
+ dialogRef.afterClosed().subscribe(
+ dialogResult => dialogResult ? this.awardeeService.delete(awardee.id).subscribe(
+ result => {
+ if (result) {
+ this.awardees.splice(idx, 1);
+ this.awardeeService.triggerChange();
+ }
+ }
+ ) : false
+ )
}
}
diff --git a/src/app/awardee-list/awardee-list.component.ts b/src/app/awardee-list/awardee-list.component.ts
index 9df6664..26e4de0 100644
--- a/src/app/awardee-list/awardee-list.component.ts
+++ b/src/app/awardee-list/awardee-list.component.ts
@@ -1,5 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { Title } from "@angular/platform-browser";
+import { ActivatedRoute } from "@angular/router";
+
+import { Awardee } from "../shared/awardee";
+import { AwardeeService } from "../shared/awardee.service";
@Component({
selector: 'app-awardee-list',
@@ -9,11 +13,17 @@ import { Title } from "@angular/platform-browser";
export class AwardeeListComponent implements OnInit {
constructor(
- private titleService: Title
+ private titleService: Title,
+ private route: ActivatedRoute,
+ private awardeeService: AwardeeService,
) { }
ngOnInit() {
this.titleService.setTitle('Awardee list');
+ this.route.data.subscribe((data: {
+ awardees: Array,
+ }) => {
+ this.awardeeService.awardees = data.awardees;
+ });
}
-
}
diff --git a/src/app/confirm-dialog/confirm-dialog.component.css b/src/app/confirm-dialog/confirm-dialog.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/confirm-dialog/confirm-dialog.component.html b/src/app/confirm-dialog/confirm-dialog.component.html
new file mode 100644
index 0000000..08b6433
--- /dev/null
+++ b/src/app/confirm-dialog/confirm-dialog.component.html
@@ -0,0 +1,6 @@
+Are you sure?
+{{data.question}}
+
+
+
+
diff --git a/src/app/confirm-dialog/confirm-dialog.component.spec.ts b/src/app/confirm-dialog/confirm-dialog.component.spec.ts
new file mode 100644
index 0000000..ccea433
--- /dev/null
+++ b/src/app/confirm-dialog/confirm-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConfirmDialogComponent } from './confirm-dialog.component';
+
+describe('ConfirmDialogComponent', () => {
+ let component: ConfirmDialogComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ConfirmDialogComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfirmDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/confirm-dialog/confirm-dialog.component.ts b/src/app/confirm-dialog/confirm-dialog.component.ts
new file mode 100644
index 0000000..d057f35
--- /dev/null
+++ b/src/app/confirm-dialog/confirm-dialog.component.ts
@@ -0,0 +1,15 @@
+import { Component, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material";
+
+@Component({
+ selector: 'app-confirm-dialog',
+ templateUrl: './confirm-dialog.component.html',
+ styleUrls: ['./confirm-dialog.component.css']
+})
+export class ConfirmDialogComponent{
+
+ constructor(
+ public dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public data: {question: string}
+ ) {}
+}
diff --git a/src/app/judge-editor/judge-editor.component.css b/src/app/judge-editor/judge-editor.component.css
index 1cd63ef..936f0c2 100644
--- a/src/app/judge-editor/judge-editor.component.css
+++ b/src/app/judge-editor/judge-editor.component.css
@@ -17,11 +17,15 @@
margin-right: 20px;
}
-button + mat-divider {
+mat-divider {
margin-top: 10px;
margin-bottom: 10px;
}
-.title-table {
- margin-bottom: 20px;
+.save-button {
+ margin-top: 20px;
+}
+
+.mat-radio-button + .mat-radio-button {
+ margin-left: 20px;
}
diff --git a/src/app/judge-editor/judge-editor.component.html b/src/app/judge-editor/judge-editor.component.html
index 26f634d..0a70c91 100644
--- a/src/app/judge-editor/judge-editor.component.html
+++ b/src/app/judge-editor/judge-editor.component.html
@@ -1,49 +1,67 @@
-
diff --git a/src/app/judge-editor/judge-editor.component.ts b/src/app/judge-editor/judge-editor.component.ts
index 6191730..9405e99 100644
--- a/src/app/judge-editor/judge-editor.component.ts
+++ b/src/app/judge-editor/judge-editor.component.ts
@@ -1,11 +1,10 @@
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 { ActivatedRoute, Router } from "@angular/router";
import { Judge } from "../shared/judge";
import { JudgeService } from "../shared/judge.service";
+import { JudgeTitle } from "../shared/judge-title";
@Component({
selector: 'app-judge-editor',
@@ -13,63 +12,54 @@ import { JudgeService } from "../shared/judge.service";
styleUrls: ['./judge-editor.component.css']
})
export class JudgeEditorComponent implements OnInit {
- @ViewChild(MatTable) private table;
+ @ViewChild(MatTable) private table: MatTable>;
- public judgedYearInput: JudgedYear = new JudgedYear();
+ public judgedYearInput: JudgeTitle = new JudgeTitle();
public displayedColumns = ['buttons', 'year', 'title'];
- public judge = {
- yearlyData: [
- {
- year: 2013,
- title: 'Something something dark side',
- }
- ]
- };
+ public judge: Judge = new Judge();
constructor(
- private yearProvider: YearService,
private judgeService: JudgeService,
private titleService: Title,
- private route: ActivatedRoute
+ private route: ActivatedRoute,
+ private router: Router
) {}
ngOnInit() {
this.titleService.setTitle('Edit judge');
this.route.data.subscribe((data: {
- judges: Array,
+ judge: Judge,
}) => {
- this.judges = data.judges;
+ this.judge = data.judge ? data.judge : new Judge();
});
}
- 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;
}
+ get canSave(): boolean {
+ return this.judge.name.trim().length > 0;
+ }
+
public addToYear() {
let appendable = Object.assign({}, this.judgedYearInput);
- this.judge.yearlyData.push(appendable);
- this.judgedYearInput = new JudgedYear();
- this.table.renderRows();
+ this.judge.titles.push(appendable);
+ this.judgedYearInput = new JudgeTitle();
+ if (this.table) { this.table.renderRows(); }
}
public removeFromYear(year: number) {
- this.judge.yearlyData = this.judge.yearlyData.filter(
+ this.judge.titles = this.judge.titles.filter(
row => row.year !== year
);
}
+
+ public saveJudge() {
+ if (this.canSave) {
+ this.judgeService.persist(this.judge).subscribe(() => this.router.navigate(['/judges']));
+ }
+ }
}
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 ae65ed1..fb0950d 100644
--- a/src/app/judge-list-table/judge-list-table-datasource.ts
+++ b/src/app/judge-list-table/judge-list-table-datasource.ts
@@ -5,7 +5,6 @@ import { Observable, of as observableOf, merge } from 'rxjs';
import { JudgeService } from "../shared/judge.service";
import { Judge } from "../shared/judge";
-
/**
* Data source for the JudgeListTable view. This class should
* encapsulate all logic for fetching and manipulating the displayed data
@@ -31,6 +30,7 @@ export class JudgeListTableDataSource extends DataSource {
// stream for the data-table to consume.
const dataMutations = [
observableOf(this.judgeService.judges),
+ this.judgeService.changed,
this.paginator.page,
this.sort.sortChange
];
@@ -71,7 +71,6 @@ export class JudgeListTableDataSource extends DataSource {
const isAsc = this.sort.direction === 'asc';
switch (this.sort.active) {
case 'name': return compare(a.name, b.name, isAsc);
- case 'id': return compare(+a.id, +b.id, isAsc);
default: return 0;
}
});
diff --git a/src/app/judge-list-table/judge-list-table.component.css b/src/app/judge-list-table/judge-list-table.component.css
index d4a9b17..d3f73aa 100644
--- a/src/app/judge-list-table/judge-list-table.component.css
+++ b/src/app/judge-list-table/judge-list-table.component.css
@@ -2,3 +2,7 @@
display: block;
margin-top: 20px;
}
+
+.mat-column-buttons {
+ flex: 0 0 100px;
+}
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 f023ccc..8c93e66 100644
--- a/src/app/judge-list-table/judge-list-table.component.html
+++ b/src/app/judge-list-table/judge-list-table.component.html
@@ -1,26 +1,43 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
- Id
- {{row.id}}
-
+
+
+ Name
+ {{row.prefix}}{{row.name}}
+
-
-
- Name
- {{row.name}}
-
+
+ Active years
+ {{getJudgedYears(row.titles)}}
+
-
-
-
+
+ Latest title
+ {{getLatestTitle(row.titles)}}
+
-
-
+
+
+
+
+
+
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 e844ff4..91fa9ed 100644
--- a/src/app/judge-list-table/judge-list-table.component.ts
+++ b/src/app/judge-list-table/judge-list-table.component.ts
@@ -1,8 +1,10 @@
import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatPaginator, MatSort } from '@angular/material';
+import { MatDialog, MatPaginator, MatSort } from '@angular/material';
import { JudgeListTableDataSource } from './judge-list-table-datasource';
import { JudgeService } from "../shared/judge.service";
import { Judge } from "../shared/judge";
+import { JudgeTitle } from "../shared/judge-title";
+import { ConfirmDialogComponent } from "../confirm-dialog/confirm-dialog.component";
@Component({
selector: 'judge-list-table',
@@ -15,9 +17,12 @@ export class JudgeListTableComponent implements OnInit {
dataSource: JudgeListTableDataSource;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
- displayedColumns = ['id', 'name'];
+ displayedColumns = ['buttons', 'name', 'years', 'title'];
- constructor(private judgeService: JudgeService) {}
+ constructor(
+ private judgeService: JudgeService,
+ private dialog: MatDialog,
+ ) {}
ngOnInit() {
this.dataSource = new JudgeListTableDataSource(this.paginator, this.sort, this.judgeService);
@@ -26,4 +31,33 @@ export class JudgeListTableComponent implements OnInit {
get judges(): Array {
return this.judgeService.judges;
}
+
+ public getJudgedYears(titles: Array): string {
+ return titles.map(title => title.year).join(', ');
+ }
+
+ public getLatestTitle(titles: Array): string {
+ return titles.length ? titles.reduce((item, last) => item.year > last.year ? item : last).title : '';
+ }
+
+ public deleteJudge(judge: Judge) {
+ let dialogRef = this.dialog.open(ConfirmDialogComponent, {
+ width: '300px',
+ data: {
+ question: `This will delete ${judge.name}`,
+ }
+ });
+
+ let idx = this.judges.indexOf(judge);
+ dialogRef.afterClosed().subscribe(
+ dialogResult => dialogResult ? this.judgeService.delete(judge.id).subscribe(
+ result => {
+ if (result) {
+ this.judgeService.judges.splice(idx, 1);
+ this.judgeService.triggerChange();
+ }
+ }
+ ) : false
+ )
+ }
}
diff --git a/src/app/judge-list/judge-list.component.ts b/src/app/judge-list/judge-list.component.ts
index 98a36a3..d67dea6 100644
--- a/src/app/judge-list/judge-list.component.ts
+++ b/src/app/judge-list/judge-list.component.ts
@@ -1,7 +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 { Judge } from "../shared/judge";
import { JudgeService } from "../shared/judge.service";
@Component({
@@ -14,15 +15,15 @@ export class JudgeListComponent implements OnInit {
constructor(
private judgeService: JudgeService,
private titleService: Title,
- private route: ActivatedRoute
+ private route: ActivatedRoute,
) { }
ngOnInit() {
this.titleService.setTitle('Judge list');
- this.route.data.subscribe((data: {
- judges: Array,
- }) => {
- this.judgeService.judges = data.judges;
- });
+ this.route.data.subscribe((data: {
+ judges: Array,
+ }) => {
+ this.judgeService.judges = data.judges;
+ });
}
}
diff --git a/src/app/shared/awardee-resolver.service.spec.ts b/src/app/shared/awardee-resolver.service.spec.ts
new file mode 100644
index 0000000..108b895
--- /dev/null
+++ b/src/app/shared/awardee-resolver.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { AwardeeResolverService } from './awardee-resolver.service';
+
+describe('AwardeeResolverService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [AwardeeResolverService]
+ });
+ });
+
+ it('should be created', inject([AwardeeResolverService], (service: AwardeeResolverService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/src/app/shared/awardee-resolver.service.ts b/src/app/shared/awardee-resolver.service.ts
new file mode 100644
index 0000000..2f9f463
--- /dev/null
+++ b/src/app/shared/awardee-resolver.service.ts
@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from "@angular/router";
+import { HttpClient } from "@angular/common/http";
+import { Observable } from "rxjs/internal/Observable";
+
+import { environment } from "../../environments/environment";
+import { Awardee } from "./awardee";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AwardeeResolverService implements Resolve {
+
+ private apiEndPoint = `${environment.apiUrl}/awardee`;
+
+ constructor(private httpClient: HttpClient) {}
+
+ public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
+ return this.httpClient.get(`${this.apiEndPoint}/${route.params['id']}`);
+ }
+}
diff --git a/src/app/shared/awardee.service.spec.ts b/src/app/shared/awardee.service.spec.ts
new file mode 100644
index 0000000..7811cbb
--- /dev/null
+++ b/src/app/shared/awardee.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { AwardeeService } from './awardee.service';
+
+describe('AwardeeService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [AwardeeService]
+ });
+ });
+
+ it('should be created', inject([AwardeeService], (service: AwardeeService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/src/app/shared/awardee.service.ts b/src/app/shared/awardee.service.ts
new file mode 100644
index 0000000..8efde7c
--- /dev/null
+++ b/src/app/shared/awardee.service.ts
@@ -0,0 +1,59 @@
+import { EventEmitter, Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from "@angular/router";
+import { HttpClient } from "@angular/common/http";
+import { Observable } from "rxjs/internal/Observable";
+
+import { environment } from "../../environments/environment";
+import { Awardee } from "./awardee";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AwardeeService implements Resolve> {
+
+ private apiEndPoint = `${environment.apiUrl}/awardee`;
+ private cachedAwardees: Array = [];
+
+ public changed: EventEmitter> = new EventEmitter>();
+
+ 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 awardees(): Array {
+ return this.cachedAwardees;
+ }
+
+ set awardees(judges: Array) {
+ this.cachedAwardees = judges;
+ this.triggerChange();
+ }
+
+ public triggerChange() {
+ this.changed.emit(this.cachedAwardees);
+ }
+
+ public persist(judge: Awardee): Observable {
+ return judge.id === null
+ ? this.create(judge)
+ : this.update(judge);
+ }
+
+ public create(awardee: Awardee): Observable {
+ return this.httpClient.post(this.apiEndPoint, awardee);
+ }
+
+ public update(awardee: Awardee): Observable {
+ return this.httpClient.put(`${this.apiEndPoint}/${awardee.id}`, awardee);
+ }
+
+ public delete(id: number): Observable {
+ return this.httpClient.delete(`${this.apiEndPoint}/${id}`);
+ }
+}
diff --git a/src/app/shared/awardee.ts b/src/app/shared/awardee.ts
new file mode 100644
index 0000000..5f9cb7b
--- /dev/null
+++ b/src/app/shared/awardee.ts
@@ -0,0 +1,7 @@
+export class Awardee {
+ public id: number = null;
+ public year: number = null;
+ public name: string = '';
+ public text: string = '';
+ public imageLabel: string = '';
+}
diff --git a/src/app/shared/judge-resolver.service.spec.ts b/src/app/shared/judge-resolver.service.spec.ts
new file mode 100644
index 0000000..f890c41
--- /dev/null
+++ b/src/app/shared/judge-resolver.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { JudgeResolverService } from './judge-resolver.service';
+
+describe('JudgeResolverService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [JudgeResolverService]
+ });
+ });
+
+ it('should be created', inject([JudgeResolverService], (service: JudgeResolverService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/src/app/shared/judge-resolver.service.ts b/src/app/shared/judge-resolver.service.ts
new file mode 100644
index 0000000..f94b868
--- /dev/null
+++ b/src/app/shared/judge-resolver.service.ts
@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from "@angular/router";
+import { HttpClient } from "@angular/common/http";
+import { Observable } from "rxjs/internal/Observable";
+
+import { environment } from "../../environments/environment";
+import { Judge } from "./judge";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class JudgeResolverService implements Resolve {
+
+ private apiEndPoint = `${environment.apiUrl}/judge`;
+
+ constructor(private httpClient: HttpClient) {}
+
+ public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
+ return this.httpClient.get(`${this.apiEndPoint}/${route.params['id']}`);
+ }
+}
diff --git a/src/app/shared/judge-title.ts b/src/app/shared/judge-title.ts
index e15ff6d..1870d93 100644
--- a/src/app/shared/judge-title.ts
+++ b/src/app/shared/judge-title.ts
@@ -1,5 +1,5 @@
export class JudgeTitle {
- id: number;
- year: number;
- title: string;
+ id: number = null;
+ year: number = null;
+ title: string = '';
}
diff --git a/src/app/shared/judge.service.ts b/src/app/shared/judge.service.ts
index 84069f0..1dc0dcf 100644
--- a/src/app/shared/judge.service.ts
+++ b/src/app/shared/judge.service.ts
@@ -1,11 +1,11 @@
-import { Injectable } from '@angular/core';
+import { EventEmitter, 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";
+import { environment } from '../../environments/environment';
+import { Judge } from "./judge";
+
@Injectable({
providedIn: 'root'
})
@@ -14,6 +14,8 @@ export class JudgeService implements Resolve> {
private apiEndPoint = `${environment.apiUrl}/judge`;
private cachedJudges: Array = [];
+ public changed: EventEmitter> = new EventEmitter>();
+
constructor(private httpClient: HttpClient) {}
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise> {
@@ -30,5 +32,28 @@ export class JudgeService implements Resolve> {
set judges(judges: Array) {
this.cachedJudges = judges;
+ this.triggerChange();
+ }
+
+ public triggerChange() {
+ this.changed.emit(this.cachedJudges);
+ }
+
+ public persist(judge: Judge): Observable {
+ return judge.id === null
+ ? this.create(judge)
+ : this.update(judge);
+ }
+
+ public create(judge: Judge): Observable {
+ return this.httpClient.post(this.apiEndPoint, judge);
+ }
+
+ public update(judge: Judge): Observable {
+ return this.httpClient.put(`${this.apiEndPoint}/${judge.id}`, judge);
+ }
+
+ public delete(id: number): Observable {
+ return this.httpClient.delete(`${this.apiEndPoint}/${id}`);
}
}
diff --git a/src/app/shared/judge.ts b/src/app/shared/judge.ts
index ec3b41c..58eb113 100644
--- a/src/app/shared/judge.ts
+++ b/src/app/shared/judge.ts
@@ -1,7 +1,8 @@
import { JudgeTitle } from "./judge-title";
export class Judge {
- public id: number;
- public name: string;
- public titles: Array;
+ public id: number = null;
+ public prefix: string = null;
+ public name: string = '';
+ public titles: Array = [];
}
diff --git a/src/app/shared/judged-year.ts b/src/app/shared/judged-year.ts
deleted file mode 100644
index 9d5ac02..0000000
--- a/src/app/shared/judged-year.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export class JudgedYear {
- public year: number = null;
- public title = '';
-}
diff --git a/src/app/shared/year-resolver.service.spec.ts b/src/app/shared/year-resolver.service.spec.ts
new file mode 100644
index 0000000..4263a8e
--- /dev/null
+++ b/src/app/shared/year-resolver.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { YearResolverService } from './year-resolver.service';
+
+describe('YearResolverService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [YearResolverService]
+ });
+ });
+
+ it('should be created', inject([YearResolverService], (service: YearResolverService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/src/app/shared/year-resolver.service.ts b/src/app/shared/year-resolver.service.ts
new file mode 100644
index 0000000..90ba544
--- /dev/null
+++ b/src/app/shared/year-resolver.service.ts
@@ -0,0 +1,19 @@
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from "@angular/router";
+import { HttpClient } from "@angular/common/http";
+import { Observable } from "rxjs/internal/Observable";
+
+import { environment } from "../../environments/environment";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class YearResolverService implements Resolve> {
+ private apiEndPoint = `${environment.apiUrl}/years`;
+
+ constructor(private httpClient: HttpClient) {}
+
+ public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> {
+ return this.httpClient.get>(this.apiEndPoint);
+ }
+}