organize services into services folder
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CookieService } from './cookie.service';
|
||||
|
||||
describe('CookieService', () => {
|
||||
let service: CookieService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CookieService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CookieService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
getCookie(name: string): string {
|
||||
let ca: Array<string> = document.cookie.split(';');
|
||||
let caLen: number = ca.length;
|
||||
let cookieName = `${name}=`;
|
||||
let c: string;
|
||||
|
||||
for (let i: number = 0; i < caLen; i += 1) {
|
||||
c = ca[i].replace(/^\s+/g, '');
|
||||
if (c.indexOf(cookieName) == 0) {
|
||||
return c.substring(cookieName.length, c.length);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
deleteCookie(name): void {
|
||||
this.setCookie(name, "", -1);
|
||||
}
|
||||
|
||||
setCookie(name: string, value: string, expireDays: number, path: string = ""): void {
|
||||
let d: Date = new Date();
|
||||
d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);
|
||||
let expires: string = "expires=" + d.toUTCString();
|
||||
document.cookie = name + "=" + value + "; " + expires + (path.length > 0 ? "; path=" + path : "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DbStatusService } from './db-status.service';
|
||||
|
||||
describe('DbStatusService', () => {
|
||||
let service: DbStatusService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(DbStatusService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { CookieService } from './cookie.service';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, retry, catchError } from 'rxjs/operators';
|
||||
|
||||
import { environment } from '../../environments/environment'
|
||||
import { apiURL, apiRetry } from '../api-utils'
|
||||
import Folder from '../folder'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DbStatusService {
|
||||
private dbStatusUrl = environment.production ? apiURL + 'rest/db/status' : 'api/dbStatus';
|
||||
|
||||
constructor(private http: HttpClient, private cookieService: CookieService) { }
|
||||
|
||||
getFolderStatus(id: string): Observable<Folder.Status> {
|
||||
let httpOptions: { params: HttpParams };
|
||||
if (id) {
|
||||
httpOptions = {
|
||||
params: new HttpParams().set('folder', id)
|
||||
};
|
||||
} else { }
|
||||
|
||||
return this.http
|
||||
.get<Folder.Status>(this.dbStatusUrl, httpOptions)
|
||||
.pipe(
|
||||
retry(apiRetry),
|
||||
map(res => {
|
||||
// Remove from array in developement
|
||||
// in-memory-web-api returns arrays
|
||||
if (!environment.production) {
|
||||
const a: any = res as any;
|
||||
if (a.length > 0) {
|
||||
res = res[0];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DeviceService } from './device.service';
|
||||
|
||||
describe('DeviceService', () => {
|
||||
let service: DeviceService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(DeviceService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DeviceService {
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FolderService } from './folder.service';
|
||||
|
||||
describe('FolderService', () => {
|
||||
let service: FolderService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(FolderService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SystemConfigService } from './system-config.service';
|
||||
import { Observable, Subscriber } from 'rxjs';
|
||||
import Folder from '../folder';
|
||||
import { DbStatusService } from './db-status.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FolderService {
|
||||
private folders: Folder[];
|
||||
|
||||
constructor(
|
||||
private systemConfigService: SystemConfigService,
|
||||
private dbStatusService: DbStatusService
|
||||
) { }
|
||||
|
||||
getFolderStatusInOrder(observer: Subscriber<Folder>, startIndex: number) {
|
||||
// Return if there aren't any folders at the index
|
||||
if (startIndex >= (this.folders.length)) {
|
||||
observer.complete();
|
||||
return;
|
||||
}
|
||||
const folder: Folder = this.folders[startIndex];
|
||||
startIndex = startIndex + 1;
|
||||
this.dbStatusService.getFolderStatus(folder.id).subscribe(
|
||||
status => {
|
||||
folder.status = status;
|
||||
observer.next(folder);
|
||||
|
||||
// recursively get the status of the next folder
|
||||
this.getFolderStatusInOrder(observer, startIndex);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* getAll() finds all folders and uses db status service to
|
||||
* set all their statuses
|
||||
*/
|
||||
getAll(): Observable<Folder> {
|
||||
const folderObservable: Observable<Folder> = new Observable((observer) => {
|
||||
this.systemConfigService.getFolders().subscribe(
|
||||
folders => {
|
||||
this.folders = folders;
|
||||
|
||||
// Synchronously get the status of each folder
|
||||
this.getFolderStatusInOrder(observer, 0);
|
||||
},
|
||||
err => { console.log("getAll error!", err) },
|
||||
() => { console.log("get all complete!") }
|
||||
);
|
||||
});
|
||||
return folderObservable
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InMemoryConfigDataService } from './in-memory-config-data.service';
|
||||
|
||||
describe('InMemoryDataService', () => {
|
||||
let service: InMemoryConfigDataService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(InMemoryConfigDataService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { config } from '../mocks/mock-config'
|
||||
import { dbStatus } from '../mocks/mock-db-status'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class InMemoryConfigDataService {
|
||||
createDb() {
|
||||
return { config, dbStatus };
|
||||
}
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RequestCacheService } from './request-cache.service';
|
||||
|
||||
describe('RequestCacheService', () => {
|
||||
let service: RequestCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(RequestCacheService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpResponse, HttpRequest } from '@angular/common/http';
|
||||
|
||||
export interface RequestCacheEntry {
|
||||
url: string;
|
||||
response: HttpResponse<any>;
|
||||
lastRead: number;
|
||||
}
|
||||
|
||||
const maxAge = 30000; // milliseconds
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RequestCacheService {
|
||||
private cache: Map<string, RequestCacheEntry> = new Map();
|
||||
|
||||
constructor() { }
|
||||
|
||||
get(req: HttpRequest<any>): HttpResponse<any> | undefined {
|
||||
const url = req.urlWithParams;
|
||||
const cached = this.cache.get(url);
|
||||
|
||||
if (!cached) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isExpired = cached.lastRead < (Date.now() - maxAge);
|
||||
return isExpired ? undefined : cached.response;
|
||||
}
|
||||
|
||||
put(req: HttpRequest<any>, response: HttpResponse<any>): void {
|
||||
const url = req.urlWithParams;
|
||||
|
||||
const entry = { url, response, lastRead: Date.now() };
|
||||
this.cache.set(url, entry);
|
||||
|
||||
// Remove expired cache entries
|
||||
const expired = Date.now() - maxAge;
|
||||
this.cache.forEach(entry => {
|
||||
if (entry.lastRead < expired) {
|
||||
this.cache.delete(entry.url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearAll(): void {
|
||||
this.cache = new Map();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SystemConfigService } from './system-config.service';
|
||||
|
||||
describe('SystemConfigService', () => {
|
||||
let service: SystemConfigService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(SystemConfigService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, retry } from 'rxjs/operators';
|
||||
|
||||
import Folder from '../folder';
|
||||
import { Device } from '../device';
|
||||
import { CookieService } from './cookie.service';
|
||||
import { environment } from '../../environments/environment'
|
||||
import { apiURL, apiRetry } from '../api-utils'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SystemConfigService {
|
||||
private folders: Folder[];
|
||||
private devices: Device[];
|
||||
private foldersSubject: Subject<Folder[]> = new Subject();
|
||||
private devicesSubject: Subject<Device[]> = new Subject();
|
||||
|
||||
private systemConfigUrl = environment.production ? apiURL + 'rest/system/config' : 'api/config';
|
||||
|
||||
private checkInterval: number = 100;
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
getSystemConfig(): Observable<any> {
|
||||
return this.http
|
||||
.get(this.systemConfigUrl)
|
||||
.pipe(
|
||||
retry(apiRetry),
|
||||
map(res => {
|
||||
this.folders = res['folders'];
|
||||
this.devices = res['devices'];
|
||||
this.foldersSubject.next(this.folders);
|
||||
this.devicesSubject.next(this.devices);
|
||||
|
||||
return res;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getFolders(): Observable<Folder[]> {
|
||||
const folderObservable: Observable<Folder[]> = new Observable((observer) => {
|
||||
if (this.folders) {
|
||||
observer.next(this.folders);
|
||||
observer.complete();
|
||||
} else {
|
||||
// create timer to keep checking for folders
|
||||
let t = setInterval(() => {
|
||||
if (this.folders) {
|
||||
clearInterval(t);
|
||||
observer.next(this.folders)
|
||||
observer.complete();
|
||||
}
|
||||
}, this.checkInterval);
|
||||
}
|
||||
});
|
||||
return folderObservable;
|
||||
}
|
||||
|
||||
// TODO switch to devices
|
||||
getDevices(): Observable<Device[]> {
|
||||
const deviceObserverable: Observable<Device[]> = new Observable((observer) => {
|
||||
if (this.folders) {
|
||||
observer.next(this.devices);
|
||||
} else {
|
||||
let t = setInterval(() => {
|
||||
if (this.devices) {
|
||||
clearInterval(t);
|
||||
observer.next(this.devices);
|
||||
}
|
||||
}, this.checkInterval);
|
||||
}
|
||||
});
|
||||
return deviceObserverable;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user