Skip to content

Commit

Permalink
Dashboard: improve a workspace creation flow (#8338)
Browse files Browse the repository at this point in the history
* add che-button-dropdown2 directive and unit tests

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>

* replace "Create" button with dropdown button in top of Create WS page

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>

* add after-creation-dialog component, show it on 'Create' button is clicked

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>

* replace unused dropdown component with new one

- remove che-button-dropdown
- rename che-button-dropdown2 => che-button-dropdown

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>

* fix aligning

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
  • Loading branch information
akurinnoy authored Jan 18, 2018
1 parent 69535fd commit eca10af
Show file tree
Hide file tree
Showing 16 changed files with 648 additions and 208 deletions.
27 changes: 26 additions & 1 deletion src/app/demo-components/demo-components.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
*/
'use strict';

enum Tab {Font, Panel, Selecter, Icons, Buttons, Input, List, Label_container, Stack_selector, Popover};
import {
ICheButtonDropdownMainAction,
ICheButtonDropdownOtherAction
} from '../../components/widget/button-dropdown/che-button-dropdown.directive';

enum Tab {Font, Panel, Selecter, Icons, Dropdown_button, Buttons, Input, List, Label_container, Stack_selector, Popover}

/**
* This class is handling the controller for the demo of components
Expand Down Expand Up @@ -38,6 +43,11 @@ export class DemoComponentsController {

placement: any;

buttonDropdownConfig: {
mainAction: ICheButtonDropdownMainAction;
otherActions: Array<ICheButtonDropdownOtherAction>;
};

/**
* Default constructor that is using resource
* @ngInject for Dependency injection
Expand Down Expand Up @@ -68,6 +78,21 @@ export class DemoComponentsController {
],
selected: 'top'
};
this.buttonDropdownConfig = {
mainAction: {
title: 'Main Action',
type: 'button'
},
otherActions: [{
title: 'Other action 2',
type: 'button',
orderNumber: 2
}, {
title: 'Other action 1',
type: 'button',
orderNumber: 1
}]
};
this.init();
}

Expand Down
19 changes: 19 additions & 0 deletions src/app/demo-components/demo-components.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ <h6>This is h6
</div>
</md-tab>

<md-tab label="Dropdown Button"
md-on-select="demoComponentsController.onSelectTab(demoComponentsController.tab.Dropdown_button)">
<div layout="column"
style="padding-bottom: 100px;">

<label for="dropdownDisabled">The dropdown button is disabled:
<input id="dropdownDisabled" type="checkbox" ng-model="dropdownDisabled">
</label>

<textarea demo-source-render>
<che-button-dropdown button-style="che-button-primary"
main-action-config="demoComponentsController.buttonDropdownConfig.mainAction"
other-actions-config="demoComponentsController.buttonDropdownConfig.otherActions"
button-disabled="dropdownDisabled"></che-button-dropdown>
</textarea>

</div>
</md-tab>

<md-tab label="Buttons"
md-on-select="demoComponentsController.onSelectTab(demoComponentsController.tab.Buttons)">
<div layout="column">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* 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:
* Red Hat, Inc. - initial API and implementation
*/
'use strict';

export class AfterCreationDialogController {

/**
* Service for displaying dialogs.
*/
private $mdDialog: ng.material.IDialogService;

/**
* Default constructor that is using resource
* @ngInject for Dependency injection
*/
constructor($mdDialog: ng.material.IDialogService) {
this.$mdDialog = $mdDialog;
}

/**
* It will hide the dialog box.
*/
close(): void {
this.$mdDialog.cancel();
}

/**
* Opens a workspace in IDE.
*/
openWorkspace(): any {
return this.$mdDialog.hide();
}

/**
* Opens the Workspace Details page.
*/
editWorkspace(): void {
this.$mdDialog.cancel();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!--
Copyright (c) 2015-2018 Red Hat, Inc.
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:
Red Hat, Inc. - initial API and implementation
-->
<che-popup title="Workspace Is Created"
on-close="afterCreationDialogController.close()">
<div class="after-creation-dialog">

<div class="after-creation-dialog-content">
<p>Workspace was successfully created.</p>
<p>You may continue editing workspace or open it in IDE.</p>
</div>

<div flex
layout="row"
layout-align="end center">
<che-button-primary che-button-title="Edit"
ng-click="afterCreationDialogController.editWorkspace()">
</che-button-primary>
<che-button-default che-button-title="Open In IDE"
ng-click="afterCreationDialogController.openWorkspace()">
</che-button-default>
</div>

</div>
</che-popup>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.after-creation-dialog
width 100%

.after-creation-dialog-content
margin 20px 0
79 changes: 76 additions & 3 deletions src/app/workspaces/create-workspace/create-workspace.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,25 @@ import {NamespaceSelectorSvc} from './namespace-selector/namespace-selector.serv
import {StackSelectorSvc} from './stack-selector/stack-selector.service';
import {RandomSvc} from '../../../components/utils/random.service';
import {CheNotification} from '../../../components/notification/che-notification.factory';
import {
ICheButtonDropdownMainAction,
ICheButtonDropdownOtherAction
} from '../../../components/widget/button-dropdown/che-button-dropdown.directive';

/**
* This class is handling the controller for workspace creation.
*
* @author Oleksii Kurinnyi
*/
export class CreateWorkspaceController {
/**
* Dropdown button config.
*/
headerCreateButtonConfig: {
mainAction: ICheButtonDropdownMainAction,
otherActions: Array<ICheButtonDropdownOtherAction>
};
private $mdDialog: ng.material.IDialogService;
/**
* Timeout service.
*/
Expand Down Expand Up @@ -98,7 +110,16 @@ export class CreateWorkspaceController {
* Default constructor that is using resource injection
* @ngInject for Dependency injection
*/
constructor($timeout: ng.ITimeoutService, cheEnvironmentRegistry: CheEnvironmentRegistry, createWorkspaceSvc: CreateWorkspaceSvc, namespaceSelectorSvc: NamespaceSelectorSvc, stackSelectorSvc: StackSelectorSvc, randomSvc: RandomSvc, $log: ng.ILogService, cheNotification: CheNotification) {
constructor($mdDialog: ng.material.IDialogService,
$timeout: ng.ITimeoutService,
cheEnvironmentRegistry: CheEnvironmentRegistry,
createWorkspaceSvc: CreateWorkspaceSvc,
namespaceSelectorSvc: NamespaceSelectorSvc,
stackSelectorSvc: StackSelectorSvc,
randomSvc: RandomSvc,
$log: ng.ILogService,
cheNotification: CheNotification) {
this.$mdDialog = $mdDialog;
this.$timeout = $timeout;
this.cheEnvironmentRegistry = cheEnvironmentRegistry;
this.createWorkspaceSvc = createWorkspaceSvc;
Expand All @@ -123,6 +144,30 @@ export class CreateWorkspaceController {
// when stacks selector is rendered
// and default stack is selected
this.hideLoader = false;

// header toolbar
// dropdown button config
this.headerCreateButtonConfig = {
mainAction: {
title: 'Create',
type: 'button',
action: () => {
this.createWorkspace().then((workspace: che.IWorkspace) => {
this.createWorkspaceSvc.redirectToDetails(workspace);
});
}
},
otherActions: [{
title: 'Open in IDE',
type: 'button',
action: () => {
this.createWorkspace().then((workspace: che.IWorkspace) => {
this.createWorkspaceSvc.redirectToIDE(workspace);
});
},
orderNumber: 1
}]
};
}

/**
Expand Down Expand Up @@ -284,8 +329,10 @@ export class CreateWorkspaceController {

/**
* Creates workspace.
*
* @returns {angular.IPromise<che.IWorkspace>}
*/
createWorkspace(): void {
createWorkspace(): ng.IPromise<che.IWorkspace> {
// update workspace name
this.stack.workspaceConfig.name = this.workspaceName;

Expand All @@ -303,7 +350,33 @@ export class CreateWorkspaceController {
}
let attributes = {stackId: this.stack.id};
let workspaceConfig = angular.copy(this.stack.workspaceConfig);
this.createWorkspaceSvc.createWorkspace(workspaceConfig, attributes);

return this.createWorkspaceSvc.createWorkspace(workspaceConfig, attributes);
}

/**
* Creates a workspace and shows a dialogue window for a user to select
* whether to open Workspace Details page or the IDE.
*
* @param {MouseEvent} $event
*/
createWorkspaceAndShowDialog($event: MouseEvent): void {
this.createWorkspace().then((workspace: che.IWorkspace) => {
this.$mdDialog.show({
targetEvent: $event,
controller: 'AfterCreationDialogController',
controllerAs: 'afterCreationDialogController',
bindToController: true,
clickOutsideToClose: true,
templateUrl: 'app/workspaces/create-workspace/after-creation-dialog/after-creation-dialog.html'
}).then(() => {
// when promise is resolved then open workspace in IDE
this.createWorkspaceSvc.redirectToIDE(workspace);
}, () => {
// when promise is rejected then open Workspace Details page
this.createWorkspaceSvc.redirectToDetails(workspace);
});
});
}

}
15 changes: 8 additions & 7 deletions src/app/workspaces/create-workspace/create-workspace.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<che-toolbar che-title="New Workspace">
<che-button-save-flat class="create-workspace-header-button"
id="create-workspace-button"
che-button-title="Create"
ng-click="createWorkspaceController.createWorkspace()"
ng-disabled="createWorkspaceController.isCreateButtonDisabled()"></che-button-save-flat>
<che-toolbar che-title="New Workspace"
class="create-workspace-toolbar">
<che-button-dropdown button-style="che-button-save-flat"
button-disabled="createWorkspaceController.isCreateButtonDisabled()"
main-action-config="createWorkspaceController.headerCreateButtonConfig.mainAction"
other-actions-config="createWorkspaceController.headerCreateButtonConfig.otherActions"
class="create-workspace-header-button"></che-button-dropdown>
</che-toolbar>

<md-progress-linear md-mode="indeterminate"
Expand Down Expand Up @@ -76,7 +77,7 @@
<che-button-save-flat class="create-workspace-footer-button"
name="saveButton"
che-button-title="Create"
ng-click="createWorkspaceController.createWorkspace()"
ng-click="createWorkspaceController.createWorkspaceAndShowDialog($event)"
ng-disabled="createWorkspaceController.isCreateButtonDisabled()"></che-button-save-flat>
</che-label-container>

Expand Down
34 changes: 19 additions & 15 deletions src/app/workspaces/create-workspace/create-workspace.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,27 +157,22 @@ export class CreateWorkspaceSvc {
* Creates a workspace from config.
*
* @param {che.IWorkspaceConfig} workspaceConfig the config of workspace which will be created
* @return {IPromise<any>}
* @param {any} attributes the attributes of the workspace
* @returns {ng.IPromise<any>}
*/
createWorkspace(workspaceConfig: che.IWorkspaceConfig, attributes?: any): ng.IPromise<any> {
createWorkspace(workspaceConfig: che.IWorkspaceConfig, attributes: any): ng.IPromise<any> {
const namespaceId = this.namespaceSelectorSvc.getNamespaceId(),
projectTemplates = this.projectSourceSelectorService.getProjectTemplates();

return this.checkEditingProgress().then(() => {
workspaceConfig.projects = projectTemplates;
this.addProjectCommands(workspaceConfig, projectTemplates);
return this.cheWorkspace.createWorkspaceFromConfig(namespaceId, workspaceConfig, attributes).then((workspace: che.IWorkspace) => {
this.projectSourceSelectorService.clearTemplatesList();
this.cheWorkspace.getWorkspacesById().set(workspace.id, workspace);
this.cheWorkspace.startUpdateWorkspaceStatus(workspace.id);

return this.cheWorkspace.startWorkspace(workspace.id, workspace.config.defaultEnv).then(() => {
this.redirectToIde(namespaceId, workspace);
this.projectSourceSelectorService.clearTemplatesList();

this.cheWorkspace.getWorkspacesById().set(workspace.id, workspace);
this.cheWorkspace.startUpdateWorkspaceStatus(workspace.id);
return this.cheWorkspace.fetchStatusChange(workspace.id, 'RUNNING');
}).then(() => {
return this.cheWorkspace.fetchWorkspaceDetails(workspace.id);
});
return workspace;
}, (error: any) => {
let errorMessage = 'Creation workspace failed.';
if (error && error.data && error.data.message) {
Expand Down Expand Up @@ -209,11 +204,20 @@ export class CreateWorkspaceSvc {
/**
* Redirects to IDE with specified workspace.
*
* @param {string} namespaceId the namespace ID
* @param {che.IWorkspace} workspace the workspace to open in IDE
*/
redirectToIde(namespaceId: string, workspace: che.IWorkspace): void {
const path = `/ide/${namespaceId}/${workspace.config.name}`;
redirectToIDE(workspace: che.IWorkspace): void {
const path = `/ide/${workspace.namespace}/${workspace.config.name}`;
this.$location.path(path);
}

/**
* Redirects to the details page of the workspace.
*
* @param {che.IWorkspace} workspace the workspace to open in IDE
*/
redirectToDetails(workspace: che.IWorkspace): void {
const path = `/workspace/${workspace.namespace}/${workspace.config.name}`;
this.$location.path(path);
}

Expand Down
14 changes: 14 additions & 0 deletions src/app/workspaces/create-workspace/create-workspace.styl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
top 56px
z-index 2

.create-workspace-toolbar
.che-toolbar-header > div:last-child
bottom 9px

.create-workspace-header-button .che-button-dropdown
button.che-button,
.fa-caret-down
min-height 36px
height 36px

.area-dropdown.dropdown-menu
top 36px


md-content.create-workspace-content
background-color $very-light-grey-background-color !important
overflow auto
Expand Down
Loading

0 comments on commit eca10af

Please sign in to comment.