From 9346650e4ba74486aaac9b286916cd66e67ea9f3 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Fri, 24 Feb 2017 13:34:14 +0200 Subject: [PATCH 1/4] CHE-3743 allow to cancel workspace start from dashboard Signed-off-by: Oleksii Orel --- dashboard/src/app/ide/ide.service.ts | 10 ---------- .../workspace-details.controller.ts | 11 +++++++++-- .../workspace-details/workspace-details.html | 14 ++++++++------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/dashboard/src/app/ide/ide.service.ts b/dashboard/src/app/ide/ide.service.ts index 21c0b81729a..4cca34f48bd 100644 --- a/dashboard/src/app/ide/ide.service.ts +++ b/dashboard/src/app/ide/ide.service.ts @@ -159,16 +159,6 @@ class IdeSvc { this.listeningChannels.push(statusChannel); // for now, display log of status channel in case of errors 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() - .title('Unable to start the workspace runtime') - .content('Your workspace runtime is no longer available. It was either destroyed or ran out of memory.') - .ariaLabel('Workspace start') - .ok('OK') - ); - } if (message.eventType === 'ERROR' && message.workspaceId === data.id) { let errorMessage = 'Error when trying to start the workspace'; if (message.error) { diff --git a/dashboard/src/app/workspaces/workspace-details/workspace-details.controller.ts b/dashboard/src/app/workspaces/workspace-details/workspace-details.controller.ts index 0fded5d2c1f..c15cef52323 100644 --- a/dashboard/src/app/workspaces/workspace-details/workspace-details.controller.ts +++ b/dashboard/src/app/workspaces/workspace-details/workspace-details.controller.ts @@ -590,9 +590,16 @@ export class WorkspaceDetailsController { } stopWorkspace(): void { - let promise = this.cheWorkspace.stopWorkspace(this.workspaceId, this.getAutoSnapshot()); + let createSnapshot: boolean; + if (this.getWorkspaceStatus() === 'STARTING') { + createSnapshot = false; + } else { + createSnapshot = this.getAutoSnapshot(); + } + let promise = this.cheWorkspace.stopWorkspace(this.workspaceId, createSnapshot); - promise.then(() => {}, (error: any) => { + promise.then(() => { + }, (error: any) => { this.cheNotification.showError(error.data.message !== null ? error.data.message : 'Stop workspace failed.'); this.$log.error(error); }); diff --git a/dashboard/src/app/workspaces/workspace-details/workspace-details.html b/dashboard/src/app/workspaces/workspace-details/workspace-details.html index 65559cfe676..c1f61ddb3cf 100644 --- a/dashboard/src/app/workspaces/workspace-details/workspace-details.html +++ b/dashboard/src/app/workspaces/workspace-details/workspace-details.html @@ -88,14 +88,16 @@
- - +
From f64c0a640bc302d9a2db62a27ebf463db18bfaf9 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Fri, 24 Feb 2017 15:55:59 +0200 Subject: [PATCH 2/4] improve machine runtime popups for dashboard Signed-off-by: Oleksii Orel --- .../edit-variable-dialog.html | 2 +- .../edit-variable-dialog.styl | 28 +++++++++++++++---- .../confirm-dialog/che-confirm-dialog.html | 14 ++++++---- .../confirm-dialog/che-confirm-dialog.styl | 6 ++++ .../widget/list/che-list-header.styl | 2 +- .../components/widget/list/che-list-item.styl | 2 +- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.html b/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.html index a2ddbc8fef7..934a5e5d9c4 100644 --- a/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.html +++ b/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.html @@ -28,7 +28,7 @@ -
+
diff --git a/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.styl b/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.styl index 74c93924b7c..d202461e897 100644 --- a/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.styl +++ b/dashboard/src/app/workspaces/workspace-details/environments/list-env-variables/edit-variable-dialog/edit-variable-dialog.styl @@ -1,13 +1,29 @@ .edit-variable-dialog-content + div.che-label-container + border-bottom none + + div.che-label-container-label + min-width 100px + width 100px + + div.che-input-desktop-value-column + min-width 100% + + input, textarea + width inherit + + .che-label-container:last-child + padding-bottom 0 + + button + margin 0 0 0 10px + + .che-label-container + padding 15px 0 + .edit-variable-dialog-input margin -6px 0 .edit-variable-dialog-textarea margin -8px 0 - - button - margin 0 30px 0 0 - - input, textarea - width 300px diff --git a/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.html b/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.html index 9b588bf4711..ebfeb24e716 100644 --- a/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.html +++ b/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.html @@ -1,12 +1,14 @@
{{cheConfirmDialogController.content}}
- - - - +
+ + + + +
diff --git a/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.styl b/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.styl index 6103a2e83e5..6ad3b9c3367 100644 --- a/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.styl +++ b/dashboard/src/components/service/confirm-dialog/che-confirm-dialog.styl @@ -2,3 +2,9 @@ width 100% margin-top 10px min-height 50px + + div:last-child + margin 15px 0 0 0 + + button + margin 0 0 0 10px diff --git a/dashboard/src/components/widget/list/che-list-header.styl b/dashboard/src/components/widget/list/che-list-header.styl index e1ccecf190e..58e22a850c5 100644 --- a/dashboard/src/components/widget/list/che-list-header.styl +++ b/dashboard/src/components/widget/list/che-list-header.styl @@ -32,7 +32,7 @@ .che-list-add-button > *, .che-list-import-button > *, .che-list-delete-button > * - display inline-block + display inline box-sizing content-box min-width 34px min-height 34px diff --git a/dashboard/src/components/widget/list/che-list-item.styl b/dashboard/src/components/widget/list/che-list-item.styl index 9f33656e1f5..b6851d920d1 100644 --- a/dashboard/src/components/widget/list/che-list-item.styl +++ b/dashboard/src/components/widget/list/che-list-item.styl @@ -9,7 +9,7 @@ border-bottom 1px solid $list-separator-color .che-list-item-content - display inline-block + display inline line-height 40px overflow hidden width 100% From 28de29afa24e08b9942c5a8ed16f57a921a8229f Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Sun, 26 Feb 2017 16:13:58 +0200 Subject: [PATCH 3/4] CHE-3571 hide recipe location link if it isn't url Signed-off-by: Oleksii Orel --- .../environments/environments.controller.ts | 15 ++++++++++++++- .../environments/environments.html | 7 +++---- .../environments/environments.styl | 14 ++++++++++++-- .../widget/text-info/che-text-info.directive.ts | 2 +- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/dashboard/src/app/workspaces/workspace-details/environments/environments.controller.ts b/dashboard/src/app/workspaces/workspace-details/environments/environments.controller.ts index b34cac98876..4ca8589ecff 100644 --- a/dashboard/src/app/workspaces/workspace-details/environments/environments.controller.ts +++ b/dashboard/src/app/workspaces/workspace-details/environments/environments.controller.ts @@ -283,7 +283,7 @@ export class WorkspaceEnvironmentsController { /** * Show dialog to add a new machine to config - * @param $event + * @param $event {MouseEvent} */ showAddMachineDialog($event: MouseEvent): void { this.$mdDialog.show({ @@ -301,6 +301,19 @@ export class WorkspaceEnvironmentsController { }); } + /** + * Gets location URL + * + * @returns {string} + */ + getLocationUrl(): string { + let url: string = ''; + if (this.environment && this.environment.recipe.location && /^https?:\/\//m.test(this.environment.recipe.location)) { + url = this.environment.recipe.location; + } + return url; + } + /** * Sets environments * @param environments: {[envName: string]: any} diff --git a/dashboard/src/app/workspaces/workspace-details/environments/environments.html b/dashboard/src/app/workspaces/workspace-details/environments/environments.html index b67a76ef697..49ae86a98e1 100755 --- a/dashboard/src/app/workspaces/workspace-details/environments/environments.html +++ b/dashboard/src/app/workspaces/workspace-details/environments/environments.html @@ -94,11 +94,10 @@ - + Date: Mon, 27 Feb 2017 18:35:29 +0200 Subject: [PATCH 4/4] CHE-1687 fix sorting rule for recent workspaces Signed-off-by: Oleksii Orel --- .../recent-workspaces.controller.spec.ts | 139 ++++++++++++++++++ .../recent-workspaces.controller.ts | 20 +-- .../recent-workspaces/recent-workspaces.html | 2 +- .../environments/environments.controller.ts | 2 +- .../api/builder/che-workspace-builder.ts | 21 ++- .../components/api/che-workspace.factory.ts | 18 ++- .../components/api/test/che-http-backend.ts | 26 ++++ 7 files changed, 206 insertions(+), 22 deletions(-) create mode 100644 dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.spec.ts diff --git a/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.spec.ts b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.spec.ts new file mode 100644 index 00000000000..30823359523 --- /dev/null +++ b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.spec.ts @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015-2017 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 + */ +'use strict'; +import {CheWorkspace} from '../../../components/api/che-workspace.factory'; +import {CheAPIBuilder} from '../../../components/api/builder/che-api-builder.factory'; +import {CheHttpBackend} from '../../../components/api/test/che-http-backend'; +import IdeSvc from '../../ide/ide.service'; + + +/** + * Test of the NavbarRecentWorkspacesController + */ +describe('NavbarRecentWorkspacesController', () => { + /** + * NavbarRecentWorkspacesController + */ + let navbarRecentWorkspacesController; + + /** + * API builder + */ + let apiBuilder: CheAPIBuilder; + + /** + * Backend for handling http operations + */ + let httpBackend: ng.IHttpBackendService; + + /** + * Che backend + */ + let cheBackend: CheHttpBackend; + + + let workspaces: Array; + + /** + * setup module + */ + beforeEach(angular.mock.module('userDashboard')); + + /** + * Inject factory and http backend + */ + beforeEach(inject(($rootScope: ng.IRootScopeService, cheWorkspace: CheWorkspace, cheAPIBuilder: CheAPIBuilder, cheHttpBackend: CheHttpBackend, $controller: any, ideSvc: IdeSvc, $window: ng.IWindowService, $log: ng.ILogService) => { + apiBuilder = cheAPIBuilder; + cheBackend = cheHttpBackend; + httpBackend = cheHttpBackend.getHttpBackend(); + + let scope = $rootScope.$new(); + navbarRecentWorkspacesController = $controller('NavbarRecentWorkspacesController', { + ideSvc: IdeSvc, cheWorkspace: cheWorkspace, $window: $window, $log: $log, $scope: scope, $rootScope: $rootScope + }); + + workspaces = []; + for (let i = 0; i < 20; ++i) { + let wrkspId = 'workspaceId' + i; + let wrkspName = 'testName' + i; + let wrkspCreateDate = new Date(2001, 1, 1, i, 1).toString(); + let wrkspUpdateDate = new Date(2001, 1, 1, i, 2).toString(); + let wrkspAttr = {'created': Date.parse(wrkspCreateDate), 'updated': Date.parse(wrkspUpdateDate)}; + let workspace = apiBuilder.getWorkspaceBuilder().withId(wrkspId).withAttributes(wrkspAttr).withName(wrkspName).build(); + workspaces.push(workspace); + } + // shuffle the workspaces + workspaces.sort(() => { + return 0.5 - Math.random(); + }); + // providing request + // add workspaces on Http backend + cheBackend.addWorkspaces(workspaces); + + // setup backend + cheBackend.setup(); + + // fetch workspaces + cheWorkspace.fetchWorkspaces(); + + // flush command + httpBackend.flush(); + })); + + /** + * Check assertion after the test + */ + afterEach(() => { + httpBackend.verifyNoOutstandingExpectation(); + httpBackend.verifyNoOutstandingRequest(); + }); + + /** + * Check sorting rule for recent workspaces + */ + it('Check very recent workspaces', inject(() => { + // get recentWorkspaces + let recentWorkspaces = navbarRecentWorkspacesController.getRecentWorkspaces(); + + // check max length + expect(recentWorkspaces.length).toEqual(navbarRecentWorkspacesController.maxItemsNumber); + + // prepare test objects + let testWorkspaces: Array = angular.copy(workspaces); + testWorkspaces.sort((workspace1: che.IWorkspace, workspace2: che.IWorkspace) => { + return workspace2.attributes.updated - workspace1.attributes.updated; + }); + let veryRecentWorkspaceId = testWorkspaces[testWorkspaces.length - 1].id; + + // check default sorting + let lastPosition = recentWorkspaces.length - 1; + for (let i = 0; i < lastPosition; i++) { + expect(recentWorkspaces[i].id).toEqual(testWorkspaces[i].id); + } + // check the last one workspace is equal to the last test workspace and not equal to the very recent workspace, + // because we are going to update very recent workspace in controller and sorting rule should be changed + expect(recentWorkspaces[lastPosition].id).toEqual(testWorkspaces[lastPosition].id); + expect(recentWorkspaces[lastPosition].id).not.toEqual(veryRecentWorkspaceId); + + // update very recent workspace + navbarRecentWorkspacesController.updateRecentWorkspace(veryRecentWorkspaceId); + recentWorkspaces = navbarRecentWorkspacesController.getRecentWorkspaces(); + + // check sorting with veryRecentWorkspace + for (let i = 0; i < lastPosition; i++) { + expect(recentWorkspaces[i].id).toEqual(testWorkspaces[i].id); + } + // check the last one workspace is equal to the very recent workspace and not equal to the last test workspace + expect(recentWorkspaces[lastPosition].id).not.toEqual(testWorkspaces[lastPosition].id); + expect(recentWorkspaces[lastPosition].id).toEqual(veryRecentWorkspaceId); + }) + ); +}); diff --git a/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.ts b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.ts index 0ef8920cc3e..91ce131df5d 100644 --- a/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.ts +++ b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.controller.ts @@ -75,6 +75,14 @@ export class NavbarRecentWorkspacesController { this.fetchWorkspaceSettings(); } + /** + * Returns the MAX_RECENT_WORKSPACES_ITEMS constant + * @returns {number} + */ + get maxItemsNumber(): number { + return MAX_RECENT_WORKSPACES_ITEMS; + } + /** * Retrieves workspace settings. */ @@ -84,10 +92,6 @@ export class NavbarRecentWorkspacesController { } else { this.cheWorkspace.fetchWorkspaceSettings().then(() => { this.prepareDropdownItemsTemplate(); - }, (error: any) => { - if (error.status === 304) { - this.prepareDropdownItemsTemplate(); - } }); } } @@ -171,13 +175,10 @@ export class NavbarRecentWorkspacesController { if (recentWorkspaces.length > MAX_RECENT_WORKSPACES_ITEMS) { let pos: number = veryRecentWorkspace ? recentWorkspaces.indexOf(veryRecentWorkspace) : -1; if (veryRecentWorkspace && pos >= MAX_RECENT_WORKSPACES_ITEMS) { - recentWorkspaces.splice(MAX_RECENT_WORKSPACES_ITEMS - 1, recentWorkspaces.length , veryRecentWorkspace); - } else { - recentWorkspaces.splice(0, MAX_RECENT_WORKSPACES_ITEMS); + recentWorkspaces[MAX_RECENT_WORKSPACES_ITEMS - 1] = veryRecentWorkspace; } } - - this.recentWorkspaces = recentWorkspaces; + this.recentWorkspaces = recentWorkspaces.slice(0, MAX_RECENT_WORKSPACES_ITEMS); } /** @@ -272,6 +273,7 @@ export class NavbarRecentWorkspacesController { */ stopRecentWorkspace(workspaceId: string, createSnapshot: boolean): void { this.cheWorkspace.stopWorkspace(workspaceId, createSnapshot).then(() => { + angular.noop(); }, (error: any) => { this.$log.error(error); }); diff --git a/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.html b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.html index 25d34cc0b33..e302111a51e 100644 --- a/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.html +++ b/dashboard/src/app/navbar/recent-workspaces/recent-workspaces.html @@ -19,7 +19,7 @@ { createSnapshot = createSnapshot === undefined ? this.getAutoSnapshotSettings() : createSnapshot; - return this.remoteWorkspaceAPI.stopWorkspace({workspaceId: workspaceId, createSnapshot: createSnapshot}, {}).$promise; + return this.remoteWorkspaceAPI.stopWorkspace({ + workspaceId: workspaceId, + createSnapshot: createSnapshot + }, {}).$promise; } /** @@ -458,7 +461,6 @@ export class CheWorkspace { */ updateWorkspace(workspaceId: string, data: che.IWorkspace): ng.IPromise { let defer = this.$q.defer(); - let promise = this.remoteWorkspaceAPI.updateWorkspace({workspaceId: workspaceId}, data).$promise; promise.then((data: che.IWorkspace) => { this.workspacesById.set(data.id, data); @@ -609,13 +611,17 @@ export class CheWorkspace { * * @returns {IPromise} */ - fetchWorkspaceSettings(): ng.IPromise { + fetchWorkspaceSettings(): ng.IPromise { let promise = this.remoteWorkspaceAPI.getSettings().$promise; - let resultPromise = promise.then((settings: any) => { + return promise.then((settings: any) => { this.workspaceSettings = settings; + return this.workspaceSettings; + }, (error: any) => { + if (error.status === 304) { + return this.workspaceSettings; + } + return this.$q.reject(error); }); - - return resultPromise; } /** diff --git a/dashboard/src/components/api/test/che-http-backend.ts b/dashboard/src/components/api/test/che-http-backend.ts index 37de914ef54..b2346b820a4 100644 --- a/dashboard/src/components/api/test/che-http-backend.ts +++ b/dashboard/src/components/api/test/che-http-backend.ts @@ -17,6 +17,9 @@ */ export class CheHttpBackend { + private isAutoSnapshot: boolean = false; + private isAutoRestore: boolean = false; + /** * Constructor to use */ @@ -52,6 +55,13 @@ export class CheHttpBackend { this.addWorkspaceAgent(key, tmpWorkspace.runtime); this.httpBackend.when('GET', '/api/workspace/' + key).respond(tmpWorkspace); } + + let workspacSettings = { + 'che.workspace.auto_snapshot': this.isAutoSnapshot, + 'che.workspace.auto_restore': this.isAutoRestore + }; + this.httpBackend.when('GET', '/api/workspace/settings').respond(200, workspacSettings); + this.httpBackend.when('OPTIONS', '/api/').respond({}); this.httpBackend.when('GET', '/api/workspace/settings').respond({}); @@ -90,6 +100,22 @@ export class CheHttpBackend { } + /** + * Set workspace auto snapshot status + * @param isAutoSnapshot {boolean} + */ + setWorkspaceAutoSnapshot(isAutoSnapshot: boolean) { + this.isAutoSnapshot = isAutoSnapshot; + } + + /** + * Set workspace auto restore status + * @param isAutoRestore {boolean} + */ + setWorkspaceAutoRestore(isAutoRestore: boolean) { + this.isAutoRestore = isAutoRestore; + } + /** * Add the given workspaces on this backend