organize services into services folder

This commit is contained in:
Jesse Lucas
2020-03-29 16:51:12 -04:00
parent 2fe94736e6
commit 0361d303f2
24 changed files with 20 additions and 21 deletions
+16
View File
@@ -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();
});
});
+35
View File
@@ -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();
});
});
+45
View File
@@ -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;
})
);
}
}
+16
View File
@@ -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();
});
});
+9
View File
@@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DeviceService {
constructor() { }
}
+16
View File
@@ -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();
});
});
+56
View File
@@ -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();
});
});
+50
View File
@@ -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();
});
});
+79
View File
@@ -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;
}
}