Skip to content

Commit

Permalink
[UD] Added ability to disable some menu items and corresponding routes (
Browse files Browse the repository at this point in the history
#15777)

* [UD] Added ability to disable some menu items and corresponding routes

User Dashboard can disable some of menu items located in the side bar and corresponding routes.

Signed-off-by: Oleksii Kurinnyi <[email protected]>

* fixup! [UD] Added ability to disable some menu items and corresponding routes

* fixup! fixup! [UD] Added ability to disable some menu items and corresponding routes
  • Loading branch information
akurinnoy authored Jan 24, 2020
1 parent 54c0d1b commit 80df9d9
Show file tree
Hide file tree
Showing 21 changed files with 534 additions and 150 deletions.
83 changes: 58 additions & 25 deletions dashboard/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
## About Eclipse Che

Eclipse Che is a next generation Eclipse IDE and open source alternative to IntelliJ. This repository is licensed under the Eclipse Public License 2.0. Visit [Eclipse Che's Web site](https://eclipse.org/che) for feature information or the main [Che assembly repository](https://github.com/codenvy/che) for a description of all participating repositories.

Che Dashboard

==============

## Requirements

- Docker

## Quick start
Expand All @@ -22,54 +25,61 @@ $ mvn -Pnative clean install
```

Required tools for native build:

- Python `v2.7.x`(`v3.x.x`currently not supported)
- Node.js `v8.x.x` or `v9.x.x`
- yarn `v1.13.0` or higher
- gulp

Installation instructions for Node.js can be found on the following [link](https://docs.npmjs.com/getting-started/installing-node).
Installation instructions for Node.js can be found on the following [link](https://docs.npmjs.com/getting-started/installing-node).

## Running

In order to run the project, the serve command is used

```sh
$ gulp serve
```

It will launch the server and then the project can be tested on http://localhost:3000

By default it will use http://localhost:8080 as a remote server, so make sure that Che is running locally. More details about how to do that can be found on the following [link](https://github.com/eclipse/che/wiki/Development-Workflow#build-and-run---tomcat)

The argument `--server <url>` may allow to use another server. (url is for example http://my-server.com)


```sh
$ gulp serve:dist
```

This command will provide the 'minified/optimised' version of the application

This is a good check for testing if the final rendering is OK


## Tests

The application contains both unit tests and e2e tests (end-to-end)

Unit tests

```sh
$ gulp test
```

e2e tests

```sh
$ gulp protractor
```

Both tests

```sh
$ gulp alltests
```

Note: before pushing contribution, these tests should always work

#Architecture design
# Architecture design

## Ecmascript 2015/es6

Expand All @@ -80,70 +90,77 @@ So application is written with the new language but the resulting build is Javas
Among new features, Class, arrow functions, etc

## Styling/css

[Stylus](https://github.com/LearnBoost/stylus) is used for produced the final CSS.

Variables, simple syntax, etc is then provided


## Code convention

### indent

There is a .editorconfig file that is indicating the current identation which is

```
indent_style = space
indent_size = 2
```

### syntax

The syntax is checked by jshint (through .jshintrc file)

Also when launching gulp serve command, there is a report on each file that may have invalid data

For example use single quote 'hello', no "double quote", use === and !=== and not == or !=

For example use single quote `'hello'`, no `"double quote"`, use `===` and `!===` and not `==` or `!=`

### name of the files
Controllers are in files named <name>.controller.js

Directives: <name>.directive.js
Controllers are in files named `[name].controller.ts`

Directives: `[name].directive.ts`

Templates: <name>.html
Templates: `[name].html`

Factories: <name>.factory.js
Factories: `[name].factory.ts`

Unit test: <name>.spec.js (for my-example.factory.js will be named my-example.spec.js)
Unit test: `[name].spec.ts` (for `my-example.factory.ts` will be named `my-example.spec.ts`)

#### About e2e tests

If a 'project' page needs to be tested:

project.po.js will contain the Page Object pattern (all methods allowing to get HTML elements on the page)
`project.po.ts` will contain the Page Object pattern (all methods allowing to get HTML elements on the page)

project.spec.js will have the e2e test
`project.spec.ts` will have the e2e test

project.mock.js will provide some mock for the test
`project.mock.ts` will provide some mock for the test

## source tree

Each 'page' needs to have its own folder which include:

controller, directive, template, style for the page

for a 'list-projects' page, the folder tree will have

```
list-projects
- list-projects.controller.js
- list-projects.html
- list-projects.styl
```

## AngularJS recommandation
As classes are available, the controller will be designed as es6 classes.
## AngularJS recommendation

All injection required will be done through the constructor by adding also the static $inject = ['$toBeInjected']; line.
As classes are available, the controller will be designed as es6 classes.

All injection required will be done through the constructor by adding also the static `$inject = ['$toBeInjected'];` line.

Also properties are bound with this. scope (so avoid to use $scope in injection as this will be more aligned with AngularJS 2.0 where scope will disappear)

example

```js
/**
* Defines a controller
Expand Down Expand Up @@ -173,8 +190,8 @@ export default CheToggleCtrl;

So, no need to add specific arrays for injection.


By using the this syntax, the controllerAs needs to be used when adding the router view

```js
.when('/myURL', {
templateUrl: 'mytemplate.html',
Expand All @@ -183,11 +200,12 @@ By using the this syntax, the controllerAs needs to be used when adding the rout
})
```

And then, when there is a need to interact with code of a controller, the controllerAs value is used.
And then, when there is a need to interact with code of a controller, the `controllerAs` value is used.

```html
<div>Selected book is {{myCtrl.selectedBook}}</div>
```

Note that as if scope was using, the values are always prefixed

## Directives
Expand All @@ -196,23 +214,38 @@ The whole idea is to be able to reuse some 'widgets' when designing HTML pages

So instead that each page make the design/css for all buttons, inputs, it should be defined in some widget components.

The components are located in the src/components/widget folder
The components are located in the `src/components/widget` folder

It includes toggle buttons, selecter, etc.
It includes toggle buttons, selector, etc.

A demo page is also provided to browse them: localhost:5000/#/demo-components


## API of Che

Each call to the Che API shouldn't be made directly from the controller of the page.
For that, it has to use Che API fatories which are handling the job (with promises operations)
For that, it has to use Che API factories which are handling the job (with promises operations)

By injecting 'cheAPI' inside a controller, all operations can be called.

for example cheAPI.getWorkspace().getWorkspaces() for getting the array of the current workspaces of the user
for example `cheAPI.getWorkspace().getWorkspaces()` for getting the array of the current workspaces of the user

Mocks are also provided for the Che API, allowing to emulate a real backend for unit tests or e2e tests

## Configurability

The `configuration.menu.disabled` field in [product.json](/src/assets/branding/product.json) allows users to list there menu entries they want to hide in left navigation bar. Along with that corresponding routes also will be disabled.

Available values are `'administration'`, `'factories'`, `'getstarted'`, `'organizations'`, `'stacks'`.

```json
// product.json
{
// disables the `Organizations` menu item and prevents opening views
// with list of available organizations or an organization details
"configuration": {
"menu": {
"disabled": ["organizations"]
}
}
}
```
33 changes: 33 additions & 0 deletions dashboard/src/app/administration/administration-config.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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
*/

import { CheDashboardConfigurationService } from '../../components/branding/che-dashboard-configuration.service';

export class AdministrationConfigService {

static $inject = [
'cheDashboardConfigurationService'
];

private cheDashboardConfigurationService: CheDashboardConfigurationService;

constructor(
cheDashboardConfigurationService: CheDashboardConfigurationService,
) {
this.cheDashboardConfigurationService = cheDashboardConfigurationService;
}

allowAdministrationRoutes(): ng.IPromise<void> {
return this.cheDashboardConfigurationService.allowRoutes('administration');
}

}
14 changes: 11 additions & 3 deletions dashboard/src/app/administration/administration-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
*/
'use strict';


import {DockerRegistryList} from './docker-registry/docker-registry-list/docker-registry-list.directive';
import {DockerRegistryListController} from './docker-registry/docker-registry-list/docker-registry-list.controller';
import {EditRegistryController} from './docker-registry/docker-registry-list/edit-registry/edit-registry.controller';

import { AdministrationConfigService } from './administration-config.service';

export class AdministrationConfig {

Expand All @@ -25,11 +24,20 @@ export class AdministrationConfig {

register.controller('EditRegistryController', EditRegistryController);

register.service('administrationConfigService', AdministrationConfigService);

// config routes
register.app.config(['$routeProvider', ($routeProvider: che.route.IRouteProvider) => {
$routeProvider.accessWhen('/administration', {
title: 'Administration',
templateUrl: 'app/administration/administration.html'
templateUrl: 'app/administration/administration.html',
resolve: {
init: [
'administrationConfigService',
(svc: AdministrationConfigService) => {
return svc.allowAdministrationRoutes();
}]
}
});
}]);

Expand Down
2 changes: 1 addition & 1 deletion dashboard/src/app/dashboard/dashboard-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class DashboardConfig {
const defer = $q.defer();
cheWorkspace.fetchWorkspaces().then(() => {
if (cheWorkspace.getWorkspaces().length === 0) {
$window.open(MENU_ITEM.getStarted, '_self');
$window.open(MENU_ITEM.getstarted, '_self');
defer.reject();
} else {
defer.resolve();
Expand Down
48 changes: 32 additions & 16 deletions dashboard/src/app/factories/factories-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/
'use strict';


import {FactoryDetailsConfig} from './factory-details/factory-details-config';
import {CreateFactoryConfig} from './create-factory/create-factory-config';
import {LastFactoriesConfig} from './last-factories/last-factories-config';
Expand All @@ -20,6 +19,7 @@ import {FactoryItemController} from './list-factories/factory-item/factory-item.
import {CheFactoryItem} from './list-factories/factory-item/factory-item.directive';
import {LoadFactoryController} from './load-factory/load-factory.controller';
import {LoadFactoryService} from './load-factory/load-factory.service';
import { FactoryConfigService } from './factory-config.service';

export class FactoryConfig {

Expand All @@ -32,27 +32,44 @@ export class FactoryConfig {
register.controller('LoadFactoryController', LoadFactoryController);
register.service('loadFactoryService', LoadFactoryService);

register.service('factoryConfigService', FactoryConfigService);

// config routes
register.app.config(['$routeProvider', ($routeProvider: che.route.IRouteProvider) => {
$routeProvider.accessWhen('/factories', {
title: 'Factories',
templateUrl: 'app/factories/list-factories/list-factories.html',
controller: 'ListFactoriesController',
controllerAs: 'listFactoriesCtrl'
})
$routeProvider
.accessWhen('/factories', {
title: 'Factories',
templateUrl: 'app/factories/list-factories/list-factories.html',
controller: 'ListFactoriesController',
controllerAs: 'listFactoriesCtrl',
resolve: {
initData: ['factoryConfigService', (svc: FactoryConfigService) => {
return svc.allowFactoriesRoutes();
}]
}
})
.accessWhen('/load-factory', {
title: 'Load Factory',
templateUrl: 'app/factories/load-factory/load-factory.html',
controller: 'LoadFactoryController',
controllerAs: 'loadFactoryController'
controllerAs: 'loadFactoryController',
resolve: {
initData: ['factoryConfigService', (svc: FactoryConfigService) => {
return svc.allowFactoriesRoutes();
}]
}
})
.accessWhen('/load-factory/:id', {
title: 'Load Factory',
templateUrl: 'app/factories/load-factory/load-factory.html',
controller: 'LoadFactoryController',
controllerAs: 'loadFactoryController'
});

.accessWhen('/load-factory/:id', {
title: 'Load Factory',
templateUrl: 'app/factories/load-factory/load-factory.html',
controller: 'LoadFactoryController',
controllerAs: 'loadFactoryController',
resolve: {
initData: ['factoryConfigService', (svc: FactoryConfigService) => {
return svc.allowFactoriesRoutes();
}]
}
});
}]);

// config files
Expand All @@ -63,4 +80,3 @@ export class FactoryConfig {
/* tslint:enable */
}
}

Loading

0 comments on commit 80df9d9

Please sign in to comment.