Implemented the 'Get Started' page for UD (#15642)

* Implemented the 'Get Started' page for UD

Signed-off-by: Oleksii Orel <oorel@redhat.com>

* fix locator for Search field

* remove checkSearchField method from UNDER_REPAIR group in WorkspacesListTest

Co-authored-by: Sergey Skorik <sskoryk@redhat.com>
7.20.x
Oleksii Orel 2020-01-14 13:26:48 +02:00 committed by GitHub
parent 9d6cb68aa8
commit b52a2efdce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 673 additions and 203 deletions

View File

@ -15,6 +15,7 @@ import {DashboardLastWorkspacesController} from './last-workspaces/last-workspac
import {DashboardLastWorkspaces} from './last-workspaces/last-workspaces.directive';
import {DashboardPanel} from './dashboard-panel/dashboard-panel.directive';
import {CheWorkspace} from '../../components/api/workspace/che-workspace.factory';
import {MENU_ITEM} from '../navbar/navbar.controller';
export class DashboardConfig {
@ -33,16 +34,17 @@ export class DashboardConfig {
title: 'Dashboard',
templateUrl: 'app/dashboard/dashboard.html',
resolve: {
check: ['$q', '$location', 'cheWorkspace', ($q: ng.IQService, $location: ng.ILocationService, cheWorkspace: CheWorkspace) => {
check: ['$q', '$window', 'cheWorkspace', ($q: ng.IQService, $window: ng.IWindowService, cheWorkspace: CheWorkspace) => {
const defer = $q.defer();
cheWorkspace.fetchWorkspaces().then(() => {
if (cheWorkspace.getWorkspaces().length === 0) {
$location.path('/create-workspace');
}
}, (error: any) => {
if (error.status === 304 && cheWorkspace.getWorkspaces().length === 0) {
$location.path('/create-workspace');
$window.open(MENU_ITEM.getStarted, '_self');
defer.reject();
} else {
defer.resolve();
}
});
return defer.promise;
}]
}
});

View File

@ -9,9 +9,9 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
import { DashboardLastWorkspacesController } from "./last-workspaces.controller";
import { CheWorkspace } from "../../../components/api/workspace/che-workspace.factory";
import { CheNotification } from "../../../components/notification/che-notification.factory";
import {DashboardLastWorkspacesController} from './last-workspaces.controller';
import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory';
import {CheNotification} from '../../../components/notification/che-notification.factory';
declare const expect: (param: any) => {
toHaveBeenCalledTimes: any;

View File

@ -9,8 +9,8 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
import { IAugmentedJQuery, ITemplateCacheService, ICompileService, IRootScopeService, ICompileProvider } from "angular";
import { CheHttpBackend } from "../../../components/api/test/che-http-backend";
import {IAugmentedJQuery, ITemplateCacheService, ICompileService, IRootScopeService, ICompileProvider} from 'angular';
import {CheHttpBackend} from '../../../components/api/test/che-http-backend';
/**
* @author Lucia Jelinkova
@ -22,11 +22,11 @@ describe(`Last workspaces directive >`, () => {
let directiveElement: IAugmentedJQuery;
beforeAll(() => {
// this call replaces the inner directive <che-workspace-item> with mocked value.
// the reason is that we want to test only <dashboard-last-workspaces> itself and not
// underlying directives. Those should be tested separately.
// this call replaces the inner directive <che-workspace-item> with mocked value.
// the reason is that we want to test only <dashboard-last-workspaces> itself and not
// underlying directives. Those should be tested separately.
// NOTE: it is possible that if another test mocks the same directive, it will fail. In that
// case the whole call needs to be extracted and executed before all .spec files.
// case the whole call needs to be extracted and executed before all .spec files.
angular.module('userDashboard').config(function ($compileProvider: ICompileProvider) {
$compileProvider.directive('cheWorkspaceItem', function () {
var def = {
@ -124,8 +124,10 @@ describe(`Last workspaces directive >`, () => {
}
function moreWorkspacesDirectiveTest(workspacesCount: number, workspacesDisplayedCount: number = workspacesCount) {
$scope.dashboardLastWorkspacesController.workspaces =
Array.from(new Array(workspacesCount)).map((x, i) => {return {} });
$scope.dashboardLastWorkspacesController.workspaces =
Array.from(new Array(workspacesCount)).map((x, i) => {
return {}
});
$scope.$digest();
let emptyLabel = directiveElement.find('.last-workspaces-empty-label');

View File

@ -99,9 +99,7 @@ export class DemoComponentsController {
orderNumber: 1
}]
};
}
$onInit(): void {
const tab = this.$location.search().tab;
if (Tab[tab]) {
this.selectedIndex = parseInt(Tab[tab], 10);
@ -199,14 +197,14 @@ export class DemoComponentsController {
{text: 'Starting workspace runtime', inProgressText: 'Retrieving the stack\'s image and launching it', logs: '', hasError: false},
{text: 'Starting workspace agent', inProgressText: 'Agents provide RESTful services like intellisense and SSH', logs: '', hasError: false},
{text: 'Open IDE', inProgressText: '', logs: '', hasError: false}
]
];
this.loader.getLoadingSteps = () => allSteps;
let currentProgressStep = 0;
this.loader.getCurrentProgressStep = () => currentProgressStep;
this.loader.nextStep = () => {
currentProgressStep++;
currentProgressStep = currentProgressStep % (allSteps.length);
}
};
this.loader.pause = () => {
this.loader.paused = !this.loader.paused;
};

View File

@ -306,27 +306,26 @@ Ultima Syriarum est Palaestina per intervalla magna protenta, cultis abundans te
<md-tab label="List"
md-on-select="demoComponentsController.onSelectTab(demoComponentsController.tab.List)">
<div layout="column">
<che-html-source>
<che-list style="margin: 10px; width: 200px">
<textarea demo-source-render>
<che-list style="margin: 10px; width: 200px; float: left;">
<che-list-item ng-repeat="document in demoComponentsController.listItemsDocs">
<div layout="row" flex="100" style="height: 24px; margin: 5px">
<div layout="row" flex="100" style="height: 35px; margin: 5px">
<che-list-item-checked flex="20" che-icon="md-font fa fa-file-text-o"
style="font-size: 20px"></che-list-item-checked>
<div flex="80" style="height: 20px">{{document}}</div>
<div flex="80" style="height: 40px">{{document}}</div>
</div>
</che-list-item>
</che-list>
<che-list style="margin: 10px; width: 200px">
<che-list style="margin: 10px; width: 200px; float: right;">
<che-list-item ng-repeat="task in demoComponentsController.listItemsTasks">
<div layout="row" flex="100" style="height: 24px; margin: 5px">
<div layout="row" flex="100" style="height: 35px; margin: 5px">
<div flex="70">{{task.name}}</div>
<che-list-item-checked flex="30" ng-model="task.done"></che-list-item-checked>
</div>
</che-list-item>
</che-list>
</che-html-source>
</textarea>
</div>
</md-tab>
@ -440,31 +439,38 @@ Ultima Syriarum est Palaestina per intervalla magna protenta, cultis abundans te
<input id="message-content" type="text" ng-model="demoComponentsController.overlayConfig.message.content">
<br/>
<label for="message-visible">Visible</label>
<input id="message-visible" type="checkbox" ng-model="demoComponentsController.overlayConfig.message.visible">
<input id="message-visible" type="checkbox"
ng-model="demoComponentsController.overlayConfig.message.visible">
</fieldset>
<fieldset>
<legend>SAVE button</legend>
<label for="save-button-title">Title</label>
<input id="save-button-title" type="text" ng-model="demoComponentsController.overlayConfig.saveButton.title">
<input id="save-button-title" type="text"
ng-model="demoComponentsController.overlayConfig.saveButton.title">
<br/>
<label for="save-button-disabled">Disabled</label>
<input id="save-button-disabled" type="checkbox" ng-model="demoComponentsController.overlayConfig.saveButton.disabled">
<input id="save-button-disabled" type="checkbox"
ng-model="demoComponentsController.overlayConfig.saveButton.disabled">
</fieldset>
<fieldset>
<legend>APPLY button</legend>
<label for="apply-button-title">Title</label>
<input id="apply-button-title" type="text" ng-model="demoComponentsController.overlayConfig.applyButton.title">
<input id="apply-button-title" type="text"
ng-model="demoComponentsController.overlayConfig.applyButton.title">
<br/>
<label for="apply-button-disabled">Disabled</label>
<input id="apply-button-disabled" type="checkbox" ng-model="demoComponentsController.overlayConfig.applyButton.disabled">
<input id="apply-button-disabled" type="checkbox"
ng-model="demoComponentsController.overlayConfig.applyButton.disabled">
</fieldset>
<fieldset>
<legend>CANCEL button</legend>
<label for="cancel-button-title">Title</label>
<input id="cancel-button-title" type="text" ng-model="demoComponentsController.overlayConfig.cancelButton.title">
<input id="cancel-button-title" type="text"
ng-model="demoComponentsController.overlayConfig.cancelButton.title">
<br/>
<label for="cancel-button-disabled">Disabled</label>
<input id="cancel-button-disabled" type="checkbox" ng-model="demoComponentsController.overlayConfig.cancelButton.disabled">
<input id="cancel-button-disabled" type="checkbox"
ng-model="demoComponentsController.overlayConfig.cancelButton.disabled">
</fieldset>
</form>
</div>
@ -485,14 +491,16 @@ Ultima Syriarum est Palaestina per intervalla magna protenta, cultis abundans te
</div>
<div>
<label for="loader-pause">Pause</label><input id="loader-pause" type="checkbox"
ng-click="demoComponentsController.loader.pause()" value="{{demoComponentsController.loader.paused}}">
ng-click="demoComponentsController.loader.pause()"
value="{{demoComponentsController.loader.paused}}">
</div>
<md-content flex>
<div class="{{demoComponentsController.loader.paused ? 'animation-pause' : ''}}">
<che-loader-crane che-all-steps="demoComponentsController.loader.getLoadingSteps()"
che-exclude-steps="[demoComponentsController.loader.getLoadingSteps().length-1]"
che-step="{{demoComponentsController.loader.getCurrentProgressStep()}}" che-switch-on-iteration="true">
che-exclude-steps="[demoComponentsController.loader.getLoadingSteps().length-1]"
che-step="{{demoComponentsController.loader.getCurrentProgressStep()}}"
che-switch-on-iteration="true">
</che-loader-crane>
</div>
</md-content>

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
import {TemplateListController} from './template-list/template-list.controller';
import {Template} from './template/template.directive';
/**
* @ngdoc controller
* @name getStarted:GetStartedConfig
* @description This class is used for configuring all get started devfiles.
* @author Oleksii Orel
*/
export class GetStartedConfig {
constructor(register: che.IRegisterService) {
register.directive('cheTemplate', Template);
register.controller('TemplateListController', TemplateListController);
// config routes
register.app.config(['$routeProvider', ($routeProvider: any) => {
$routeProvider.accessWhen('/getstarted', {
title: 'Get Started',
templateUrl: 'app/get-started/template-list/template-list.html',
controller: 'TemplateListController',
controllerAs: 'templateListController'
});
}]);
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
import {CreateWorkspaceSvc} from '../../workspaces/create-workspace/create-workspace.service';
import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory';
import {DevfileRegistry, IDevfileMetaData} from '../../../components/api/devfile-registry.factory';
import {
ICheButtonDropdownMainAction,
ICheButtonDropdownOtherAction
} from '../../../components/widget/button-dropdown/che-button-dropdown.directive';
import {CheNotification} from '../../../components/notification/che-notification.factory';
/**
* @ngdoc controller
* @name template.list.controller:TemplateListController
* @description This class is handling the controller for a template list
* @author Oleksii Orel
*/
export class TemplateListController {
static $inject = [
'$q',
'cheWorkspace',
'devfileRegistry',
'createWorkspaceSvc',
'$filter',
'$log',
'cheNotification'];
private $q: ng.IQService;
private $log: ng.ILogService;
private $filter: ng.IFilterService;
private cheNotification: CheNotification;
private devfileRegistry: DevfileRegistry;
private createWorkspaceSvc: CreateWorkspaceSvc;
/**
* Create button config.
*/
private createButtonConfig: {
mainAction: ICheButtonDropdownMainAction,
otherActions: Array<ICheButtonDropdownOtherAction>
};
private isLoading: boolean;
private isCreating: boolean;
private devfileRegistryUrl: string;
private selectedDevfile: IDevfileMetaData | undefined;
private searchValue: string = '';
private devfiles: Array<IDevfileMetaData> = [];
private filteredDevfiles: Array<IDevfileMetaData> = [];
/**
* Default constructor that is using resource
*/
constructor($q: ng.IQService,
cheWorkspace: CheWorkspace,
devfileRegistry: DevfileRegistry,
createWorkspaceSvc: CreateWorkspaceSvc,
$filter: ng.IFilterService,
$log: ng.ILogService,
cheNotification: CheNotification) {
this.$q = $q;
this.$log = $log;
this.$filter = $filter;
this.cheNotification = cheNotification;
this.devfileRegistry = devfileRegistry;
this.createWorkspaceSvc = createWorkspaceSvc;
this.devfileRegistryUrl = cheWorkspace.getWorkspaceSettings().cheWorkspaceDevfileRegistryUrl;
this.createButtonConfig = {
mainAction: {
title: 'Create & Open',
type: 'button',
action: () => {
this.isCreating = true;
this.createWorkspace().then((workspace: che.IWorkspace) => {
this.createWorkspaceSvc.redirectToIDE(workspace);
}).catch(() => this.isCreating = false);
}
},
otherActions: [{
title: 'Create & Proceed Editing',
type: 'button',
action: () => {
this.isCreating = true;
this.createWorkspace().then((workspace: che.IWorkspace) => {
this.createWorkspaceSvc.redirectToDetails(workspace);
}).catch(() => this.isCreating = false);
},
orderNumber: 1
}]
};
this.init();
}
private init(): void {
this.isLoading = true;
this.devfileRegistry.fetchDevfiles(this.devfileRegistryUrl).then((devfiles: Array<IDevfileMetaData>) => {
this.devfiles = devfiles;
this.applyFilter();
}, (error: any) => {
const message = 'Failed to load devfiles meta list.';
this.cheNotification.showError(message);
this.$log.error(message, error);
}).finally(() => {
this.isLoading = false;
});
}
private createWorkspace(): ng.IPromise<che.IWorkspace> {
if (!this.selectedDevfile || !this.selectedDevfile.links || !this.selectedDevfile.links.self) {
return this.$q.reject({data: {message: 'There is no selected Template.'}});
}
const selfLink = this.selectedDevfile.links.self;
return this.devfileRegistry.fetchDevfile(this.devfileRegistryUrl, selfLink).then(() => {
const devfile = this.devfileRegistry.getDevfile(this.devfileRegistryUrl, selfLink);
const attributes = {stackName: this.selectedDevfile.displayName};
return this.createWorkspaceSvc.createWorkspaceFromDevfile(devfile, attributes, true);
});
}
applyFilter(): void {
if (!this.searchValue) {
this.clearFilter();
return;
}
const value = this.searchValue.toLocaleLowerCase();
this.filteredDevfiles = this.$filter('filter')(this.devfiles, devfile => {
return devfile.displayName.toLowerCase().includes(value) || devfile.description.toLowerCase().includes(value);
});
if (this.filteredDevfiles.findIndex(devfile => devfile === this.selectedDevfile) === -1) {
this.selectedDevfile = undefined;
}
}
clearFilter(): void {
if (this.searchValue) {
this.searchValue = '';
}
this.filteredDevfiles = this.devfiles;
}
onSelect(devfile: IDevfileMetaData): void {
this.selectedDevfile = devfile;
}
isCreateButtonDisabled(): boolean {
return this.isCreating || !this.selectedDevfile || !this.selectedDevfile.links || !this.selectedDevfile.links.self;
}
}

View File

@ -0,0 +1,72 @@
<!--
Copyright (c) 2015-2018 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<che-toolbar che-title="Getting Started with Eclipse Che"
class="getting-started-toolbar">
<che-button-primary-flat che-button-title="Create a Custom Workspace" class="custom-template md-raised"
href="#/create-workspace"></che-button-primary-flat>
<che-button-dropdown button-disabled="templateListController.isCreateButtonDisabled()"
main-action-config="templateListController.createButtonConfig.mainAction"
other-actions-config="templateListController.createButtonConfig.otherActions"
button-style="che-button-save-flat"></che-button-dropdown>
</che-toolbar>
<md-content md-scroll-y flex layout="column" md-theme="maincontent-theme" class="getting-started">
<md-progress-linear ng-show="templateListController.isLoading || templateListController.isCreating"
md-mode="indeterminate"></md-progress-linear>
<div ng-hide="templateListController.isLoading" class="getting-started-list">
<!-- Template header -->
<div flex="100" layout="row" layout-align="start center" class="template-header">
<div flex>
<div class="header-title">Select a Template</div>
<div class="header-description">Use a sample template to create your first workspace.</div>
</div>
<div flex class="template-search">
<div flex="100" layout="row">
<div flex="15" class="search-icon" ng-hide="templateListController.searchValue"><i class="fa fa-search"></i>
</div>
<div flex class="search-input">
<input type="text" maxlength="128" ng-model="templateListController.searchValue"
ng-change="templateListController.applyFilter()" placeholder="Search">
</div>
<div flex="15" class="close-icon" ng-click="templateListController.clearFilter();"
ng-show="templateListController.searchValue"><i class="fa fa-close"></i>
</div>
</div>
</div>
<div flex="5" layout-align="end center" class="template-info">
{{templateListController.filteredDevfiles.length}}&nbsp;items
</div>
</div>
<!-- Template area -->
<div class="templates-area">
<!-- Template list -->
<che-template
ng-class="{'selected': templateListController.selectedDevfile === devfile}"
ng-repeat="devfile in templateListController.filteredDevfiles"
devfile="devfile"
ng-click="templateListController.onSelect(devfile)">
</che-template>
<!-- Empty list message -->
<div ng-hide="templateListController.filteredDevfiles.length"
class="che-list-empty">
<span>There are no templates.</span>
</div>
<!-- Create Workspace Button -->
<che-button-save-flat name="saveButton"
che-button-title="Create & Open"
ng-click="templateListController.createButtonConfig.mainAction.action()"
ng-disabled="templateListController.isCreateButtonDisabled()">
</che-button-save-flat>
</div>
</div>
</md-content>

View File

@ -0,0 +1,112 @@
.getting-started-toolbar
border-bottom 1px solid $very-light-grey-background-color
user-select none
md-toolbar
height: 110px;
div.che-toolbar-header div:last-child
bottom initial
div.che-toolbar-title
display inline-block
font-weight bold
text-align left
margin-left 10px
.layout-align-start-center
.custom-template
float left
margin-right 20px
.che-button
margin 0
font-size 14px !important
font-weight bold !important
padding 0 20px !important
height 40px !important
line-height 40px !important
md-content.getting-started
background-color $very-light-grey-background-color
padding-left 10px
& > *
background-color $background-color
.getting-started-list
che-box-shadow()
margin 15px
.template-header
margin 15px
.header-title
font-weight bold
font-size 133%
.template-search
height 34px
max-width 150px
border 1px solid $list-header-blue-color
che-border-radius(2px)
input
width 100%
padding 0 10px
border none
outline none
font-size 12px
text-overflow ellipsis
color $default-dark-color
input:
:-webkit-input-placeholder
position relative
right 8px
color $list-header-blue-color
text-transform capitalize
text-align center
input:
:-moz-placeholder
position relative
right 8px
color $list-header-blue-color
text-transform capitalize
text-align center
.search-icon
text-align end
color $list-header-blue-color
.close-icon
outline none
text-align center
color $default-color
i
line-height 34px
font-size 16px
.template-info
text-align end
font-weight bold
margin 0 10px
.templates-area
width 100%
user-select none
.selected
background-color #F2F7FD
border-color $primary-color
che-button-save-flat
float left
width 100%
padding 15px
.che-button
width inherit
margin 0

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
/**
* @ngDoc directive
* @name template.directive:Template
* @description This class is handling the directive to handle the container with get-started template
* @author Oleksii Orel
*/
export class Template implements ng.IDirective {
restrict = 'E';
templateUrl = 'app/get-started/template/template.html';
replace = true;
scope = {
devfile: '='
};
constructor () { }
}

View File

@ -0,0 +1,24 @@
<!--
Copyright (c) 2015-2018 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<div class="get-started-template">
<div ng-if="devfile.icon" class="devfile-item-icon">
<img src="{{devfile.icon}}">
</div>
<p>
<span class="display-name">{{devfile.displayName}}</span>
</p>
<p>
<span class="description">{{devfile.description}}</span>
</p>
</div>

View File

@ -0,0 +1,33 @@
.get-started-template
outline none
margin 15px 0 0 15px
padding 15px
border 2px solid #ededed
border-radius 2px
display inline-block
overflow hidden
float left
width 260px
height 240px
p
max-width 100%
overflow hidden
text-overflow ellipsis
white-space normal
.devfile-item-icon
width 70px
height 70px
overflow hidden
margin-bottom 10px
img
height inherit
.display-name
font-weight bold
font-size 133%
.description
font-weight bold

View File

@ -25,6 +25,7 @@ import {NavbarConfig} from './navbar/navbar-config';
import {ProxySettingsConfig} from './proxy/proxy-settings.constant';
import {WorkspacesConfig} from './workspaces/workspaces-config';
import {StacksConfig} from './stacks/stacks-config';
import {GetStartedConfig} from './get-started/get-started-config';
import {DemoComponentsController} from './demo-components/demo-components.controller';
import {CheBranding} from '../components/branding/che-branding.factory';
import {ChePreferences} from '../components/api/che-preferences.factory';
@ -152,14 +153,14 @@ angular.element(document).ready(() => {
// load Keycloak
return keycloakLoad(keycloakSettings).then(() => {
// init Keycloak
var theUseNonce: boolean;
let theUseNonce: boolean;
if (typeof keycloakSettings['che.keycloak.use_nonce'] === 'string') {
theUseNonce = keycloakSettings['che.keycloak.use_nonce'].toLowerCase() === 'true';
}
var initOptions = {
let initOptions = {
useNonce: theUseNonce,
redirectUrl: keycloakSettings['che.keycloak.redirect_url.dashboard']
}
};
return keycloakInit(keycloakAuth.config, initOptions);
}).then((keycloak: any) => {
keycloakAuth.isPresent = true;
@ -492,6 +493,7 @@ new NavbarConfig(instanceRegister);
new WorkspacesConfig(instanceRegister);
new DashboardConfig(instanceRegister);
new StacksConfig(instanceRegister);
new GetStartedConfig(instanceRegister);
new FactoryConfig(instanceRegister);
new OrganizationsConfig(instanceRegister);
new TeamsConfig(instanceRegister);

View File

@ -14,22 +14,31 @@ import {CheAPI} from '../../components/api/che-api.factory';
import {CheKeycloak} from '../../components/api/che-keycloak.factory';
import {CheService} from '../../components/api/che-service.factory';
export const MENU_ITEM = {
dashboard: '#/',
getStarted: '#/getstarted',
workspaces: '#/workspaces',
stacks: '#/stacks',
factories: '#/factories',
administration: '#/administration',
usermanagement: '#/admin/usermanagement',
organizations: '#/organizations',
account: '#/account'
};
export class CheNavBarController {
static $inject = ['$mdSidenav', '$scope', '$location', '$route', 'cheAPI', '$window', 'chePermissions', 'cheKeycloak', 'cheService'];
static $inject = ['$mdSidenav',
'$scope',
'$location',
'$route',
'cheAPI',
'$window',
'chePermissions',
'cheKeycloak',
'cheService'];
menuItemUrl = {
dashboard: '#/',
workspaces: '#/workspaces',
administration: '#/administration',
// subsections
plugins: '#/admin/plugins',
factories: '#/factories',
account: '#/account',
stacks: '#/stacks',
organizations: '#/organizations',
usermanagement: '#/admin/usermanagement'
};
menuItemUrl = MENU_ITEM;
accountItems = [
{
@ -87,9 +96,7 @@ export class CheNavBarController {
$onInit(): void {
this.isKeycloackPresent = this.cheKeycloak.isPresent();
this.profile = this.cheAPI.getProfile().getProfile();
this.userServices = this.chePermissions.getUserServices();
// highlight navbar menu item
@ -104,14 +111,13 @@ export class CheNavBarController {
this.isPermissionServiceAvailable = false;
this.resolvePermissionServiceAvailability().then((isAvailable: boolean) => {
this.isPermissionServiceAvailable = isAvailable;
if (isAvailable) {
if (this.chePermissions.getSystemPermissions()) {
this.updateData();
} else {
this.chePermissions.fetchSystemPermissions()
.catch((error: any) => {
// noop
.catch(() => {
// fetch unhandled rejection
})
.finally(() => {
this.updateData();
@ -141,8 +147,8 @@ export class CheNavBarController {
this.organizations = organization.getOrganizations();
const user = this.cheAPI.getUser().getUser();
organization.fetchOrganizationByName(user.name)
.catch((error: any) => {
// noop
.catch(() => {
// fetch unhandled rejection
})
.finally(() => {
this.hasPersonalAccount = angular.isDefined(organization.getOrganizationByName(user.name));
@ -150,10 +156,6 @@ export class CheNavBarController {
});
}
reload(): void {
this.$route.reload();
}
/**
* Returns user nickname.
* @return {string}
@ -167,7 +169,6 @@ export class CheNavBarController {
/**
* Returns number of workspaces.
*
* @return {number}
*/
getWorkspacesNumber(): number {
@ -176,7 +177,6 @@ export class CheNavBarController {
/**
* Returns number of factories.
*
* @return {number}
*/
getFactoriesNumber(): number {
@ -185,7 +185,6 @@ export class CheNavBarController {
/**
* Returns number of all organizations.
*
* @return {number}
*/
getOrganizationsNumber(): number {
@ -198,7 +197,6 @@ export class CheNavBarController {
/**
* Returns number of root organizations.
*
* @return {number}
*/
getRootOrganizationsNumber(): number {
@ -212,22 +210,17 @@ export class CheNavBarController {
return rootOrganizations.length;
}
openLinkInNewTab(url: string): void {
this.$window.open(url, '_blank');
}
/**
* Opens user profile in new browser page.
*/
gotoProfile(): void {
private gotoProfile(): void {
this.$location.path('/account');
}
/**
* Logout.
*/
logout(): void {
private logout(): void {
this.cheKeycloak.logout();
}
}

View File

@ -13,25 +13,25 @@
-->
<div class="left-sidebar-container" id="navbar">
<md-toolbar class="flex-shrink-none">
<md-progress-linear md-mode="indeterminate" ng-hide="navbarController.profile && navbarController.profile.userId"></md-progress-linear>
<md-progress-linear md-mode="indeterminate"
ng-hide="navbarController.profile && navbarController.profile.userId"></md-progress-linear>
<div ng-show="navbarController.profile && navbarController.profile.userId"
layout="column" flex>
<div flex="none"
layout="row" layout-align="start center">
<section class="navbar-top-logo logo-color-white" layout="column" layout-align="center left" ng-include="branding.logoText">
<section class="navbar-top-logo logo-color-white" layout="column" layout-align="center left"
ng-include="branding.logoText">
</section>
<div flex></div>
<navbar-notification id="navbar-notification-container"></navbar-notification>
</div>
<md-divider md-theme="factory-theme"></md-divider>
<div class="admin-navbar-menu">
<section class="left-sidebar-menu" layout="column" layout-align="center center">
<md-list layout="column">
<md-list-item flex class="navbar-subsection-item">
<md-button nav-bar-selected flex che-reload-href href="{{navbarController.menuItemUrl.dashboard}}" layout-align="left"
<md-button nav-bar-selected flex che-reload-href href="{{navbarController.menuItemUrl.dashboard}}"
layout-align="left"
target="_self">
<div class="navbar-item" layout="row" layout-align="start center" id="dashboard-item">
<md-icon md-font-icon="navbar-icon chefont cheico-dashboard" aria-label="Dashboard"></md-icon>
@ -40,11 +40,24 @@
</md-button>
</md-list-item>
<md-list-item flex class="navbar-subsection-item">
<md-button nav-bar-selected flex che-reload-href href="{{navbarController.menuItemUrl.workspaces}}" layout-align="left">
<md-button nav-bar-selected flex che-reload-href href="{{navbarController.menuItemUrl.getStarted}}"
layout-align="left"
target="_self">
<div class="navbar-item" layout="row" layout-align="start center">
<md-icon md-font-icon="navbar-icon fa fa-plus" aria-label="Get Started"></md-icon>
<span>Get Started</span>
</div>
</md-button>
</md-list-item>
<md-list-item flex class="navbar-subsection-item">
<md-button nav-bar-selected flex che-reload-href href="{{navbarController.menuItemUrl.workspaces}}"
layout-align="left">
<div class="navbar-item" layout="row" layout-align="start center" id="workspaces-item">
<md-icon md-font-icon="navbar-icon chefont cheico-workspace"></md-icon>
<span>Workspaces</span>
<span class="navbar-number" ng-show="navbarController.getWorkspacesNumber()">&nbsp;({{navbarController.getWorkspacesNumber()}})</span>
<span class="navbar-number" ng-show="navbarController.getWorkspacesNumber()">
&nbsp;({{navbarController.getWorkspacesNumber()}})
</span>
</div>
</md-button>
</md-list-item>
@ -63,7 +76,9 @@
<div class="navbar-item" layout="row" layout-align="start center" id="factories-item">
<md-icon md-font-icon="navbar-icon chefont cheico-factory"></md-icon>
<span>Factories</span>
<span class="navbar-number" ng-show="navbarController.getFactoriesNumber()">&nbsp;({{navbarController.getFactoriesNumber()}})</span>
<span class="navbar-number" ng-show="navbarController.getFactoriesNumber()">
&nbsp;({{navbarController.getFactoriesNumber()}})
</span>
</div>
</md-button>
</md-list-item>
@ -76,24 +91,25 @@
</div>
</md-button>
</md-list-item>
<md-list-item flex class="navbar-subsection-item" ng-if="navbarController.isPermissionServiceAvailable && !navbarController.userServices.hasInstallationManagerService && !navbarController.hasPersonalAccount">
<md-list-item flex class="navbar-subsection-item"
ng-if="navbarController.isPermissionServiceAvailable && !navbarController.userServices.hasInstallationManagerService && !navbarController.hasPersonalAccount">
<md-button nav-bar-selected flex che-reload-href
href="{{navbarController.menuItemUrl.organizations}}" layout-align="left">
<div class="navbar-item" layout="row" layout-align="start center">
<md-icon md-font-icon="fa navbar-icon fa-sitemap"></md-icon>
<span>Organizations</span>
<span class="navbar-number" ng-show="navbarController.getOrganizationsNumber()">&nbsp;({{navbarController.getOrganizationsNumber()}})</span>
<span class="navbar-number" ng-show="navbarController.getOrganizationsNumber()">
&nbsp;({{navbarController.getOrganizationsNumber()}})
</span>
</div>
</md-button>
</md-list-item>
</md-list>
</section>
</div>
<div class="admin-navbar-menu"
ng-if="navbarController.userServices.hasInstallationManagerService || navbarController.userServices.hasAdminUserService">
<section class="left-sidebar-menu" layout="column" layout-align="start start">
<div class="navbar-section navbar-section-title"
flex layout="row" layout-align="start start">
<span>Administration</span>
@ -104,7 +120,7 @@
<md-button nav-bar-selected flex che-reload-href
href="{{navbarController.menuItemUrl.usermanagement}}"
layout-align="left">
<div class="navbar-item" layout="row" layout-align="start center" id="users-item">
<div class="navbar-item" layout="row" layout-align="start center" id="users-item">
<i class="fa fa-user fa-lg navbar-icon"></i>
<span>Users</span>
</div>
@ -114,34 +130,32 @@
ng-if="navbarController.userServices.hasInstallationManagerService">
<md-button nav-bar-selected flex che-reload-href
href="{{navbarController.menuItemUrl.organizations}}" layout-align="left">
<div class="navbar-item" layout="row" layout-align="start center" id="organizations-item">
<div class="navbar-item" layout="row" layout-align="start center" id="organizations-item">
<md-icon md-font-icon="fa navbar-icon fa-sitemap"></md-icon>
<span>Organizations</span>
<span class="navbar-number" ng-show="navbarController.getRootOrganizationsNumber()">&nbsp;({{navbarController.getRootOrganizationsNumber()}})</span>
<span class="navbar-number" ng-show="navbarController.getRootOrganizationsNumber()">
&nbsp;({{navbarController.getRootOrganizationsNumber()}})
</span>
</div>
</md-button>
</md-list-item>
</md-list>
</section>
</div>
<navbar-recent-workspaces></navbar-recent-workspaces>
<navbar-teams flex layout="column" layout-aling="start strength"></navbar-teams>
<div class="admin-navbar-menu"
layout="column" layout-align="end stretch" flex>
<section class="left-sidebar-menu navbar-account-section"
ng-if="navbarController.isPermissionServiceAvailable">
<md-list layout="column" flex>
<md-list-item class="navbar-subsection-item">
<navbar-dropdown-menu flex
navbar-dropdown-items="navbarController.accountItems"
navbar-dropdown-offset="15 -45">
<md-button ng-href="" layout-align="left">
<div class="navbar-item navbar-identity" layout="row" layout-align="start center" id="navbar-user-panel">
<div class="navbar-item navbar-identity" layout="row" layout-align="start center"
id="navbar-user-panel">
<i class="navbar-icon" flex="none">
<img class="developers-face" id="developers-face" gravatar-src="navbarController.profile.email"/>
</i>
@ -154,9 +168,7 @@
</md-list>
</section>
</div>
</div>
</md-toolbar>
<div class="navbar-iframe-button-left-border" ng-show="showIDE"></div>
</div>

View File

@ -12,6 +12,7 @@
'use strict';
import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory';
import {DevfileRegistry, IDevfileMetaData} from '../../../components/api/devfile-registry.factory';
import {CheNotification} from '../../../components/notification/che-notification.factory';
const DEFAULT_COLUMN = 'displayName';
@ -24,32 +25,42 @@ const DEFAULT_COLUMN = 'displayName';
*/
export class ListStacksController {
static $inject = ['$scope', 'cheWorkspace', '$location', 'devfileRegistry', 'cheListHelperFactory'];
static $inject = ['$scope',
'$location',
'cheWorkspace',
'devfileRegistry',
'cheListHelperFactory',
'$log',
'cheNotification'];
private $location: ng.ILocationService;
private cheWorkspace: CheWorkspace;
private devfileRegistry: DevfileRegistry;
private cheListHelper: che.widget.ICheListHelper;
private $log: ng.ILogService;
private cheNotification: CheNotification;
private orderBy: string;
private searchBy: string;
private searchStr: string;
private pluginRegistryUrl: string;
private devfileRegistryUrl: string;
private isLoading: boolean;
/**
* Default constructor that is using resource
*/
constructor($scope: ng.IScope,
cheWorkspace: CheWorkspace,
$location: ng.ILocationService,
devfileRegistry: DevfileRegistry,
cheListHelperFactory: che.widget.ICheListHelperFactory) {
$location: ng.ILocationService,
cheWorkspace: CheWorkspace,
devfileRegistry: DevfileRegistry,
cheListHelperFactory: che.widget.ICheListHelperFactory,
$log: ng.ILogService,
cheNotification: CheNotification) {
this.$location = $location;
this.cheWorkspace = cheWorkspace;
this.devfileRegistry = devfileRegistry;
this.$log = $log;
this.cheNotification = cheNotification;
this.devfileRegistryUrl = cheWorkspace.getWorkspaceSettings().cheWorkspaceDevfileRegistryUrl;
const helperId = 'devfiles-meta-list';
this.cheListHelper = cheListHelperFactory.getHelper(helperId);
@ -58,9 +69,8 @@ export class ListStacksController {
});
this.orderBy = DEFAULT_COLUMN;
// TODO remove this after cheListHelper improvement
this.searchBy = 'tmpFilterColumn';
//
this.searchBy = '$';
this.loadDevfiles();
}
@ -72,18 +82,12 @@ export class ListStacksController {
loadDevfiles(): void {
this.isLoading = true;
this.pluginRegistryUrl = this.cheWorkspace.getWorkspaceSettings().cheWorkspaceDevfileRegistryUrl;
this.devfileRegistry.fetchDevfiles(this.pluginRegistryUrl).then((data: Array<IDevfileMetaData>) => {
const devfileMetaDatas = data.map((devfileMetaData: IDevfileMetaData) => {
// TODO remove this after cheListHelper improvement
devfileMetaData[this.searchBy]= `${devfileMetaData.displayName} ${devfileMetaData.description} ${devfileMetaData.globalMemoryLimit}`;
return devfileMetaData;
});
this.cheListHelper.setList(devfileMetaDatas, DEFAULT_COLUMN);
this.devfileRegistry.fetchDevfiles(this.devfileRegistryUrl).then((data: Array<IDevfileMetaData>) => {
this.cheListHelper.setList(data, 'displayName');
}, (error: any) => {
console.log('Failed to load devfiles meta list', error);
const message = 'Failed to load devfiles meta list.';
this.cheNotification.showError(message);
this.$log.error(message, error);
}).finally(() => {
this.isLoading = false;
});
@ -102,7 +106,7 @@ export class ListStacksController {
updateFilters(): void {
this.cheListHelper.clearFilters();
const filter: {[searchBy: string]: string} = {};
const filter: { [searchBy: string]: string } = {};
if (this.searchStr) {
filter[this.searchBy] = this.searchStr;
}

View File

@ -13,7 +13,6 @@ md-tab-content.md-active .import-custom-stack .config-import
animation-duration .5s
animation-delay 0s
animation-name devfile-by-url-height
overflow hidden
@keyframes devfile-by-url-height
0%

View File

@ -28,7 +28,7 @@ export class ListWorkspacesCtrl {
static $inject = ['$log', '$mdDialog', '$q', 'lodash', 'cheAPI', 'cheNotification', 'cheBranding', 'cheWorkspace', 'cheNamespaceRegistry',
'confirmDialogService', '$scope', 'cheListHelperFactory'];
$q: ng.IQService;
$q: ng.IQService;
$log: ng.ILogService;
lodash: any;
$mdDialog: ng.material.IDialogService;
@ -39,7 +39,6 @@ export class ListWorkspacesCtrl {
state: string;
isInfoLoading: boolean;
workspaceFilter: any;
userWorkspaces: che.IWorkspace[];
workspaceCreationLink: string;
@ -84,7 +83,6 @@ export class ListWorkspacesCtrl {
this.state = 'loading';
this.isInfoLoading = true;
this.isExactMatch = false;
this.workspaceFilter = {config: {name: ''}};
this.namespaceFilter = {namespace: ''};
// map of all workspaces with additional info by id:
@ -100,8 +98,7 @@ export class ListWorkspacesCtrl {
// callback when search value is changed
this.onSearchChanged = (str: string) => {
this.workspaceFilter.config.name = str;
this.cheListHelper.applyFilter('name', this.workspaceFilter);
this.cheListHelper.applyFilter('$', str ? str : {});
};
// callback when namespace is changed

View File

@ -12,13 +12,14 @@
-->
<che-toolbar che-title="Workspaces" border-none></che-toolbar>
<che-description che-link-title="Learn more." che-link="{{branding.docs.workspace}}">A workspace is where your projects live and run. Create workspaces from stacks that define projects, runtimes, and commands.</che-description>
<che-description che-link-title="Learn more." che-link="{{branding.docs.workspace}}">
A workspace is where your projects live and run. Create workspaces from stacks that define projects, runtimes, and commands.
</che-description>
<md-content md-scroll-y flex layout="column" md-theme="maincontent-theme">
<div class="progress-line"><md-progress-linear md-mode="indeterminate"
ng-show="listWorkspacesCtrl.isInfoLoading || listWorkspacesCtrl.isRequestPending"></md-progress-linear>
<md-content flex class="workspace-list-content" ng-hide="listWorkspacesCtrl.isInfoLoading"><div>
<che-list-header che-input-placeholder="Search"
che-search-model="listWorkspacesCtrl.workspaceFilter.config.name"
che-on-search-change="listWorkspacesCtrl.onSearchChanged(str)"
che-hide-search="listWorkspacesCtrl.userWorkspaces.length === 0"
che-add-button-title="Add Workspace"
@ -48,19 +49,15 @@
class="che-list-item-details">
<che-list-header-column flex-gt-xs="25"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.name"
che-sort-item="devfile.metadata.name"
che-column-title="Name"></che-list-header-column>
<che-list-header-column flex-gt-xs="10"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.environments[0].machineConfigs[0].limits.ram"
che-column-title="RAM"></che-list-header-column>
<che-list-header-column flex-gt-xs="10"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.projects"
che-column-title="Projects"></che-list-header-column>
<che-list-header-column flex-gt-xs="40"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="attributes.stackId"
che-sort-item="attributes.stackName"
che-column-title="Stack"></che-list-header-column>
<che-list-header-column flex-gt-xs="15"
che-column-title="Actions"></che-list-header-column>
@ -69,7 +66,7 @@
</che-list-header>
<che-list ng-show="listWorkspacesCtrl.cheListHelper.visibleItemsNumber > 0">
<che-workspace-item
ng-repeat="workspace in listWorkspacesCtrl.cheListHelper.getVisibleItems() | orderBy:[listWorkspacesCtrl.workspaceOrderBy, 'config.name']"
ng-repeat="workspace in listWorkspacesCtrl.cheListHelper.getVisibleItems() | orderBy:[listWorkspacesCtrl.workspaceOrderBy, 'devfile.metadata.name']"
ng-model="listWorkspacesCtrl.cheListHelper.itemsSelectionStatus[workspace.id]"
is-request-pending="listWorkspacesCtrl.isRequestPending"
che-selectable="true"

View File

@ -25,7 +25,7 @@ export class RandomSvc {
* @param {string[]} list the list of strings to check the uniqueness of new one.
* @return {string}
*/
getRandString({prefix, list}: {prefix?: string, list?: string[]}) {
getRandString({prefix, list}: {prefix?: string, list?: string[]}): string {
let str: string,
limit = 100;

View File

@ -21,10 +21,11 @@
<div flex="100" layout="row">
<div flex="15" class="header-search-icon" ng-show="!inputValue"><i class="fa fa-search"></i></div>
<div flex class="header-search-input">
<input type="text" maxlength="128" ng-placeholder="{{inputPlaceholder}}"
<input type="text" maxlength="128" placeholder="{{inputPlaceholder}}"
data-ng-model="inputValue" ng-change="onSearchChange({str: inputValue})">
</div>
<div flex="10" class="header-close-icon" ng-click="inputValue='';onSearchChange({str: ''})" ng-show="inputValue"><i class="fa fa-close"></i></div>
<div flex="10" class="header-close-icon" ng-click="inputValue='';onSearchChange({str: ''})"
ng-show="inputValue"><i class="fa fa-close"></i></div>
</div>
</div>
<che-filter-selector che-values="filterValues"
@ -36,7 +37,8 @@
che-button-title="{{deleteButtonTitle}}"
ng-click="onDelete()"
ng-disabled="deleteButtonDisable === true"></che-button-primary>
<span ng-if="deleteButtonDisableMessage && !hideDelete && deleteButtonDisable" class="delete-button-disable-message">
<span ng-if="deleteButtonDisableMessage && !hideDelete && deleteButtonDisable"
class="delete-button-disable-message">
{{deleteButtonDisableMessage}}
</span>
</div>

View File

@ -157,26 +157,3 @@
.che-list-item-checkbox-main
display inline-block
.che-list-search-input
float right
width 150px
overflow hidden
display inline-block
box-sizing content-box
min-height 30px !important
height 30px !important
margin-top 15px !important
margin-bottom 0
box-shadow none !important
border-color $list-header-blue-color !important
.search-icon i:before
color $primary-color
.search-input input::-webkit-input-placeholder
color $list-header-blue-color !important
.search-input input::-moz-placeholder
color $list-header-blue-color !important

View File

@ -14,7 +14,7 @@ $toolbar-height = 60px
.che-toolbar a:hover span
text-decoration none
.che-toolbar a,
.che-toolbar *:not(.custom-template) > a,
.che-toolbar md-icon,
.che-toolbar .che-toolbar-subheader,
.che-toolbar .che-toolbar-title-label
@ -76,7 +76,7 @@ $toolbar-height = 60px
.che-toolbar-control-button md-icon
vertical-align inherit
.che-toolbar .che-button.md-button
.che-toolbar *:not(.custom-template) > .che-button.md-button
color $white-color !important
font-size 13px !important
font-weight bold !important

View File

@ -4106,6 +4106,18 @@ glob@7.0.x:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@7.1.5:
version "7.1.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^3.2.11:
version "3.2.11"
resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d"
@ -4147,18 +4159,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.5:
version "7.1.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@~3.1.21:
version "3.1.21"
resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd"
@ -7350,22 +7350,22 @@ moment@*:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.9.0.tgz#77ec1175fa294f42627f10c8e6de6302c036f6d5"
integrity sha1-d+wRdfopT0JifxDI5t5jAsA29tU=
monaco-editor-core@^0.14.6:
monaco-editor-core@0.14.6:
version "0.14.6"
resolved "https://registry.yarnpkg.com/monaco-editor-core/-/monaco-editor-core-0.14.6.tgz#25fae6a2e7c7da6eb2a3bba653a283627dc624e4"
integrity sha512-B7ZFmTO/4L+ff07Qmxt2TB0/nux80dVyah5AQaeuWCAD3H5wuaGOszAWBZEU6hEalSYTXv+O9bnTxnjXZG6tuw==
monaco-languageclient@^0.9.0:
version "0.9.1"
resolved "https://registry.yarnpkg.com/monaco-languageclient/-/monaco-languageclient-0.9.1.tgz#dccd26ae0be4d1014395b406e924baae9f8eb9b5"
integrity sha512-mDwbYk67UVPf41RnhfMLRME08NsK2/JeqCkkhPL+wef6rZQNHRb/U2bMMuW/MVVM/yT2DYFy5f7cLNm63FYGMw==
monaco-languageclient@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/monaco-languageclient/-/monaco-languageclient-0.9.0.tgz#4b65684e277edab07625e76eb3d3d93e8f2130fa"
integrity sha512-N8IdHUnV8Sq2nfm3dSZ0SpILmGhqrTvdXkL0BFfJvV2vcKYVVQ36AXJNqCRImmovkeNUHLyQMeHTqOwvMMVxCQ==
dependencies:
glob-to-regexp "^0.3.0"
vscode-base-languageclient "4.4.0"
vscode-jsonrpc "^3.6.2"
vscode-uri "^1.0.5"
monaco-languages@^1.8.0:
monaco-languages@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/monaco-languages/-/monaco-languages-1.8.0.tgz#aeacf40b0f8d0130c4b43c6c143b55f86e6b909d"
integrity sha512-vC/lqNgSslQT3vSlNOpyT34ELK0eoNbA/rHUvTUjQemIiR1GpRMKhuwB21BqzWk+0MjZuJydGSCQMCebBge7jg==
@ -8998,6 +8998,11 @@ regenerate@^1.2.1:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
regenerator-runtime@0.13.3:
version "0.13.3"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
regenerator-runtime@^0.10.5:
version "0.10.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
@ -9008,11 +9013,6 @@ regenerator-runtime@^0.11.0:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
regenerator-runtime@^0.13.3:
version "0.13.3"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
regenerator-transform@^0.10.0:
version "0.10.1"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
@ -10653,10 +10653,10 @@ ultron@1.0.x:
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=
umd-compat-loader@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/umd-compat-loader/-/umd-compat-loader-2.1.2.tgz#abf89be1591940a236cf8fa87f88d6d6f5a8da35"
integrity sha512-RkTlsfrCxUISWqiTtYFFJank7b2Hhl4V2pc29nl0xOEGvvuVkpy1xnufhXfTituxgpW0HSrDk0JHlvPYZxEXKQ==
umd-compat-loader@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/umd-compat-loader/-/umd-compat-loader-2.1.1.tgz#1a44674f57deeb429f4d1533668453a3cf322422"
integrity sha512-rbU2eHzW6tp64cF3X9o93wNYeG6hwvmTTktnd4nW9CdY2rMdw/py0J4C9h/b9HNfn1H0HF7jQQNxGvrm5qio7g==
dependencies:
ast-types "^0.9.2"
loader-utils "^1.0.3"
@ -11024,7 +11024,12 @@ vscode-languageserver-protocol@3.14.1, vscode-languageserver-protocol@^3.10.0:
vscode-jsonrpc "^4.0.0"
vscode-languageserver-types "3.14.0"
vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.10.0, vscode-languageserver-types@^3.14.0:
vscode-languageserver-types@3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389"
integrity sha512-vxmCsVZGwq8X40SuLP8Ix7V0rq5V/7iQUjRVe2Oxm+TbmjxtjK4dpHHXQCUawjA4fhPA9FwjSRbDhbvQmYCfMw==
vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.14.0:
version "3.14.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743"
integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==

View File

@ -105,7 +105,7 @@ public class DashboardFactories {
String BULK_CHECKBOX = "//md-checkbox[@aria-label='Factory list']";
String DELETE_FACTORY_BTN_ID = "delete-item-button";
String DELETE_DIALOG_BUTTON_ID = "ok-dialog-button";
String SEARCH_FACTORY_FIELD = "//input[@ng-placeholder='Search']";
String SEARCH_FACTORY_FIELD = "//input[placeholder='Search']";
}
private interface AddActionWindow {

View File

@ -36,7 +36,7 @@ public class WorkspaceShare {
private interface Locators {
String ADD_DEVELOPER_BUTTON_XPATH = "//che-button-primary[@che-button-title='Add Developer']";
String BULK_SELECTION_ID = "share-workspace-bulk-selection";
String FILTER_MEMBERS_BY_NAME_FIELD_XPATH = "//input[@ng-placeholder='Search']";
String FILTER_MEMBERS_BY_NAME_FIELD_XPATH = "//share-workspace//input[@placeholder='Search']";
String MEMBER_ITEM_XPATH_PATTERN = "//div[@id='member-email-%s']";
String MEMBER_NAME_XPATH = MEMBER_ITEM_XPATH_PATTERN + "//span[@data-user-email]";
String MEMBER_CHECKBOX_XPATH = MEMBER_ITEM_XPATH_PATTERN + "//md-checkbox";

View File

@ -72,7 +72,7 @@ public class Workspaces {
String DELETE_WORKSPACE_BTN = "delete-item-button";
String DELETE_DIALOG_BUTTON = "//md-dialog[@role='dialog']//button[text()='Delete']";
String BULK_CHECKBOX = "//md-checkbox[@aria-label='Workspace list']";
String SEARCH_WORKSPACE_FIELD = "//input[@ng-placeholder='Search']";
String SEARCH_WORKSPACE_FIELD = "//input[@placeholder='Search']";
String NO_WORKSPACE_FOUND = "//span[text()='No workspaces found.']";
String WORKSPACE_ITEM_NAME = "//div[@class='workspace-name-clip' and contains(@id, '/%s')]";
String WORKSPACE_ITEM_XPATH = "//div[@id='ws-name-%s']";

View File

@ -13,7 +13,6 @@ package org.eclipse.che.selenium.dashboard.workspaces;
import static java.util.Arrays.asList;
import static org.eclipse.che.commons.lang.NameGenerator.generate;
import static org.eclipse.che.selenium.core.TestGroup.UNDER_REPAIR;
import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces.Locators.WORKSPACE_ITEM_ADD_PROJECT_BUTTON;
import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces.Locators.WORKSPACE_ITEM_CONFIGURE_BUTTON;
import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces.Locators.WORKSPACE_ITEM_STOP_START_WORKSPACE_BUTTON;
@ -177,7 +176,7 @@ public class WorkspacesListTest {
workspaces.waitDeleteWorkspaceBtnDisappearance();
}
@Test(groups = UNDER_REPAIR)
@Test
public void checkSearchField() throws Exception {
int nameLength = WORKSPACE_NAME.length();
int existingWorkspacesCount = testWorkspaceServiceClient.getWorkspacesCount();