1 import { Injectable, SecurityContext } from '@angular/core';
2 import { Observable } from 'rxjs/Observable';
3 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
5 import { XDSAgentService, IXDSProjectConfig } from '../services/xdsagent.service';
7 /* FIXME: syntax only compatible with TS>2.4.0
8 export enum ProjectType {
10 NATIVE_PATHMAP = 'PathMap',
11 SYNCTHING = 'CloudSync'
14 export type ProjectTypeEnum = '' | 'PathMap' | 'CloudSync';
15 export const ProjectType = {
17 NATIVE_PATHMAP: 'PathMap',
18 SYNCTHING: 'CloudSync'
21 export const ProjectTypes = [
22 { value: ProjectType.NATIVE_PATHMAP, display: 'Path mapping' },
23 { value: ProjectType.SYNCTHING, display: 'Cloud Sync' }
26 export const ProjectStatus = {
27 ErrorConfig: 'ErrorConfig',
34 export interface IProject {
40 type: ProjectTypeEnum;
44 serverPrjDef?: IXDSProjectConfig;
47 defaultSdkID?: string;
51 export class ProjectService {
52 public Projects$: Observable<IProject[]>;
54 private _prjsList: IProject[] = [];
55 private current: IProject;
56 private prjsSubject = <BehaviorSubject<IProject[]>>new BehaviorSubject(this._prjsList);
58 constructor(private xdsSvr: XDSAgentService) {
60 this.Projects$ = this.prjsSubject.asObservable();
62 this.xdsSvr.getProjects().subscribe((projects) => {
64 projects.forEach(p => {
65 this._addProject(p, true);
67 this.prjsSubject.next(Object.assign([], this._prjsList));
70 // Update Project data
71 this.xdsSvr.ProjectState$.subscribe(prj => {
72 const i = this._getProjectIdx(prj.id);
74 // XXX for now, only isInSync and status may change
75 this._prjsList[i].isInSync = prj.isInSync;
76 this._prjsList[i].status = prj.status;
77 this._prjsList[i].isUsable = this._isUsableProject(prj);
78 this.prjsSubject.next(Object.assign([], this._prjsList));
82 // Add listener on create and delete project events
83 this.xdsSvr.addEventListener('event:project-add', (ev) => {
84 if (ev && ev.data && ev.data.id) {
85 this._addProject(ev.data);
87 console.log('Warning: received events with unknown data: ev=', ev);
90 this.xdsSvr.addEventListener('event:project-delete', (ev) => {
91 if (ev && ev.data && ev.data.id) {
92 const idx = this._prjsList.findIndex(item => item.id === ev.data.id);
94 console.log('Warning: received events on unknown project id: ev=', ev);
97 this._prjsList.splice(idx, 1);
98 this.prjsSubject.next(Object.assign([], this._prjsList));
100 console.log('Warning: received events with unknown data: ev=', ev);
106 public setCurrent(s: IProject) {
110 public getCurrent(): IProject {
114 public getCurrentId(): string {
115 if (this.current && this.current.id) {
116 return this.current.id;
121 Add(prj: IProject): Observable<IProject> {
122 const xdsPrj: IXDSProjectConfig = {
124 serverId: prj.serverId,
125 label: prj.label || '',
126 clientPath: prj.pathClient.trim(),
127 serverPath: prj.pathServer,
129 defaultSdkID: prj.defaultSdkID,
131 // Send config to XDS server
132 return this.xdsSvr.addProject(xdsPrj)
133 .map(xp => this._convToIProject(xp));
136 Delete(prj: IProject): Observable<IProject> {
137 const idx = this._getProjectIdx(prj.id);
140 throw new Error('Invalid project id (id=' + prj.id + ')');
142 return this.xdsSvr.deleteProject(prj.id)
146 Sync(prj: IProject): Observable<string> {
147 const idx = this._getProjectIdx(prj.id);
149 throw new Error('Invalid project id (id=' + prj.id + ')');
151 return this.xdsSvr.syncProject(prj.id);
154 private _isUsableProject(p) {
155 return p && p.isInSync &&
156 (p.status === ProjectStatus.Enable) &&
157 (p.status !== ProjectStatus.Syncing);
160 private _getProjectIdx(id: string): number {
161 return this._prjsList.findIndex((item) => item.id === id);
164 private _convToIProject(rPrj: IXDSProjectConfig): IProject {
165 // Convert XDSFolderConfig to IProject
166 const pp: IProject = {
168 serverId: rPrj.serverId,
170 pathClient: rPrj.clientPath,
171 pathServer: rPrj.serverPath,
174 isInSync: rPrj.isInSync,
175 isUsable: this._isUsableProject(rPrj),
176 defaultSdkID: rPrj.defaultSdkID,
177 serverPrjDef: Object.assign({}, rPrj), // do a copy
182 private _addProject(rPrj: IXDSProjectConfig, noNext?: boolean): IProject {
184 // Convert XDSFolderConfig to IProject
185 const pp = this._convToIProject(rPrj);
188 this._prjsList.push(pp);
190 // sort project array
191 this._prjsList.sort((a, b) => {
192 if (a.label < b.label) {
195 if (a.label > b.label) {
202 this.prjsSubject.next(Object.assign([], this._prjsList));