123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import { Injectable, Inject } from '@angular/core';
- import { BehaviorSubject } from 'rxjs/BehaviorSubject';
- import { Subject } from 'rxjs/Subject';
- import { Report, NewReport, PS_REPORTS_KEY, RemoteData, isRemoteDataOK } from '../types';
- import { WindowService } from './window.service';
- declare global {
- interface Array<T> {
- filterWith<TKey extends keyof T, TValue extends T[TKey]>(member: TKey, value: TValue): T[];
- }
- }
- Array.prototype.filterWith = function<T, TKey extends keyof T, TValue extends T[TKey]>(this: T[], member: TKey, value: TValue): T[] {
- return this.filter(x => x[member] === value);
- }
- // Non-generics version.
- // function filter(reports: Report[], term: string): Report[] {
- // return reports.filter((r => r.description === term));
- // }
- // Generics versions
- const reports: Report[] = [];
- reports.filterWith('approved', true);
- @Injectable()
- export class ReportDataService {
- dataChange = new BehaviorSubject<RemoteData<Report[]>>({ kind: "notFetched" });
- reportCreated: Subject<Report> = new Subject();
- reportApprovedReject: Subject<{ report: Report, user: string }> = new Subject();
- constructor(@Inject(WindowService) private _window: Window) {
- this.fetch();
- }
- get remoteData(): RemoteData<Report[]> {
- return this.dataChange.value;
- }
- getReport(reportId: number): Promise<Report | undefined> {
- if (isRemoteDataOK(this.remoteData)) {
- return Promise.resolve(this.remoteData.data.find(r => r.id === reportId));
- } else {
- return Promise.resolve(undefined);
- }
- }
- add(report: NewReport) {
- if (isRemoteDataOK(this.remoteData)) {
- const newReport = {
- ...report,
- // Since this.data: Report[], rep is a Report, so it does have an id
- // property we can use, although Report.id is an optional number.
- // Which means we can tell the compiler it exists with a '!'.
- id: this.remoteData.data.reduce((biggestId, rep) => biggestId > rep.id ? biggestId : rep.id, 0) + 1,
- amount: report.items.reduce((sum, item) => sum + item.amount, 0)
- };
- const newData = [...this.remoteData.data, newReport];
- this.updateData(newData);
- this.reportCreated.next(newReport);
- }
- }
- save(report: Report) {
- if (isRemoteDataOK(this.remoteData)) {
- const reportIndex = this.remoteData.data.findIndex(r => r.id === report.id);
- const newData = [...this.remoteData.data];
- newData.splice(reportIndex, 1, report);
- this.updateData(newData);
- }
- }
- toggleApproval(report: Report, user: string) {
- if (isRemoteDataOK(this.remoteData)) {
- const reportIndex = this.remoteData.data.findIndex(r => r.id === report.id);
- const newData = [...this.remoteData.data];
- newData.splice(reportIndex, 1, report);
- this.updateData(newData);
- this.reportApprovedReject.next({ report, user });
- }
- }
- private updateData(reports: Report[]) {
- this._window.localStorage.setItem(PS_REPORTS_KEY, JSON.stringify(reports));
- this._window.psExpenses = JSON.stringify(reports);
- this.dataChange.next({ kind: "ok", data: reports });
- }
- private fetch(): void {
- this.dataChange.next({ kind: "loading" });
- setTimeout(() => {
- const random = Math.floor((Math.random() * 10) + 1);
- const stringfiedReports = this._window.localStorage.getItem(PS_REPORTS_KEY);
- if (random > 3 && stringfiedReports) {
- this.dataChange.next({
- kind: "ok",
- data: JSON.parse(stringfiedReports)
- });
- } else {
- this.dataChange.next({
- kind: 'error',
- error: 'The were was an issue loading the data'
- })
- }
- }, 1000);
- }
- }
|