aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/todo/todo-page
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/ClientApp/src/app/todo/todo-page')
-rw-r--r--Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.css39
-rw-r--r--Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.html21
-rw-r--r--Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.spec.ts78
-rw-r--r--Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.ts39
4 files changed, 177 insertions, 0 deletions
diff --git a/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.css b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.css
new file mode 100644
index 00000000..754b786e
--- /dev/null
+++ b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.css
@@ -0,0 +1,39 @@
+.align-self-bottom {
+ align-self: flex-end;
+}
+
+.item-box {
+ display: flex;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.first-item-box {
+ justify-content: space-between;
+ padding: 0 0 5px 5px;
+}
+
+.non-first-item-box {
+ padding: 5px;
+}
+
+.space {
+ flex: 1 4 20px;
+}
+
+.sample-box {
+ box-sizing: border-box;
+ align-self: flex-start;
+}
+
+.sample-item {
+ display: flex;
+ align-items: center;
+}
+
+.sample-color-block {
+ border-radius: 0.2em;
+ width: 1em;
+ height: 1em;
+ margin-right: 2px;
+}
diff --git a/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.html b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.html
new file mode 100644
index 00000000..50180fe8
--- /dev/null
+++ b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.html
@@ -0,0 +1,21 @@
+<mat-progress-bar *ngIf="!isLoadCompleted" mode="indeterminate"></mat-progress-bar>
+
+<mat-list>
+ <mat-list-item *ngFor="let item of items; let i = index" style="height:unset;">
+ <div class="item-box" [class.first-item-box]="i === 0" [class.non-first-item-box]="i !== 0">
+ <app-todo-item @itemEnter [class.align-self-bottom]="i === 0" [item]="item"></app-todo-item>
+ <div class="space"></div>
+ <div class="sample-box" *ngIf="i === 0">
+ <div class="mat-caption sample-item">
+ <span class="sample-color-block color-block-open"></span>
+ <span> means working now.</span>
+ </div>
+ <div class="mat-caption sample-item">
+ <span class="sample-color-block color-block-closed"></span>
+ <span> means completed.</span>
+ </div>
+ <div class="mat-caption">click on item to see details.</div>
+ </div>
+ </div>
+ </mat-list-item>
+</mat-list>
diff --git a/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.spec.ts b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.spec.ts
new file mode 100644
index 00000000..16c77376
--- /dev/null
+++ b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.spec.ts
@@ -0,0 +1,78 @@
+import { Component, NO_ERRORS_SCHEMA } from '@angular/core';
+import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+
+import { Observable, from } from 'rxjs';
+import { delay } from 'rxjs/operators';
+
+import { TodoItem } from '../todo-item';
+import { TodoPageComponent } from './todo-page.component';
+import { TodoService } from '../todo-service/todo.service';
+
+
+@Component({
+ /* tslint:disable-next-line:component-selector*/
+ selector: 'mat-progress-bar',
+ template: ''
+})
+class MatProgressBarStubComponent { }
+
+function asyncArray<T>(data: T[]): Observable<T> {
+ return from(data).pipe(delay(0));
+}
+
+describe('TodoListPageComponent', () => {
+ let component: TodoPageComponent;
+ let fixture: ComponentFixture<TodoPageComponent>;
+
+ const mockTodoItems: TodoItem[] = [
+ {
+ number: 0,
+ title: 'Test title 1',
+ isClosed: true,
+ detailUrl: 'test_url1'
+ },
+ {
+ number: 1,
+ title: 'Test title 2',
+ isClosed: false,
+ detailUrl: 'test_url2'
+ }
+ ];
+
+ beforeEach(async(() => {
+ const mockTodoService: jasmine.SpyObj<TodoService> = jasmine.createSpyObj('TodoService', ['getWorkItemList']);
+
+ mockTodoService.getWorkItemList.and.returnValue(asyncArray(mockTodoItems));
+
+ TestBed.configureTestingModule({
+ declarations: [TodoPageComponent, MatProgressBarStubComponent],
+ imports: [NoopAnimationsModule],
+ providers: [{ provide: TodoService, useValue: mockTodoService }],
+ schemas: [NO_ERRORS_SCHEMA]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TodoPageComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ it('should show progress bar during loading', () => {
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('mat-progress-bar'))).toBeTruthy();
+ });
+
+ it('should hide progress bar after loading', fakeAsync(() => {
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ expect(fixture.debugElement.query(By.css('mat-progress-bar'))).toBeFalsy();
+ }));
+});
diff --git a/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.ts b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.ts
new file mode 100644
index 00000000..7b658228
--- /dev/null
+++ b/Timeline/ClientApp/src/app/todo/todo-page/todo-page.component.ts
@@ -0,0 +1,39 @@
+import { Component, OnInit } from '@angular/core';
+import { trigger, transition, style, animate } from '@angular/animations';
+
+
+import { TodoItem } from '../todo-item';
+import { TodoService } from '../todo-service/todo.service';
+
+@Component({
+ selector: 'app-todo-page',
+ templateUrl: './todo-page.component.html',
+ styleUrls: ['./todo-page.component.css', '../todo-list-color-block.css'],
+ animations: [
+ trigger('itemEnter', [
+ transition(':enter', [
+ style({
+ transform: 'translateX(-100%) translateX(-20px)'
+ }),
+ animate('400ms ease-out', style({
+ transform: 'none'
+ }))
+ ])
+ ])
+ ]
+})
+export class TodoPageComponent implements OnInit {
+
+ items: TodoItem[] = [];
+ isLoadCompleted = false;
+
+ constructor(private todoService: TodoService) {
+ }
+
+ ngOnInit() {
+ this.todoService.getWorkItemList().subscribe({
+ next: result => this.items.push(result),
+ complete: () => { this.isLoadCompleted = true; }
+ });
+ }
+}