From 46065fc745e51aa43b92eca9f86288aa507eaa6d Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Sun, 8 Nov 2020 11:34:10 +0200 Subject: [PATCH] table sorting working --- src/app/api-response.ts | 6 -- src/app/app.module.ts | 6 +- .../article-page/article-page.component.html | 2 +- .../article-page/article-page.component.ts | 2 + src/app/custom-sort.pipe.spec.ts | 8 +++ src/app/custom-sort.pipe.ts | 19 +++++++ src/app/gender.pipe.ts | 2 + src/app/list-page/list-page.component.ts | 2 + .../list-paginate/list-paginate.component.ts | 8 ++- src/app/list.service.ts | 10 ++-- src/app/list/list.component.html | 57 +++++++++++++++++-- src/app/list/list.component.ts | 51 +++++++++++------ src/app/person.ts | 2 +- src/app/sort.ts | 15 +++++ 14 files changed, 150 insertions(+), 40 deletions(-) delete mode 100644 src/app/api-response.ts create mode 100644 src/app/custom-sort.pipe.spec.ts create mode 100644 src/app/custom-sort.pipe.ts create mode 100644 src/app/sort.ts diff --git a/src/app/api-response.ts b/src/app/api-response.ts deleted file mode 100644 index 1e117b0..0000000 --- a/src/app/api-response.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IPerson } from './person' - -export interface IAPIResponse { - stats: any; - list: IPerson[]; -} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c76eb5e..3435759 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -11,6 +11,7 @@ import { ListComponent } from './list/list.component'; import { ListPaginateComponent } from './list-paginate/list-paginate.component'; import { ListService } from './list.service'; import { GenderPipe } from './gender.pipe'; +import { CustomSortPipe } from './custom-sort.pipe'; @NgModule({ declarations: [ @@ -20,12 +21,13 @@ import { GenderPipe } from './gender.pipe'; ListPageComponent, ListComponent, ListPaginateComponent, - GenderPipe + GenderPipe, + CustomSortPipe, ], imports: [ BrowserModule, AppRoutingModule, - HttpClientModule + HttpClientModule, ], providers: [ ], diff --git a/src/app/article-page/article-page.component.html b/src/app/article-page/article-page.component.html index b598de6..8c9a9cd 100644 --- a/src/app/article-page/article-page.component.html +++ b/src/app/article-page/article-page.component.html @@ -1 +1 @@ -

article-page works!

+ diff --git a/src/app/article-page/article-page.component.ts b/src/app/article-page/article-page.component.ts index dfa5047..e3a9d5c 100644 --- a/src/app/article-page/article-page.component.ts +++ b/src/app/article-page/article-page.component.ts @@ -1,5 +1,7 @@ import { Component, OnInit } from '@angular/core'; +// This is a router component for the article. + @Component({ selector: 'app-article-page', templateUrl: './article-page.component.html', diff --git a/src/app/custom-sort.pipe.spec.ts b/src/app/custom-sort.pipe.spec.ts new file mode 100644 index 0000000..b9ca180 --- /dev/null +++ b/src/app/custom-sort.pipe.spec.ts @@ -0,0 +1,8 @@ +import { CustomSortPipe } from './custom-sort.pipe'; + +describe('CustomSortPipe', () => { + it('create an instance', () => { + const pipe = new CustomSortPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/custom-sort.pipe.ts b/src/app/custom-sort.pipe.ts new file mode 100644 index 0000000..d9fc89c --- /dev/null +++ b/src/app/custom-sort.pipe.ts @@ -0,0 +1,19 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { Sort } from './sort' + +const sorter = new Sort(); + +// This is a sorting pipe for the list of people. +// I couldn't come up with a better way of doing it at the moment. + +@Pipe({ + name: 'customSort' +}) +export class CustomSortPipe implements PipeTransform { + transform(value: Array, field: string, direction: number): Array { + if (direction === 0 || field == null) { + return value; + } + return sorter.sort(value.slice(), field, direction); + } +} diff --git a/src/app/gender.pipe.ts b/src/app/gender.pipe.ts index bbf09ff..d754672 100644 --- a/src/app/gender.pipe.ts +++ b/src/app/gender.pipe.ts @@ -1,5 +1,7 @@ import { Pipe, PipeTransform } from '@angular/core'; +// This is a simple pipe for formatting the gender + @Pipe({ name: 'gender' }) diff --git a/src/app/list-page/list-page.component.ts b/src/app/list-page/list-page.component.ts index 1ecfa71..fada53f 100644 --- a/src/app/list-page/list-page.component.ts +++ b/src/app/list-page/list-page.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +// This is a router component for the list of people. + @Component({ selector: 'app-list-page', templateUrl: './list-page.component.html', diff --git a/src/app/list-paginate/list-paginate.component.ts b/src/app/list-paginate/list-paginate.component.ts index 5d1b015..f809426 100644 --- a/src/app/list-paginate/list-paginate.component.ts +++ b/src/app/list-paginate/list-paginate.component.ts @@ -16,11 +16,17 @@ export class ListPaginateComponent { constructor(private router: Router) { } public get pageNums(): number[] { + // This function calculates the buttons for the pagination so that the + // current page number is always in the center unless it is near the beginning + // or the end. const starti = Math.min(Math.max(this.page - 2, 1), this.pages - 4); return [...Array(5)].map((p, i) => starti + i); } public navigate(num: number): void { - this.router.navigate(['/list'], { queryParams: { page: Math.min(Math.max(num, 1), this.pages) }}); + // This function navigates to a page number that is clamped + this.router.navigate(['/list'], { queryParams: { + page: Math.min(Math.max(num, 1), this.pages), + } }); } } diff --git a/src/app/list.service.ts b/src/app/list.service.ts index e9f172b..356965b 100644 --- a/src/app/list.service.ts +++ b/src/app/list.service.ts @@ -1,18 +1,18 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs' -import { IAPIResponse } from './api-response' + +// This is the service file for the API request @Injectable({ providedIn: 'root' }) export class ListService { - private listUrl = 'http://midaiganes.irw.ee/api/list'; + private listUrl = 'http://midaiganes.irw.ee/api/list?limit=100'; constructor(private http: HttpClient) { } - public getList(limit: number = 10, offset: number = 0): Observable { - const url = `${this.listUrl}?offset=${offset}&limit=${limit}`; - return this.http.get(url); + public getList(): Observable { + return this.http.get(this.listUrl); } } diff --git a/src/app/list/list.component.html b/src/app/list/list.component.html index 8a601fd..ed25f4c 100644 --- a/src/app/list/list.component.html +++ b/src/app/list/list.component.html @@ -1,12 +1,57 @@ - - - - - + + + + + - + diff --git a/src/app/list/list.component.ts b/src/app/list/list.component.ts index 1bc722d..a88bb4d 100644 --- a/src/app/list/list.component.ts +++ b/src/app/list/list.component.ts @@ -1,20 +1,21 @@ -import { Component, OnInit, OnChanges, SimpleChanges, Input } from '@angular/core'; +import { Component, OnInit, SimpleChanges, Input } from '@angular/core'; import { ListService } from '../list.service' import { IPerson } from '../person' -import { IAPIResponse } from '../api-response' + +// This component is for listing the people @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.styl'] }) -export class ListComponent implements OnInit, OnChanges { +export class ListComponent implements OnInit { public people: IPerson[]; private selected: IPerson; - private sortBy: string; - private sortDir: number; + public sortBy: string; + public sortDir = 0; @Input() public page = 1; @@ -23,28 +24,42 @@ export class ListComponent implements OnInit, OnChanges { constructor(private listService: ListService) { } - ngOnChanges(changes: SimpleChanges): void { - if (changes.page) { - this.getList(); - } - } - ngOnInit(): void { this.getList(); } - private getList(): void { - const offset = this.perPage * this.page; - this.listService.getList(this.perPage, offset).subscribe( - (data) => this.updateList(data)); + public get startIndex(): number { + // First argument to array slicer + return (this.page - 1) * this.perPage; } - private updateList(data: IAPIResponse): void { - this.people = data.list; - // this.pages = data.stats.total / this.perPage + public get endIndex(): number { + // Second argument to array slicer + return this.startIndex + this.perPage; + } + + public setSort(field: string): void { + // Reset the sorting if it is a new field + if (this.sortBy !== field) { + this.sortDir = 0; + } + + this.sortBy = field; + this.sortDir++; + + // Loop back to descending sort + if (this.sortDir === 2) { + this.sortDir = -1; + } + } + + private getList(): void { + this.listService.getList().subscribe( + (data) => this.people = data.list); } private selectPerson(person: IPerson): void { + // Select a person to show the details of if (this.selected === person) { this.selected = null; return; diff --git a/src/app/person.ts b/src/app/person.ts index 97162a9..1c65f09 100644 --- a/src/app/person.ts +++ b/src/app/person.ts @@ -7,4 +7,4 @@ export interface IPerson { phone: string; image: string[]; intro: string; -}; +} diff --git a/src/app/sort.ts b/src/app/sort.ts new file mode 100644 index 0000000..a815a63 --- /dev/null +++ b/src/app/sort.ts @@ -0,0 +1,15 @@ + +// This is a simple encapsulation class for the Collator used in sorting. + +export class Sort { + private collator = new Intl.Collator('et', { + numeric: true, + sensitivity: 'base', + }); + + constructor() { } + + public sort(value: Array, property: string, order: number, type = ''): Array { + return value.sort((a, b) => this.collator.compare(a[property], b[property]) * order); + } +}
EesnimiPerekonnanimiSuguSünnikuupäevTelefonEesnimi + + + ^ + v + | + + + | + Perekonnanimi + + + ^ + v + | + + + | + Sugu + + + ^ + v + | + + + | + Sünnikuupäev + + + ^ + v + | + + + | + Telefon + + + ^ + v + | + + + | +
{{ person.firstname }} {{ person.surname }}