From 5afa4248c5ec67d361a8f75e0ec0f1d12778e266 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 20 Feb 2019 00:12:18 +0800 Subject: Add sample on todo page. --- Timeline/ClientApp/src/app/app.component.css | 4 -- .../todo-list-page/todo-list-page.component.css | 36 ++++++++++- .../todo-list-page/todo-list-page.component.html | 20 ++++-- .../app/todo-list-page/todo-list-page.component.ts | 2 +- .../app/todo-list-page/todo-list.service.spec.ts | 12 ++++ .../src/app/todo-list-page/todo-list.service.ts | 73 ++++++++++++++++++++++ .../ClientApp/src/app/todo-list.service.spec.ts | 12 ---- Timeline/ClientApp/src/app/todo-list.service.ts | 68 -------------------- Timeline/ClientApp/src/styles.css | 4 ++ 9 files changed, 139 insertions(+), 92 deletions(-) create mode 100644 Timeline/ClientApp/src/app/todo-list-page/todo-list.service.spec.ts create mode 100644 Timeline/ClientApp/src/app/todo-list-page/todo-list.service.ts delete mode 100644 Timeline/ClientApp/src/app/todo-list.service.spec.ts delete mode 100644 Timeline/ClientApp/src/app/todo-list.service.ts (limited to 'Timeline/ClientApp/src') diff --git a/Timeline/ClientApp/src/app/app.component.css b/Timeline/ClientApp/src/app/app.component.css index 759a30d6..13a44248 100644 --- a/Timeline/ClientApp/src/app/app.component.css +++ b/Timeline/ClientApp/src/app/app.component.css @@ -1,7 +1,3 @@ -.fill-remaining-space { - flex: 1 1 auto; -} - a.icp-record { color: grey; text-decoration: none; diff --git a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.css b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.css index c17267c5..6a603863 100644 --- a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.css +++ b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.css @@ -1,12 +1,42 @@ +.align-self-bottom { + align-self: flex-end; +} + +.first-item-box { + justify-content: space-between; +} + +.item-box { + display: flex; + width: 100%; + padding: 10px; + box-sizing: border-box; +} + +.sample-box { + box-sizing: border-box; + align-self: flex-start; +} + .item-id { display: inline-block; text-align: center; - background: skyblue; border-radius: 0.2rem; width: 1.2rem; height: 1.2rem; } -mat-list-item { - margin: 10px; +.item-id-sample { + display: inline-block; + border-radius: 0.2em; + width: 1em; + height: 1em; +} + +.item-id-open { + background: red; +} + +.item-id-closed { + background: green; } diff --git a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.html b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.html index 3a80e4eb..ce6eb2ed 100644 --- a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.html +++ b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.html @@ -1,9 +1,21 @@ - - - {{item.id}} {{item.title}} - + +
+ + {{item.id}} + {{item.title}} + +
+
+ means working now. +
+
+ means completed. +
+
+
diff --git a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.ts b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.ts index 722ecbdc..8af1f5ef 100644 --- a/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.ts +++ b/Timeline/ClientApp/src/app/todo-list-page/todo-list-page.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { TodoListService, WorkItem } from '../todo-list.service'; +import { TodoListService, WorkItem } from './todo-list.service'; @Component({ selector: 'app-todo-list-page', diff --git a/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.spec.ts b/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.spec.ts new file mode 100644 index 00000000..529ba8cc --- /dev/null +++ b/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { TodoListService } from './todo-list.service'; + +describe('TodoListServiceService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: TodoListService = TestBed.get(TodoListService); + expect(service).toBeTruthy(); + }); +}); diff --git a/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.ts b/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.ts new file mode 100644 index 00000000..0b54653b --- /dev/null +++ b/Timeline/ClientApp/src/app/todo-list-page/todo-list.service.ts @@ -0,0 +1,73 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { switchMap, concatMap, map, toArray } from 'rxjs/operators'; + +interface WiqlWorkItemResult { + id: number; + url: string; +} + +interface WiqlResult { + workItems: WiqlWorkItemResult[]; +} + +interface WorkItemResult { + id: number; + fields: { [name: string]: any }; +} + +export interface WorkItem { + id: number; + title: string; + closed: boolean; +} + +@Injectable({ + providedIn: 'root' +}) +export class TodoListService { + + private username = 'crupest'; + private organization = 'crupest-web'; + private project = 'Timeline'; + private titleFieldName = 'System.Title'; + private stateFieldName = 'System.State'; + + constructor(private client: HttpClient) { } + + private getAzureDevOpsPat(): Observable { + return this.client.get('/api/TodoList/AzureDevOpsPat', { + headers: { + 'Accept': 'text/plain' + }, + responseType: 'text' + }); + } + + getWorkItemList(): Observable { + return this.getAzureDevOpsPat().pipe( + switchMap( + pat => { + const headers = new HttpHeaders({ + 'Accept': 'application/json', + 'Authorization': `Basic ${btoa(this.username + ':' + pat)}` + }); + return this.client.post( + `https://dev.azure.com/${this.organization}/${this.project}/_apis/wit/wiql?api-version=5.0`, { + query: 'SELECT [System.Id] FROM workitems WHERE [System.TeamProject] = @project' + }, { headers: headers }).pipe( + switchMap(result => result.workItems), + concatMap(result => this.client.get(result.url, { headers: headers })), + map(result => { + id: result.id, + title: result.fields[this.titleFieldName], + closed: ((result.fields[this.stateFieldName]).toLowerCase() === 'closed') + }), + toArray() + ); + } + ) + ); + } +} diff --git a/Timeline/ClientApp/src/app/todo-list.service.spec.ts b/Timeline/ClientApp/src/app/todo-list.service.spec.ts deleted file mode 100644 index 529ba8cc..00000000 --- a/Timeline/ClientApp/src/app/todo-list.service.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { TodoListService } from './todo-list.service'; - -describe('TodoListServiceService', () => { - beforeEach(() => TestBed.configureTestingModule({})); - - it('should be created', () => { - const service: TodoListService = TestBed.get(TodoListService); - expect(service).toBeTruthy(); - }); -}); diff --git a/Timeline/ClientApp/src/app/todo-list.service.ts b/Timeline/ClientApp/src/app/todo-list.service.ts deleted file mode 100644 index 238919d3..00000000 --- a/Timeline/ClientApp/src/app/todo-list.service.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { switchMap, concatMap, map, toArray } from 'rxjs/operators'; - -interface WiqlWorkItemResult { - id: number; - url: string; -} - -interface WiqlResult { - workItems: WiqlWorkItemResult[]; -} - -interface WorkItemResult { - id: number; - fields: { [name: string]: any }; -} - -export interface WorkItem { - id: number; - title: string; -} - -@Injectable({ - providedIn: 'root' -}) -export class TodoListService { - - private username = 'crupest'; - private organization = 'crupest-web'; - private project = 'Timeline'; - private fieldId = 'System.Title'; - - - constructor(private client: HttpClient) { } - - private getAzureDevOpsPat(): Observable { - return this.client.get('/api/TodoList/AzureDevOpsPat', { - headers: { - 'Accept': 'text/plain' - }, - responseType: 'text' - }); - } - - getWorkItemList(): Observable { - return this.getAzureDevOpsPat().pipe( - switchMap( - pat => { - const headers = new HttpHeaders({ - 'Accept': 'application/json', - 'Authorization': `Basic ${btoa(this.username + ':' + pat)}` - }); - return this.client.post( - `https://dev.azure.com/${this.organization}/${this.project}/_apis/wit/wiql?api-version=5.0`, { - query: 'SELECT [System.Id] FROM workitems WHERE [System.TeamProject] = @project' - }, { headers: headers }).pipe( - switchMap(result => result.workItems), - concatMap(result => this.client.get(result.url, { headers: headers })), - map(result => { id: result.id, title: result.fields[this.fieldId] }), - toArray() - ); - } - ) - ); - } -} diff --git a/Timeline/ClientApp/src/styles.css b/Timeline/ClientApp/src/styles.css index 7a81e04c..fad44c53 100644 --- a/Timeline/ClientApp/src/styles.css +++ b/Timeline/ClientApp/src/styles.css @@ -4,3 +4,7 @@ body { margin: 0; } + +.fill-remaining-space { + flex: 1 1 auto; +} -- cgit v1.2.3