1 import { Injectable, SecurityContext, isDevMode } 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 IUISettings {
43 export interface IProject {
49 type: ProjectTypeEnum;
53 serverPrjDef?: IXDSProjectConfig;
56 defaultSdkID?: string;
57 uiSettings?: IUISettings;
60 const defaultUISettings: IUISettings = {
62 cmdClean: 'rm -rf build && echo Done',
63 cmdPrebuild: 'mkdir -p build && cd build && cmake ..',
64 cmdBuild: 'cd build && make',
65 cmdPopulate: 'cd build && make remote-target-populate',
71 export class ProjectService {
72 projects$: Observable<IProject[]>;
73 curProject$: Observable<IProject>;
75 private _prjsList: IProject[] = [];
76 private prjsSubject = <BehaviorSubject<IProject[]>>new BehaviorSubject(this._prjsList);
77 private _current: IProject;
78 private curPrjSubject = <BehaviorSubject<IProject>>new BehaviorSubject(this._current);
80 constructor(private xdsSvr: XDSAgentService) {
82 this.projects$ = this.prjsSubject.asObservable();
83 this.curProject$ = this.curPrjSubject.asObservable();
85 // Load initial projects list
86 this.xdsSvr.getProjects().subscribe((projects) => {
88 projects.forEach(p => {
89 this._addProject(p, true);
92 // TODO: get previous val from xds-config service / cookie
93 if (this._prjsList.length > 0) {
94 this._current = this._prjsList[0];
95 this.curPrjSubject.next(this._current);
98 this.prjsSubject.next(this._prjsList);
101 // Add listener on projects creation, deletion and change events
102 this.xdsSvr.onProjectAdd().subscribe(prj => this._addProject(prj));
103 this.xdsSvr.onProjectDelete().subscribe(prj => this._delProject(prj));
104 this.xdsSvr.onProjectChange().subscribe(prj => this._updateProject(prj));
107 setCurrent(p: IProject): IProject | undefined {
109 this._current = null;
112 return this.setCurrentById(p.id);
115 setCurrentById(id: string): IProject | undefined {
116 const p = this._prjsList.find(item => item.id === id);
119 this.curPrjSubject.next(this._current);
121 return this._current;
124 getCurrent(): IProject {
125 return this._current;
128 add(prj: IProject): Observable<IProject> {
129 // Send config to XDS server
130 return this.xdsSvr.addProject(this._convToIXdsProject(prj))
131 .map(xp => this._convToIProject(xp));
134 delete(prj: IProject): Observable<IProject> {
135 const idx = this._getProjectIdx(prj.id);
138 throw new Error('Invalid project id (id=' + prj.id + ')');
140 return this.xdsSvr.deleteProject(prj.id)
144 sync(prj: IProject): Observable<string> {
145 const idx = this._getProjectIdx(prj.id);
147 throw new Error('Invalid project id (id=' + prj.id + ')');
149 return this.xdsSvr.syncProject(prj.id);
152 setSettings(prj: IProject): Observable<IProject> {
153 return this.xdsSvr.updateProject(this._convToIXdsProject(prj))
154 .map(xp => this._convToIProject(xp));
157 getDefaultSettings(): IUISettings {
158 return defaultUISettings;
161 /*** Private functions ***/
163 private _isUsableProject(p) {
164 return p && p.isInSync &&
165 (p.status === ProjectStatus.Enable) &&
166 (p.status !== ProjectStatus.Syncing);
169 private _getProjectIdx(id: string): number {
170 return this._prjsList.findIndex((item) => item.id === id);
174 private _convToIXdsProject(prj: IProject): IXDSProjectConfig {
175 const xPrj: IXDSProjectConfig = {
177 serverId: prj.serverId,
178 label: prj.label || '',
179 clientPath: prj.pathClient.trim(),
180 serverPath: prj.pathServer,
182 defaultSdkID: prj.defaultSdkID,
183 clientData: JSON.stringify(prj.uiSettings || defaultUISettings),
188 private _convToIProject(rPrj: IXDSProjectConfig): IProject {
189 let settings = defaultUISettings;
190 if (rPrj.clientData && rPrj.clientData !== '') {
191 settings = JSON.parse(rPrj.clientData);
194 // Convert XDSFolderConfig to IProject
195 const pp: IProject = {
197 serverId: rPrj.serverId,
199 pathClient: rPrj.clientPath,
200 pathServer: rPrj.serverPath,
203 isInSync: rPrj.isInSync,
204 isUsable: this._isUsableProject(rPrj),
205 defaultSdkID: rPrj.defaultSdkID,
206 serverPrjDef: Object.assign({}, rPrj), // do a copy
207 uiSettings: settings,
212 private _addProject(prj: IXDSProjectConfig, noNext?: boolean): IProject {
214 // Convert XDSFolderConfig to IProject
215 const pp = this._convToIProject(prj);
218 this._prjsList.push(pp);
220 // sort project array
221 this._prjsList.sort((a, b) => {
222 if (a.label < b.label) {
225 if (a.label > b.label) {
232 this.prjsSubject.next(this._prjsList);
238 private _delProject(prj: IXDSProjectConfig) {
239 const idx = this._prjsList.findIndex(item => item.id === prj.id);
242 /* tslint:disable:no-console */
243 console.log('Warning: Try to delete project unknown id: prj=', prj);
247 const delId = this._prjsList[idx].id;
248 this._prjsList.splice(idx, 1);
249 if (this._prjsList[idx].id === this._current.id) {
250 this.setCurrent(this._prjsList[0]);
252 this.prjsSubject.next(this._prjsList);
255 private _updateProject(prj: IXDSProjectConfig) {
256 const i = this._getProjectIdx(prj.id);
258 // XXX for now, only isInSync and status may change
259 this._prjsList[i].isInSync = prj.isInSync;
260 this._prjsList[i].status = prj.status;
261 this._prjsList[i].isUsable = this._isUsableProject(prj);
262 this.prjsSubject.next(this._prjsList);