* initial commit
This commit is contained in:
parent
bc4fb64f59
commit
699753fc23
@ -23,6 +23,12 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
{
|
||||||
|
"input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css"
|
||||||
|
},
|
||||||
|
"node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-solid.css",
|
||||||
|
"node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-regular.css",
|
||||||
|
"node_modules/@fortawesome/fontawesome-free-webfonts/css/fontawesome.css",
|
||||||
"src/styles.css"
|
"src/styles.css"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
@ -72,6 +78,9 @@
|
|||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
"karmaConfig": "src/karma.conf.js",
|
"karmaConfig": "src/karma.conf.js",
|
||||||
"styles": [
|
"styles": [
|
||||||
|
{
|
||||||
|
"input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css"
|
||||||
|
},
|
||||||
"styles.css"
|
"styles.css"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
|
|||||||
21
package-lock.json
generated
21
package-lock.json
generated
@ -115,6 +115,14 @@
|
|||||||
"tslib": "1.9.0"
|
"tslib": "1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@angular/cdk": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-f8WAY/PC4etTWhtPDuu5zRy+5+qUWSnW+6PidfYAHHdVGu+90H8qIKA27VOW/RWk+oZnl2SC2LVg4G7hggio+A==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular/cli": {
|
"@angular/cli": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.0.0.tgz",
|
||||||
@ -352,6 +360,14 @@
|
|||||||
"integrity": "sha512-ysNUM8uec9Kf5Te5HBT6b3G5CLlxOKAXtk+bY1sqbE9sMDZFWQhqR66QzfWdOPRyj9KKrwuKZd9ArMjAbOVNYw==",
|
"integrity": "sha512-ysNUM8uec9Kf5Te5HBT6b3G5CLlxOKAXtk+bY1sqbE9sMDZFWQhqR66QzfWdOPRyj9KKrwuKZd9ArMjAbOVNYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@angular/material": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/material/-/material-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-QbAFoE3wruv/XsAKJirGn0fSfmVIBMCrtGe55hZjOVhvRbrnXJ61VSr4zrO/LDPzT17yXhf3ZaB3Yp/4GmRk8w==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular/platform-browser": {
|
"@angular/platform-browser": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.0.0.tgz",
|
||||||
@ -376,6 +392,11 @@
|
|||||||
"tslib": "1.9.0"
|
"tslib": "1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@fortawesome/fontawesome-free-webfonts": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-webfonts/-/fontawesome-free-webfonts-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-pAeqqnpH2+uuUdSZJ0vmEtmtKhiatebzIrl4VDMPiB0lXkp2E+vFypp8MDTZhu7gF5XzdZRD0CCAwKz16u/x6Q=="
|
||||||
|
},
|
||||||
"@ngtools/webpack": {
|
"@ngtools/webpack": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.0.0.tgz",
|
||||||
|
|||||||
@ -12,14 +12,17 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^6.0.0",
|
"@angular/animations": "^6.0.0",
|
||||||
|
"@angular/cdk": "^6.0.0",
|
||||||
"@angular/common": "^6.0.0",
|
"@angular/common": "^6.0.0",
|
||||||
"@angular/compiler": "^6.0.0",
|
"@angular/compiler": "^6.0.0",
|
||||||
"@angular/core": "^6.0.0",
|
"@angular/core": "^6.0.0",
|
||||||
"@angular/forms": "^6.0.0",
|
"@angular/forms": "^6.0.0",
|
||||||
"@angular/http": "^6.0.0",
|
"@angular/http": "^6.0.0",
|
||||||
|
"@angular/material": "^6.0.1",
|
||||||
"@angular/platform-browser": "^6.0.0",
|
"@angular/platform-browser": "^6.0.0",
|
||||||
"@angular/platform-browser-dynamic": "^6.0.0",
|
"@angular/platform-browser-dynamic": "^6.0.0",
|
||||||
"@angular/router": "^6.0.0",
|
"@angular/router": "^6.0.0",
|
||||||
|
"@fortawesome/fontawesome-free-webfonts": "^1.0.8",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
"rxjs": "^6.0.0",
|
"rxjs": "^6.0.0",
|
||||||
"zone.js": "^0.8.26"
|
"zone.js": "^0.8.26"
|
||||||
|
|||||||
@ -1,10 +1,33 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
const routes: Routes = [];
|
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";
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'awardees',
|
||||||
|
component: AwardeeListComponent
|
||||||
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
|
}, {
|
||||||
|
path: 'awardee/new',
|
||||||
|
component: AwardeeEditorComponent
|
||||||
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
|
}, {
|
||||||
|
path: 'judges',
|
||||||
|
component: JudgeListComponent
|
||||||
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
|
}, {
|
||||||
|
path: 'judge/new',
|
||||||
|
component: JudgeEditorComponent
|
||||||
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class AppRoutingModule { }
|
export class AppRoutingModule {}
|
||||||
|
|||||||
@ -1,21 +1,3 @@
|
|||||||
<!--The content below is only a placeholder and can be replaced.-->
|
<app-navigation>
|
||||||
<div style="text-align:center">
|
<router-outlet></router-outlet>
|
||||||
<h1>
|
</app-navigation>
|
||||||
Welcome to {{ title }}!
|
|
||||||
</h1>
|
|
||||||
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
|
|
||||||
</div>
|
|
||||||
<h2>Here are some links to help you start: </h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
|
|||||||
@ -5,6 +5,4 @@ import { Component } from '@angular/core';
|
|||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {}
|
||||||
title = 'app';
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,16 +1,60 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { LayoutModule } from '@angular/cdk/layout';
|
||||||
|
import {
|
||||||
|
MatToolbarModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatSidenavModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatListModule,
|
||||||
|
MatTableModule,
|
||||||
|
MatPaginatorModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
|
} from '@angular/material';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { NavigationComponent } from './navigation/navigation.component';
|
||||||
|
import { AwardeeListComponent } from './awardee-list/awardee-list.component';
|
||||||
|
import { JudgeListComponent } from './judge-list/judge-list.component';
|
||||||
|
import { JudgeListTableComponent } from './judge-list-table/judge-list-table.component';
|
||||||
|
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';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent
|
AppComponent,
|
||||||
|
NavigationComponent,
|
||||||
|
AwardeeListComponent,
|
||||||
|
JudgeListComponent,
|
||||||
|
JudgeListTableComponent,
|
||||||
|
AwardeeListTableComponent,
|
||||||
|
AwardeeEditorComponent,
|
||||||
|
JudgeEditorComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule
|
AppRoutingModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
LayoutModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatSidenavModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatListModule,
|
||||||
|
MatTableModule,
|
||||||
|
MatPaginatorModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
19
src/app/awardee-editor/awardee-editor.component.css
Normal file
19
src/app/awardee-editor/awardee-editor.component.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.awardee-form {
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button + mat-divider {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
33
src/app/awardee-editor/awardee-editor.component.html
Normal file
33
src/app/awardee-editor/awardee-editor.component.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<form class="awardee-form">
|
||||||
|
<mat-form-field class="full-width">
|
||||||
|
<input type="text" matInput placeholder="Display name">
|
||||||
|
</mat-form-field>
|
||||||
|
<button type="button" mat-raised-button>
|
||||||
|
<i class="far fa-image"></i>
|
||||||
|
Upload profile image
|
||||||
|
</button>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<mat-form-field class="full-width">
|
||||||
|
<mat-select placeholder="Year">
|
||||||
|
<mat-option *ngFor="let year of years" [value]="year">
|
||||||
|
{{ year }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field class="full-width">
|
||||||
|
<textarea matInput placeholder="Article text" rows="10"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
<button type="button" mat-raised-button>
|
||||||
|
<i class="far fa-image"></i> Upload article image
|
||||||
|
</button>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<mat-form-field class="full-width">
|
||||||
|
<input type="text" matInput placeholder="Image label">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<button type="submit" mat-raised-button color="accent">
|
||||||
|
<i class="fas fa-save"></i> Save
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
25
src/app/awardee-editor/awardee-editor.component.spec.ts
Normal file
25
src/app/awardee-editor/awardee-editor.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AwardeeEditorComponent } from './awardee-editor.component';
|
||||||
|
|
||||||
|
describe('AwardeeEditorComponent', () => {
|
||||||
|
let component: AwardeeEditorComponent;
|
||||||
|
let fixture: ComponentFixture<AwardeeEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AwardeeEditorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AwardeeEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
src/app/awardee-editor/awardee-editor.component.ts
Normal file
24
src/app/awardee-editor/awardee-editor.component.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-awardee-editor',
|
||||||
|
templateUrl: './awardee-editor.component.html',
|
||||||
|
styleUrls: ['./awardee-editor.component.css']
|
||||||
|
})
|
||||||
|
export class AwardeeEditorComponent implements OnInit {
|
||||||
|
|
||||||
|
public years: Array<number> = [
|
||||||
|
2018,
|
||||||
|
2017,
|
||||||
|
2016,
|
||||||
|
2015,
|
||||||
|
2014,
|
||||||
|
2013,
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
108
src/app/awardee-list-table/awardee-list-table-datasource.ts
Normal file
108
src/app/awardee-list-table/awardee-list-table-datasource.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
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'},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<AwardeeListTableItem> {
|
||||||
|
data: AwardeeListTableItem[] = EXAMPLE_DATA;
|
||||||
|
|
||||||
|
constructor(private paginator: MatPaginator, private sort: MatSort) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect this data source to the table. The table will only update when
|
||||||
|
* the returned stream emits new items.
|
||||||
|
* @returns A stream of the items to be rendered.
|
||||||
|
*/
|
||||||
|
connect(): Observable<AwardeeListTableItem[]> {
|
||||||
|
// Combine everything that affects the rendered data into one update
|
||||||
|
// stream for the data-table to consume.
|
||||||
|
const dataMutations = [
|
||||||
|
observableOf(this.data),
|
||||||
|
this.paginator.page,
|
||||||
|
this.sort.sortChange
|
||||||
|
];
|
||||||
|
|
||||||
|
// Set the paginators length
|
||||||
|
this.paginator.length = this.data.length;
|
||||||
|
|
||||||
|
return merge(...dataMutations).pipe(map(() => {
|
||||||
|
return this.getPagedData(this.getSortedData([...this.data]));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the table is being destroyed. Use this function, to clean up
|
||||||
|
* any open connections or free any held resources that were set up during connect.
|
||||||
|
*/
|
||||||
|
disconnect() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[]) {
|
||||||
|
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
|
||||||
|
return data.splice(startIndex, this.paginator.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[]) {
|
||||||
|
if (!this.sort.active || this.sort.direction === '') {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.sort((a, b) => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
|
||||||
|
function compare(a, b, isAsc) {
|
||||||
|
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
26
src/app/awardee-list-table/awardee-list-table.component.html
Normal file
26
src/app/awardee-list-table/awardee-list-table.component.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<div class="mat-elevation-z8">
|
||||||
|
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
|
||||||
|
|
||||||
|
<!-- Id Column -->
|
||||||
|
<ng-container matColumnDef="id">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.id}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Name Column -->
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||||
|
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||||
|
</mat-table>
|
||||||
|
|
||||||
|
<mat-paginator #paginator
|
||||||
|
[length]="dataSource.data.length"
|
||||||
|
[pageIndex]="0"
|
||||||
|
[pageSize]="50"
|
||||||
|
[pageSizeOptions]="[25, 50, 100, 250]">
|
||||||
|
</mat-paginator>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AwardeeListTableComponent } from './awardee-list-table.component';
|
||||||
|
|
||||||
|
describe('AwardeeListTableComponent', () => {
|
||||||
|
let component: AwardeeListTableComponent;
|
||||||
|
let fixture: ComponentFixture<AwardeeListTableComponent>;
|
||||||
|
|
||||||
|
beforeEach(fakeAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AwardeeListTableComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AwardeeListTableComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should compile', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
21
src/app/awardee-list-table/awardee-list-table.component.ts
Normal file
21
src/app/awardee-list-table/awardee-list-table.component.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { MatPaginator, MatSort } from '@angular/material';
|
||||||
|
import { AwardeeListTableDataSource } from './awardee-list-table-datasource';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'awardee-list-table',
|
||||||
|
templateUrl: './awardee-list-table.component.html',
|
||||||
|
styleUrls: ['./awardee-list-table.component.css']
|
||||||
|
})
|
||||||
|
export class AwardeeListTableComponent implements OnInit {
|
||||||
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
dataSource: AwardeeListTableDataSource;
|
||||||
|
|
||||||
|
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||||
|
displayedColumns = ['id', 'name'];
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.dataSource = new AwardeeListTableDataSource(this.paginator, this.sort);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/app/awardee-list/awardee-list.component.css
Normal file
4
src/app/awardee-list/awardee-list.component.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
5
src/app/awardee-list/awardee-list.component.html
Normal file
5
src/app/awardee-list/awardee-list.component.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<a class="mat-raised-button" [routerLink]="['/awardee/new']">
|
||||||
|
<mat-icon fontSet="fas" fontIcon="fa-user-plus"></mat-icon>
|
||||||
|
New awardee
|
||||||
|
</a>
|
||||||
|
<awardee-list-table></awardee-list-table>
|
||||||
25
src/app/awardee-list/awardee-list.component.spec.ts
Normal file
25
src/app/awardee-list/awardee-list.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AwardeeListComponent } from './awardee-list.component';
|
||||||
|
|
||||||
|
describe('AwardeeListComponent', () => {
|
||||||
|
let component: AwardeeListComponent;
|
||||||
|
let fixture: ComponentFixture<AwardeeListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AwardeeListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AwardeeListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
15
src/app/awardee-list/awardee-list.component.ts
Normal file
15
src/app/awardee-list/awardee-list.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-awardee-list',
|
||||||
|
templateUrl: './awardee-list.component.html',
|
||||||
|
styleUrls: ['./awardee-list.component.css']
|
||||||
|
})
|
||||||
|
export class AwardeeListComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
src/app/judge-editor/judge-editor.component.css
Normal file
29
src/app/judge-editor/judge-editor.component.css
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.judge-form {
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.half-width {
|
||||||
|
width: calc(50% - 10px);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.half-width:last-of-type {
|
||||||
|
width: calc(50%);
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button + mat-divider {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
38
src/app/judge-editor/judge-editor.component.html
Normal file
38
src/app/judge-editor/judge-editor.component.html
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<form class="judge-form">
|
||||||
|
<mat-form-field class="full-width">
|
||||||
|
<input type="text" matInput placeholder="Display name">
|
||||||
|
</mat-form-field>
|
||||||
|
<button type="button" mat-raised-button>
|
||||||
|
<i class="far fa-image"></i>
|
||||||
|
Upload profile image
|
||||||
|
</button>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
|
||||||
|
<mat-form-field class="half-width">
|
||||||
|
<input type="number" matInput placeholder="Year">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="half-width">
|
||||||
|
<input type="text" matInput placeholder="Title">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-table [dataSource]="judge.yearlyData">
|
||||||
|
<ng-container matColumnDef="year">
|
||||||
|
<mat-header-cell *matHeaderCellDef>Year</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.year}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Name Column -->
|
||||||
|
<ng-container matColumnDef="title">
|
||||||
|
<mat-header-cell *matHeaderCellDef>Title</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.title}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||||
|
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||||
|
</mat-table>
|
||||||
|
|
||||||
|
<button type="submit" mat-raised-button color="accent">
|
||||||
|
<i class="fas fa-save"></i> Save
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
25
src/app/judge-editor/judge-editor.component.spec.ts
Normal file
25
src/app/judge-editor/judge-editor.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { JudgeEditorComponent } from './judge-editor.component';
|
||||||
|
|
||||||
|
describe('JudgeEditorComponent', () => {
|
||||||
|
let component: JudgeEditorComponent;
|
||||||
|
let fixture: ComponentFixture<JudgeEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ JudgeEditorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(JudgeEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
25
src/app/judge-editor/judge-editor.component.ts
Normal file
25
src/app/judge-editor/judge-editor.component.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-judge-editor',
|
||||||
|
templateUrl: './judge-editor.component.html',
|
||||||
|
styleUrls: ['./judge-editor.component.css']
|
||||||
|
})
|
||||||
|
export class JudgeEditorComponent implements OnInit {
|
||||||
|
|
||||||
|
public displayedColumns = ['year', 'title'];
|
||||||
|
public judge = {
|
||||||
|
yearlyData: [
|
||||||
|
{
|
||||||
|
year: 2013,
|
||||||
|
title: 'Something something dark side',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
108
src/app/judge-list-table/judge-list-table-datasource.ts
Normal file
108
src/app/judge-list-table/judge-list-table-datasource.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
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 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<JudgeListTableItem> {
|
||||||
|
data: JudgeListTableItem[] = EXAMPLE_DATA;
|
||||||
|
|
||||||
|
constructor(private paginator: MatPaginator, private sort: MatSort) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect this data source to the table. The table will only update when
|
||||||
|
* the returned stream emits new items.
|
||||||
|
* @returns A stream of the items to be rendered.
|
||||||
|
*/
|
||||||
|
connect(): Observable<JudgeListTableItem[]> {
|
||||||
|
// Combine everything that affects the rendered data into one update
|
||||||
|
// stream for the data-table to consume.
|
||||||
|
const dataMutations = [
|
||||||
|
observableOf(this.data),
|
||||||
|
this.paginator.page,
|
||||||
|
this.sort.sortChange
|
||||||
|
];
|
||||||
|
|
||||||
|
// Set the paginators length
|
||||||
|
this.paginator.length = this.data.length;
|
||||||
|
|
||||||
|
return merge(...dataMutations).pipe(map(() => {
|
||||||
|
return this.getPagedData(this.getSortedData([...this.data]));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the table is being destroyed. Use this function, to clean up
|
||||||
|
* any open connections or free any held resources that were set up during connect.
|
||||||
|
*/
|
||||||
|
disconnect() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[]) {
|
||||||
|
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
|
||||||
|
return data.splice(startIndex, this.paginator.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[]) {
|
||||||
|
if (!this.sort.active || this.sort.direction === '') {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.sort((a, b) => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
|
||||||
|
function compare(a, b, isAsc) {
|
||||||
|
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||||
|
}
|
||||||
4
src/app/judge-list-table/judge-list-table.component.css
Normal file
4
src/app/judge-list-table/judge-list-table.component.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
26
src/app/judge-list-table/judge-list-table.component.html
Normal file
26
src/app/judge-list-table/judge-list-table.component.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<div class="mat-elevation-z8">
|
||||||
|
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
|
||||||
|
|
||||||
|
<!-- Id Column -->
|
||||||
|
<ng-container matColumnDef="id">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.id}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Name Column -->
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||||
|
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||||
|
</mat-table>
|
||||||
|
|
||||||
|
<mat-paginator #paginator
|
||||||
|
[length]="dataSource.data.length"
|
||||||
|
[pageIndex]="0"
|
||||||
|
[pageSize]="50"
|
||||||
|
[pageSizeOptions]="[25, 50, 100, 250]">
|
||||||
|
</mat-paginator>
|
||||||
|
</div>
|
||||||
24
src/app/judge-list-table/judge-list-table.component.spec.ts
Normal file
24
src/app/judge-list-table/judge-list-table.component.spec.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { JudgeListTableComponent } from './judge-list-table.component';
|
||||||
|
|
||||||
|
describe('JudgeListTableComponent', () => {
|
||||||
|
let component: JudgeListTableComponent;
|
||||||
|
let fixture: ComponentFixture<JudgeListTableComponent>;
|
||||||
|
|
||||||
|
beforeEach(fakeAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ JudgeListTableComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(JudgeListTableComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should compile', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
21
src/app/judge-list-table/judge-list-table.component.ts
Normal file
21
src/app/judge-list-table/judge-list-table.component.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { MatPaginator, MatSort } from '@angular/material';
|
||||||
|
import { JudgeListTableDataSource } from './judge-list-table-datasource';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'judge-list-table',
|
||||||
|
templateUrl: './judge-list-table.component.html',
|
||||||
|
styleUrls: ['./judge-list-table.component.css']
|
||||||
|
})
|
||||||
|
export class JudgeListTableComponent implements OnInit {
|
||||||
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
dataSource: JudgeListTableDataSource;
|
||||||
|
|
||||||
|
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||||
|
displayedColumns = ['id', 'name'];
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.dataSource = new JudgeListTableDataSource(this.paginator, this.sort);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/app/judge-list/judge-list.component.css
Normal file
4
src/app/judge-list/judge-list.component.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
5
src/app/judge-list/judge-list.component.html
Normal file
5
src/app/judge-list/judge-list.component.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<a class="mat-raised-button" [routerLink]="['/judge/new']">
|
||||||
|
<mat-icon fontSet="fas" fontIcon="fa-user-plus"></mat-icon>
|
||||||
|
New judge
|
||||||
|
</a>
|
||||||
|
<judge-list-table></judge-list-table>
|
||||||
25
src/app/judge-list/judge-list.component.spec.ts
Normal file
25
src/app/judge-list/judge-list.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { JudgeListComponent } from './judge-list.component';
|
||||||
|
|
||||||
|
describe('JudgeListComponent', () => {
|
||||||
|
let component: JudgeListComponent;
|
||||||
|
let fixture: ComponentFixture<JudgeListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ JudgeListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(JudgeListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
15
src/app/judge-list/judge-list.component.ts
Normal file
15
src/app/judge-list/judge-list.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-judge-list',
|
||||||
|
templateUrl: './judge-list.component.html',
|
||||||
|
styleUrls: ['./judge-list.component.css']
|
||||||
|
})
|
||||||
|
export class JudgeListComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
src/app/navigation/navigation.component.css
Normal file
8
src/app/navigation/navigation.component.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.sidenav-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav {
|
||||||
|
width: 200px;
|
||||||
|
box-shadow: 3px 0 6px rgba(0,0,0,.24);
|
||||||
|
}
|
||||||
30
src/app/navigation/navigation.component.html
Normal file
30
src/app/navigation/navigation.component.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<mat-sidenav-container class="sidenav-container">
|
||||||
|
<mat-sidenav
|
||||||
|
#drawer
|
||||||
|
class="sidenav"
|
||||||
|
fixedInViewport="true"
|
||||||
|
[attr.role]="isHandset ? 'dialog' : 'navigation'"
|
||||||
|
[mode]="(isHandset | async)!.matches ? 'over' : 'side'"
|
||||||
|
[opened]="!(isHandset | async)!.matches">
|
||||||
|
<mat-toolbar color="primary">Menu</mat-toolbar>
|
||||||
|
<mat-nav-list>
|
||||||
|
<a mat-list-item [routerLink]="['awardees']">Awardees</a>
|
||||||
|
<a mat-list-item [routerLink]="['judges']">Judges</a>
|
||||||
|
<a mat-list-item [routerLink]="['awardees']">Years</a>
|
||||||
|
</mat-nav-list>
|
||||||
|
</mat-sidenav>
|
||||||
|
<mat-sidenav-content>
|
||||||
|
<mat-toolbar color="primary">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label="Toggle sidenav"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="drawer.toggle()"
|
||||||
|
*ngIf="(isHandset | async)!.matches">
|
||||||
|
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||||
|
</button>
|
||||||
|
<span>{{title}}</span>
|
||||||
|
</mat-toolbar>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</mat-sidenav-content>
|
||||||
|
</mat-sidenav-container>
|
||||||
24
src/app/navigation/navigation.component.spec.ts
Normal file
24
src/app/navigation/navigation.component.spec.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { NavigationComponent } from './navigation.component';
|
||||||
|
|
||||||
|
describe('NavigationComponent', () => {
|
||||||
|
let component: NavigationComponent;
|
||||||
|
let fixture: ComponentFixture<NavigationComponent>;
|
||||||
|
|
||||||
|
beforeEach(fakeAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ NavigationComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(NavigationComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should compile', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
20
src/app/navigation/navigation.component.ts
Normal file
20
src/app/navigation/navigation.component.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Title } from "@angular/platform-browser";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-navigation',
|
||||||
|
templateUrl: './navigation.component.html',
|
||||||
|
styleUrls: ['./navigation.component.css']
|
||||||
|
})
|
||||||
|
export class NavigationComponent {
|
||||||
|
isHandset: Observable<BreakpointState> = this.breakpointObserver.observe(Breakpoints.Handset);
|
||||||
|
constructor(
|
||||||
|
private breakpointObserver: BreakpointObserver,
|
||||||
|
private titleService: Title
|
||||||
|
) {}
|
||||||
|
get title(): string {
|
||||||
|
return this.titleService.getTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>SwedishchamberGranprizeAdmin</title>
|
<title>Gran Prize :: Admin</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user