reportData.service.ts 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { Injectable, Inject } from '@angular/core';
  2. import { BehaviorSubject } from 'rxjs/BehaviorSubject';
  3. import { Subject } from 'rxjs/Subject';
  4. import { Report, NewReport, PS_REPORTS_KEY, RemoteData, isRemoteDataOK } from '../types';
  5. import { WindowService } from './window.service';
  6. @Injectable()
  7. export class ReportDataService {
  8. dataChange = new BehaviorSubject<RemoteData<Report[]>>({ kind: "notFetched" });
  9. reportCreated: Subject<Report> = new Subject();
  10. reportApprovedReject: Subject<{ report: Report, user: string }> = new Subject();
  11. constructor(@Inject(WindowService) private _window: Window) {
  12. this.fetch();
  13. }
  14. get remoteData(): RemoteData<Report[]> {
  15. return this.dataChange.value;
  16. }
  17. getReport(reportId: number): Promise<Report | undefined> {
  18. if (isRemoteDataOK(this.remoteData)) {
  19. return Promise.resolve(this.remoteData.data.find(r => r.id === reportId));
  20. } else {
  21. return Promise.resolve(undefined);
  22. }
  23. }
  24. add(report: NewReport) {
  25. if (isRemoteDataOK(this.remoteData)) {
  26. const newReport = {
  27. ...report,
  28. // Since this.data: Report[], rep is a Report, so it does have an id
  29. // property we can use, although Report.id is an optional number.
  30. // Which means we can tell the compiler it exists with a '!'.
  31. id: this.remoteData.data.reduce((biggestId, rep) => biggestId > rep.id ? biggestId : rep.id, 0) + 1,
  32. amount: report.items.reduce((sum, item) => sum + item.amount, 0)
  33. };
  34. const newData = [...this.remoteData.data, newReport];
  35. this.updateData(newData);
  36. this.reportCreated.next(newReport);
  37. }
  38. }
  39. save(report: Report) {
  40. if (isRemoteDataOK(this.remoteData)) {
  41. const reportIndex = this.remoteData.data.findIndex(r => r.id === report.id);
  42. const newData = [...this.remoteData.data];
  43. newData.splice(reportIndex, 1, report);
  44. this.updateData(newData);
  45. }
  46. }
  47. toggleApproval(report: Report, user: string) {
  48. if (isRemoteDataOK(this.remoteData)) {
  49. const reportIndex = this.remoteData.data.findIndex(r => r.id === report.id);
  50. const newData = [...this.remoteData.data];
  51. newData.splice(reportIndex, 1, report);
  52. this.updateData(newData);
  53. this.reportApprovedReject.next({ report, user });
  54. }
  55. }
  56. private updateData(reports: Report[]) {
  57. this._window.localStorage.setItem(PS_REPORTS_KEY, JSON.stringify(reports));
  58. this.dataChange.next({ kind: "ok", data: reports });
  59. }
  60. private fetch(): void {
  61. this.dataChange.next({ kind: "loading" });
  62. setTimeout(() => {
  63. const random = Math.floor((Math.random() * 10) + 1);
  64. const stringfiedReports = this._window.localStorage.getItem(PS_REPORTS_KEY);
  65. if (random > 3 && stringfiedReports) {
  66. this.dataChange.next({
  67. kind: "ok",
  68. data: JSON.parse(stringfiedReports)
  69. });
  70. } else {
  71. this.dataChange.next({
  72. kind: 'error',
  73. error: 'The were was an issue loading the data'
  74. });
  75. }
  76. }, 1000);
  77. }
  78. }