diff --git a/dashboard/.gitignore b/dashboard/.gitignore index 1c93788306..780355b9a6 100644 --- a/dashboard/.gitignore +++ b/dashboard/.gitignore @@ -23,4 +23,4 @@ docs target/ uE001-README.MD -typings/ +/typings/ diff --git a/dashboard/src/app/ide/ide.controller.ts b/dashboard/src/app/ide/ide.controller.ts index 608f9b886a..aaa13464b8 100644 --- a/dashboard/src/app/ide/ide.controller.ts +++ b/dashboard/src/app/ide/ide.controller.ts @@ -9,39 +9,59 @@ * Codenvy, S.A. - initial API and implementation */ 'use strict'; +import IdeSvc from './ide.service'; +import IdeIFrameSvc from './ide-iframe/ide-iframe.service'; +import {RouteHistory} from '../../components/routing/route-history.service'; +import {CheWorkspace} from '../../components/api/che-workspace.factory'; /** * This class is handling the controller for the IDE * @author Florent Benoit */ class IdeCtrl { + $rootScope: che.IRootScopeService; + $routeParams: che.route.IRouteParamsService; + $timeout: ng.ITimeoutService; + ideSvc: IdeSvc; + ideIFrameSvc: IdeIFrameSvc; + cheWorkspace: CheWorkspace; + + hasData: boolean; + workspaces: any[]; + selectedWorkspace: any = null; + selectedWorkspaceExists: boolean = true; + selectedWorkspaceName: string = null; /** * Default constructor that is using resource * @ngInject for Dependency injection */ - constructor(ideSvc, $routeParams, ideIFrameSvc, $rootScope, cheWorkspace, $timeout, $location, routeHistory) { + constructor($location: ng.ILocationService, $rootScope: ng.IRootScopeService, + $routeParams: ng.route.IRouteParamsService, $timeout: ng.ITimeoutService, ideSvc: IdeSvc, + ideIFrameSvc: IdeIFrameSvc, cheWorkspace: CheWorkspace, routeHistory: RouteHistory) { this.ideSvc = ideSvc; this.ideIFrameSvc = ideIFrameSvc; - this.$rootScope = $rootScope; + this.$rootScope = $rootScope; + this.$routeParams = $routeParams; this.cheWorkspace = cheWorkspace; this.$timeout = $timeout; - this.selectedWorkspace = null; - this.$rootScope.showIDE = false; - $rootScope.wantTokeepLoader = true; + this.$rootScope.showIDE = false; + this.$rootScope.wantTokeepLoader = true; + + this.selectedWorkspaceExists = true; // search the selected workspace - let namespace = $routeParams.namespace; - let workspace = $routeParams.workspaceName; + let namespace = this.$routeParams.namespace; + let workspace = this.$routeParams.workspaceName; if (!workspace) { this.selectedWorkspaceName = null; } else { this.selectedWorkspaceName = workspace; } - let ideAction = $routeParams.action; - let ideParams = $routeParams.ideParams; + let ideAction = this.$routeParams.action; + let ideParams: any = this.$routeParams.ideParams; let selectedWorkspaceIdeUrl = this.cheWorkspace.getIdeUrl(namespace, this.selectedWorkspaceName); if (ideAction) { // send action @@ -51,13 +71,13 @@ class IdeCtrl { routeHistory.popCurrentPath(); // remove action from path - $location.url(selectedWorkspaceIdeUrl, false); + $location.url(selectedWorkspaceIdeUrl); } else if (ideParams) { let params = new Map(); let isArray = angular.isArray(ideParams); if (isArray) { - ideParams.forEach((param) => { + ideParams.forEach((param: string) => { let argParam = this.getParams(param); params.set(argParam.key, argParam.value); }); @@ -66,7 +86,7 @@ class IdeCtrl { params.set(argParam.key, argParam.value); } - for (var [key, val] of params) { + for (let [key, val] of params) { this.ideSvc.setLoadingParameter(key, val); } @@ -74,16 +94,16 @@ class IdeCtrl { routeHistory.popCurrentPath(); // remove action from path - $location.url(selectedWorkspaceIdeUrl, false); + $location.url(selectedWorkspaceIdeUrl); } else { let promise = cheWorkspace.fetchWorkspaces(); - if ($routeParams.showLogs) { + if (this.$routeParams.showLogs) { routeHistory.popCurrentPath(); // remove action from path - $location.url(selectedWorkspaceIdeUrl, false); + $location.url(selectedWorkspaceIdeUrl); $location.replace(); } @@ -98,31 +118,33 @@ class IdeCtrl { /** * Transform colon separator value into key/value - * @param arg - * @returns object with key and value + * @param arg {string} + * @returns {Object} object with key and value */ - getParams(arg) { + getParams(arg: string): {key: string, value: string} { let array = arg.split(':'); - var obj = {}; + let obj: any = {}; obj.key = array[0]; obj.value = array[1]; return obj; } - displayIDE() { + displayIDE(): void { this.ideSvc.displayIDE(); } - updateData() { + updateData(): void { this.hasData = true; this.workspaces = this.cheWorkspace.getWorkspaces(); - for (var i = 0; i < this.workspaces.length; i++) { + for (let i = 0; i < this.workspaces.length; i++) { if (this.workspaces[i].config.name === this.selectedWorkspaceName) { this.selectedWorkspace = this.workspaces[i]; } } + this.selectedWorkspaceExists = !!this.selectedWorkspace; + this.$rootScope.hideLoader = true; if (this.selectedWorkspace) { diff --git a/dashboard/src/app/ide/ide.html b/dashboard/src/app/ide/ide.html index fe90a0e118..4fca02b778 100644 --- a/dashboard/src/app/ide/ide.html +++ b/dashboard/src/app/ide/ide.html @@ -14,8 +14,8 @@
-
No workspace selected. Unable to open IDE
-
+
Workspace doesn't exist, unable to open IDE.
+
diff --git a/dashboard/src/app/ide/ide.service.ts b/dashboard/src/app/ide/ide.service.ts index 9c15f561ce..bdc45c3355 100644 --- a/dashboard/src/app/ide/ide.service.ts +++ b/dashboard/src/app/ide/ide.service.ts @@ -9,32 +9,60 @@ * Codenvy, S.A. - initial API and implementation */ 'use strict'; +import {CheAPI} from '../../components/api/che-api.factory'; +import {CheWorkspace} from '../../components/api/che-workspace.factory'; +import {RouteHistory} from '../../components/routing/route-history.service'; /** * This class is handling the service for viewing the IDE * @author Florent Benoit */ class IdeSvc { + $location: ng.ILocationService; + $log: ng.ILogService; + $mdDialog: ng.material.IDialogService; + $q: ng.IQService; + $rootScope: ng.IRootScopeService; + $sce: ng.ISCEService; + $timeout: ng.ITimeoutService; + $websocket: ng.websocket.IWebSocketProvider; + cheAPI: CheAPI; + cheWorkspace: CheWorkspace; + lodash: any; + proxySettings: any; + routeHistory: RouteHistory; + userDashboardConfig: any; + + ideParams: Map; + lastWorkspace: any; + openedWorkspace: any; + + listeningChannels: string[]; + websocketReconnect: number; + ideAction: string; /** * Default constructor that is using resource * @ngInject for Dependency injection */ - constructor(cheAPI, $rootScope, lodash, $mdDialog, userDashboardConfig, $timeout, $websocket, $sce, proxySettings, $location, routeHistory, $q, $log, cheWorkspace) { - this.cheAPI = cheAPI; - this.$rootScope = $rootScope; - this.lodash = lodash; + constructor($location: ng.ILocationService, $log: ng.ILogService, $mdDialog: ng.material.IDialogService, + $q: ng.IQService, $rootScope: ng.IRootScopeService, $sce: ng.ISCEService, $timeout: ng.ITimeoutService, + $websocket: ng.websocket.IWebSocketProvider, cheAPI: CheAPI, cheWorkspace: CheWorkspace, lodash: any, + proxySettings: any, routeHistory: RouteHistory, userDashboardConfig: any) { + this.$location = $location; + this.$log = $log; this.$mdDialog = $mdDialog; + this.$q = $q; + this.$rootScope = $rootScope; + this.$sce = $sce; this.$timeout = $timeout; this.$websocket = $websocket; - this.userDashboardConfig = userDashboardConfig; - this.$sce = $sce; - this.proxySettings = proxySettings; - this.$location = $location; - this.routeHistory = routeHistory; - this.$q = $q; - this.$log = $log; + this.cheAPI = cheAPI; this.cheWorkspace = cheWorkspace; + this.lodash = lodash; + this.proxySettings = proxySettings; + this.routeHistory = routeHistory; + this.userDashboardConfig = userDashboardConfig; this.ideParams = new Map(); @@ -44,24 +72,24 @@ class IdeSvc { this.listeningChannels = []; } - displayIDE() { - this.$rootScope.showIDE = true; + displayIDE(): void { + (this.$rootScope as any).showIDE = true; } - restoreIDE() { - this.$rootScope.restoringIDE = true; + restoreIDE(): void { + (this.$rootScope as any).restoringIDE = true; this.displayIDE(); } - hasIdeLink() { - return this.$rootScope.ideIframeLink && (this.$rootScope.ideIframeLink !== null); + hasIdeLink(): boolean { + return (this.$rootScope as any).ideIframeLink && ((this.$rootScope as any).ideIframeLink !== null); } - handleError(error) { + handleError(error: any): void { this.$log.error(error); } - startIde(workspace) { + startIde(workspace: any): ng.IPromise { if (this.lastWorkspace) { this.cleanupChannels(this.lastWorkspace.id); } @@ -85,20 +113,20 @@ class IdeSvc { return this.cheWorkspace.fetchWorkspaceDetails(workspace.id); }).then(() => { startWorkspaceDefer.resolve(); - }, (error) => { + }, (error: any) => { this.handleError(error); startWorkspaceDefer.reject(error); }); - this.cheWorkspace.fetchStatusChange(workspace.id, 'ERROR').then((data) => { + this.cheWorkspace.fetchStatusChange(workspace.id, 'ERROR').then((data: any) => { startWorkspaceDefer.reject(data); }); - }, (error) => { + }, (error: any) => { startWorkspaceDefer.reject(error); }); return startWorkspaceDefer.promise.then(() => { if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) { - // Now that the container is started, wait for the extension server. For this, needs to get runtime details + // now that the container is started, wait for the extension server. For this, needs to get runtime details let websocketUrl = this.cheWorkspace.getWebsocketUrl(workspace.id); // try to connect this.websocketReconnect = 50; @@ -107,7 +135,7 @@ class IdeSvc { this.cleanupChannels(workspace.id); } return this.$q.resolve(); - }, (error) => { + }, (error: any) => { if (this.lastWorkspace && workspace.id === this.lastWorkspace.id) { this.cleanupChannels(workspace.id); } @@ -115,11 +143,11 @@ class IdeSvc { }); } - startWorkspace(bus, data) { + startWorkspace(bus: any, data: any): ng.IPromise { let startWorkspacePromise = this.cheAPI.getWorkspace().startWorkspace(data.id, data.config.defaultEnv); - startWorkspacePromise.then((data) => { - let statusLink = this.lodash.find(data.links, (link) => { + startWorkspacePromise.then((data: any) => { + let statusLink = this.lodash.find(data.links, (link: any) => { return link.rel === 'environment.status_channel'; }); @@ -130,8 +158,8 @@ class IdeSvc { this.listeningChannels.push(statusChannel); // for now, display log of status channel in case of errors - bus.subscribe(statusChannel, (message) => { - if (message.eventType === 'DESTROYED' && message.workspaceId === data.id && !this.$rootScope.showIDE) { + bus.subscribe(statusChannel, (message: any) => { + if (message.eventType === 'DESTROYED' && message.workspaceId === data.id && !(this.$rootScope as any).showIDE) { // need to show the error this.$mdDialog.show( this.$mdDialog.alert() @@ -161,7 +189,7 @@ class IdeSvc { }); this.listeningChannels.push(agentChannel); - bus.subscribe(agentChannel, (message) => { + bus.subscribe(agentChannel, (message: any) => { if (message.eventType === 'ERROR' && message.workspaceId === data.id) { // need to show the error this.$mdDialog.show( @@ -173,7 +201,7 @@ class IdeSvc { ); } }); - }, (error) => { + }, (error: any) => { this.handleError(error); this.$q.reject(error); }); @@ -181,7 +209,7 @@ class IdeSvc { return startWorkspacePromise; } - connectToExtensionServer(websocketURL, workspaceId) { + connectToExtensionServer(websocketURL: string, workspaceId: string): void { // try to connect let websocketStream = this.$websocket(websocketURL); @@ -191,7 +219,7 @@ class IdeSvc { }); // on error, retry to connect or after a delay, abort - websocketStream.onError((error) => { + websocketStream.onError((error: any) => { this.websocketReconnect--; if (this.websocketReconnect > 0) { this.$timeout(() => { @@ -212,16 +240,16 @@ class IdeSvc { }); } - setLoadingParameter(paramName, paramValue) { + setLoadingParameter(paramName: string, paramValue: string): void { this.ideParams.set(paramName, paramValue); } - setIDEAction(ideAction) { + setIDEAction(ideAction: string): void { this.ideAction = ideAction; } - openIde(workspaceId) { - this.$rootScope.hideNavbar = false; + openIde(workspaceId: string): void { + (this.$rootScope as any).hideNavbar = false; this.updateRecentWorkspace(workspaceId); @@ -242,16 +270,16 @@ class IdeSvc { } if (this.ideParams) { - for (var [key, val] of this.ideParams) { + for (let [key, val] of this.ideParams) { appendUrl = appendUrl + '&' + key + '=' + val; } this.ideParams.clear(); } if (inDevMode) { - this.$rootScope.ideIframeLink = this.$sce.trustAsResourceUrl(ideUrlLink + appendUrl); + (this.$rootScope as any).ideIframeLink = this.$sce.trustAsResourceUrl(ideUrlLink + appendUrl); } else { - this.$rootScope.ideIframeLink = ideUrlLink + appendUrl; + (this.$rootScope as any).ideIframeLink = ideUrlLink + appendUrl; } let defer = this.$q.defer(); @@ -260,10 +288,10 @@ class IdeSvc { } else { this.cheWorkspace.fetchStatusChange(workspace.id, 'STARTING').then(() => { defer.resolve(); - }, (error) => { + }, (error: any) => { defer.reject(error); this.$log.error('Unable to start workspace: ', error); - }) + }); } defer.promise.then(() => { // update list of recent workspaces @@ -274,7 +302,7 @@ class IdeSvc { /** * Cleanup the websocket channels (unsubscribe) */ - cleanupChannels(workspaceId, websocketStream) { + cleanupChannels(workspaceId: string, websocketStream?: any): void { if (websocketStream != null) { websocketStream.close(); } @@ -282,7 +310,7 @@ class IdeSvc { let workspaceBus = this.cheAPI.getWebsocket().getBus(); if (workspaceBus != null) { - this.listeningChannels.forEach((channel) => { + this.listeningChannels.forEach((channel: any) => { workspaceBus.unsubscribe(channel); }); this.listeningChannels.length = 0; @@ -295,9 +323,9 @@ class IdeSvc { * @param name the name of the link to find (rel attribute) * @returns empty or the href attribute of the link */ - getHrefLink(workspace, name) { + getHrefLink(workspace: any, name: string): string { let links = workspace.links; - var i = 0; + let i = 0; while (i < links.length) { let link = links[i]; if (link.rel === name) { @@ -314,7 +342,7 @@ class IdeSvc { * * @param workspaceId */ - updateRecentWorkspace(workspaceId) { + updateRecentWorkspace(workspaceId: string): void { this.$rootScope.$broadcast('recent-workspace:set', workspaceId); } } diff --git a/dashboard/src/components/typings/che.d.ts b/dashboard/src/components/typings/che.d.ts new file mode 100644 index 0000000000..69bbc4063d --- /dev/null +++ b/dashboard/src/components/typings/che.d.ts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015-2016 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + */ +import che = _che; + +declare namespace _che { + + export interface IRootScopeService extends ng.IRootScopeService { + hideLoader: boolean; + showIDE: boolean; + wantTokeepLoader: boolean; + } + + export namespace route { + + export interface IRouteParamsService extends ng.route.IRouteParamsService { + action: string; + ideParams: string | string[]; + namespace: string; + showLogs: string; + workspaceName: string; + } + + } + +}