reports.component.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { Component, Inject } from '@angular/core';
  2. import { Observable } from 'rxjs/Observable';
  3. import 'rxjs/add/observable/merge';
  4. import 'rxjs/add/observable/of';
  5. import 'rxjs/add/operator/map';
  6. import 'rxjs/add/operator/take';
  7. import { ReportDataService } from './services/reportData.service';
  8. import { ActivatedRoute, ParamMap } from '@angular/router';
  9. import { WindowService } from './services/window.service';
  10. import { Report, RemoteData } from './types';
  11. import { MatTableDataSource } from '@angular/material';
  12. function mapUser(params: ParamMap): boolean {
  13. const userName = params.get('user') || '';
  14. return userName.indexOf('admin') > -1;
  15. }
  16. /**
  17. * Special syntax: using 'this' as first argument does NOT add a first
  18. * parameter, but specifies the type of 'this' within the function.
  19. */
  20. function toggleApprovedStyle(this: HTMLElement, approved: boolean) {
  21. if (approved && this.className.indexOf('approved') === -1) {
  22. this.className += ' approved';
  23. } else {
  24. this.className = this.className.replace('approved', '');
  25. }
  26. }
  27. @Component({
  28. selector: 'ps-reports',
  29. templateUrl: './reports.component.html',
  30. styleUrls: ['./reports.component.css']
  31. })
  32. export class ReportsComponent {
  33. reports: MatTableDataSource<Report>;
  34. isAdmin = Observable.of(false);
  35. displayedColumns = ['id', 'description', 'date', 'amount', 'approved', 'actions'];
  36. constructor(private route: ActivatedRoute,
  37. private reportDataService: ReportDataService,
  38. @Inject(WindowService) private _window: Window) {
  39. this.reports = new MatTableDataSource([]);
  40. this.isAdmin = this.route.queryParamMap.map(mapUser);
  41. reportDataService.dataChange.subscribe(remoteData => {
  42. this.handleDataChanged(remoteData);
  43. });
  44. }
  45. handleDataChanged(remoteData: RemoteData<Report[]>): string {
  46. // This is called a "discriminated union".
  47. // Here "kind" is the "discriminant" for the remoteData "discriminated
  48. // union".
  49. switch (remoteData.kind) {
  50. case 'ok':
  51. this.reports.data = remoteData.data;
  52. return remoteData.kind;
  53. case 'error':
  54. alert(remoteData.error);
  55. return remoteData.kind;
  56. case 'loading':
  57. // display loading spinner;
  58. return remoteData.kind;
  59. case 'notFetched':
  60. // display initial page;
  61. return remoteData.kind;
  62. }
  63. }
  64. approve(report: Report) {
  65. this.toggleApproval(report, true);
  66. this.toggleApprovedStyle(report.id, true);
  67. }
  68. reject(report: Report) {
  69. this.toggleApproval(report, false);
  70. this.toggleApprovedStyle(report.id, false);
  71. }
  72. private toggleApprovedStyle(reportId: number, approved: boolean) {
  73. setTimeout(() => {
  74. const row = this._window.document.getElementById(`report$${reportId}`)!.closest('mat-row');
  75. toggleApprovedStyle.call(row, approved);
  76. }, 50);
  77. }
  78. private toggleApproval(report: Report, approved: boolean) {
  79. report.approved = approved;
  80. this.route
  81. .queryParamMap
  82. .take(1)
  83. .map(params => params.get('user'))
  84. .subscribe(user => {
  85. if (user) {
  86. this.reportDataService.toggleApproval(report, user);
  87. }
  88. });
  89. }
  90. }