import { Injectable, SecurityContext } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { XDSAgentService, IXDSProjectConfig } from '../services/xdsagent.service'; export enum ProjectType { UNSET = '', NATIVE_PATHMAP = 'PathMap', SYNCTHING = 'CloudSync' } export const ProjectTypes = [ { value: ProjectType.NATIVE_PATHMAP, display: 'Path mapping' }, { value: ProjectType.SYNCTHING, display: 'Cloud Sync' } ]; export const ProjectStatus = { ErrorConfig: 'ErrorConfig', Disable: 'Disable', Enable: 'Enable', Pause: 'Pause', Syncing: 'Syncing' }; export interface IProject { id?: string; serverId: string; label: string; pathClient: string; pathServer?: string; type: ProjectType; status?: string; isInSync?: boolean; isUsable?: boolean; serverPrjDef?: IXDSProjectConfig; isExpanded?: boolean; visible?: boolean; defaultSdkID?: string; } @Injectable() export class ProjectService { public Projects$: Observable; private _prjsList: IProject[] = []; private current: IProject; private prjsSubject = >new BehaviorSubject(this._prjsList); constructor(private xdsSvr: XDSAgentService) { this.current = null; this.Projects$ = this.prjsSubject.asObservable(); this.xdsSvr.getProjects().subscribe((projects) => { this._prjsList = []; projects.forEach(p => { this._addProject(p, true); }); this.prjsSubject.next(Object.assign([], this._prjsList)); }); // Update Project data this.xdsSvr.ProjectState$.subscribe(prj => { const i = this._getProjectIdx(prj.id); if (i >= 0) { // XXX for now, only isInSync and status may change this._prjsList[i].isInSync = prj.isInSync; this._prjsList[i].status = prj.status; this._prjsList[i].isUsable = this._isUsableProject(prj); this.prjsSubject.next(Object.assign([], this._prjsList)); } }); // Add listener on create and delete project events this.xdsSvr.addEventListener('event:project-add', (ev) => { if (ev && ev.data && ev.data.id) { this._addProject(ev.data); } else { console.log('Warning: received events with unknown data: ev=', ev); } }); this.xdsSvr.addEventListener('event:project-delete', (ev) => { if (ev && ev.data && ev.data.id) { const idx = this._prjsList.findIndex(item => item.id === ev.data.id); if (idx === -1) { console.log('Warning: received events on unknown project id: ev=', ev); return; } this._prjsList.splice(idx, 1); this.prjsSubject.next(Object.assign([], this._prjsList)); } else { console.log('Warning: received events with unknown data: ev=', ev); } }); } public setCurrent(s: IProject) { this.current = s; } public getCurrent(): IProject { return this.current; } public getCurrentId(): string { if (this.current && this.current.id) { return this.current.id; } return ''; } Add(prj: IProject): Observable { const xdsPrj: IXDSProjectConfig = { id: '', serverId: prj.serverId, label: prj.label || '', clientPath: prj.pathClient.trim(), serverPath: prj.pathServer, type: prj.type, defaultSdkID: prj.defaultSdkID, }; // Send config to XDS server return this.xdsSvr.addProject(xdsPrj) .map(xp => this._convToIProject(xp)); } Delete(prj: IProject): Observable { const idx = this._getProjectIdx(prj.id); const delPrj = prj; if (idx === -1) { throw new Error('Invalid project id (id=' + prj.id + ')'); } return this.xdsSvr.deleteProject(prj.id) .map(res => delPrj); } Sync(prj: IProject): Observable { const idx = this._getProjectIdx(prj.id); if (idx === -1) { throw new Error('Invalid project id (id=' + prj.id + ')'); } return this.xdsSvr.syncProject(prj.id); } private _isUsableProject(p) { return p && p.isInSync && (p.status === ProjectStatus.Enable) && (p.status !== ProjectStatus.Syncing); } private _getProjectIdx(id: string): number { return this._prjsList.findIndex((item) => item.id === id); } private _convToIProject(rPrj: IXDSProjectConfig): IProject { // Convert XDSFolderConfig to IProject const pp: IProject = { id: rPrj.id, serverId: rPrj.serverId, label: rPrj.label, pathClient: rPrj.clientPath, pathServer: rPrj.serverPath, type: rPrj.type, status: rPrj.status, isInSync: rPrj.isInSync, isUsable: this._isUsableProject(rPrj), defaultSdkID: rPrj.defaultSdkID, serverPrjDef: Object.assign({}, rPrj), // do a copy }; return pp; } private _addProject(rPrj: IXDSProjectConfig, noNext?: boolean): IProject { // Convert XDSFolderConfig to IProject const pp = this._convToIProject(rPrj); // add new project this._prjsList.push(pp); // sort project array this._prjsList.sort((a, b) => { if (a.label < b.label) { return -1; } if (a.label > b.label) { return 1; } return 0; }); if (!noNext) { this.prjsSubject.next(Object.assign([], this._prjsList)); } return pp; } }