Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make plugins/editors show one entry for each plugin with a drop down for version #13942

Merged
merged 3 commits into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
import {IPlugin, PluginRegistry} from '../../../../components/api/plugin-registry.factory';
import {IPlugin, PluginRegistry, IPluginRow} from '../../../../components/api/plugin-registry.factory';
import {CheNotification} from '../../../../components/notification/che-notification.factory';
import {CheWorkspace} from '../../../../components/api/workspace/che-workspace.factory';

Expand All @@ -36,7 +36,7 @@ export class WorkspaceEditorsController {
isLoading: boolean;

editorOrderBy = 'displayName';
editors: Array<IPlugin> = [];
editors: Map<string, IPluginRow> = new Map(); // the key is publisher/name
selectedEditor: string = '';
editorFilter: any;

Expand Down Expand Up @@ -80,14 +80,26 @@ export class WorkspaceEditorsController {
* Loads the list of plugins from registry.
*/
loadPlugins(): void {
this.editors = [];
this.editors = new Map();
this.isLoading = true;
this.pluginRegistry.fetchPlugins(this.pluginRegistryLocation).then((result: Array<IPlugin>) => {
this.pluginRegistry.fetchPlugins(this.pluginRegistryLocation).then((result: Array<IPluginRow>) => {
this.isLoading = false;
result.forEach((item: IPlugin) => {
result.forEach((item: IPluginRow) => {
if (item.type === EDITOR_TYPE) {
this.editors.push(item);
};

// since plugin registry returns an array of plugins/editors with a single version we need to unite the editor versions into one
const pluginID = `${item.publisher}/${item.name}`;

item.selected = 'latest'; // set the default selected to latest

if (this.editors.has(pluginID)) {
const foundPlugin = this.editors.get(pluginID);
foundPlugin.versions.push(item.version);
} else {
item.versions = [item.version];
this.editors.set(pluginID, item);
}
}
});

this.updateEditors();
Expand All @@ -112,12 +124,39 @@ export class WorkspaceEditorsController {
*
* @param {IPlugin} plugin
*/
updateEditor(plugin: IPlugin): void {
updateEditor(plugin: IPluginRow): void {
if (plugin.type === EDITOR_TYPE) {
this.selectedEditor = plugin.isEnabled ? plugin.id : '';
const pluginID = `${plugin.publisher}/${plugin.name}`;
const pluginIDWithVersion = `${plugin.publisher}/${plugin.name}/${plugin.selected}`;

this.selectedEditor = plugin.isEnabled ? pluginIDWithVersion : '';

this.editors.get(pluginID).selected = plugin.selected;
this.editors.get(pluginID).id = pluginIDWithVersion;

this.cheWorkspace.getWorkspaceDataManager().setEditor(this.workspace, this.selectedEditor);
}


this.onChange();
}

/**
* Update the selected editor version when the editor version dropdown is changed
*
* @param {IPlugin} plugin
*/
updateSelectedEditorVersion(plugin: IPluginRow): void {
if (plugin.type === EDITOR_TYPE) {
const pluginID = `${plugin.publisher}/${plugin.name}`;

// create a plugin id with the newly selected version
const pluginIDWithVersion = `${pluginID}/${plugin.selected}`;

this.editors.get(pluginID).selected = plugin.selected;
this.editors.get(pluginID).id = pluginIDWithVersion;

this.cheWorkspace.getWorkspaceDataManager().setEditor(this.workspace, pluginIDWithVersion);
}
this.onChange();
}

Expand All @@ -128,11 +167,17 @@ export class WorkspaceEditorsController {
this.selectedEditor = this.cheWorkspace.getWorkspaceDataManager().getEditor(this.workspace);

// check each editor's enabled state:
this.editors.forEach((editor: IPlugin) => {
this.editors.forEach((editor: IPluginRow) => {
editor.isEnabled = this.isEditorEnabled(editor);
if (editor.isEnabled) {

// this.selectedEditor is in the form publisher/name/pluginVersion
const { publisher, name, version } = this.splitEditorId(this.selectedEditor);
editor.selected = version;
}
});

this.cheListHelper.setList(this.editors, 'name');
this.cheListHelper.setList(Array.from(this.editors.values()), 'name');
}

/**
Expand All @@ -141,6 +186,21 @@ export class WorkspaceEditorsController {
* @returns {boolean} the editor's enabled state
*/
private isEditorEnabled(editor: IPlugin): boolean {
return editor.id === this.selectedEditor;
const partialId = `${editor.publisher}/${editor.name}/`;
return this.selectedEditor && this.selectedEditor.indexOf(partialId) !== -1;
}

/**
* Splits an editor ID by a separator (slash)
* @param id a string in form `${publisher}/${name}` or `${publisher}/${name}/${version}`
*/
private splitEditorId(id: string): { publisher: string, name: string, version?: string } {
const parts = id.split('/');
return {
publisher: parts[0],
name: parts[1],
version: parts[2]
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
</che-list-header>
<!-- editor list -->
<che-list class="plugins-list" flex
ng-if="workspaceEditorsController.editors && workspaceEditorsController.editors.length > 0">
ng-if="workspaceEditorsController.editors && workspaceEditorsController.editors.size > 0">
<div class="plugin-item"
ng-repeat="editor in workspaceEditorsController.editors | orderBy:[workspaceEditorsController.editorOrderBy, 'displayName' ]">
ng-repeat="editor in workspaceEditorsController.cheListHelper.getVisibleItems() | orderBy:[workspaceEditorsController.editorOrderBy, 'displayName' ]">
<che-list-item flex>
<div flex="100"
layout="row"
Expand All @@ -51,7 +51,8 @@
</div>
<!-- Version -->
<div flex="15">
<span class="che-list-item-name" plugin-version="{{editor.version}}">{{editor.version}}</span>
<select class="che-version-dropdown" ng-model="editor.selected" ng-change="workspaceEditorsController.updateSelectedEditorVersion(editor)" ng-init="editor.selected" ng-options="ver for ver in editor.versions">
</select>
</div>
<!-- Description -->
<div flex="50">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,9 @@ md-tab-content .plugin-page-separator
.che-list-item-checkbox
min-width 50px
height inherit
.che-version-dropdown
width:80%;
border-color: transparent;
background-colur: #e4e4e4;


Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
import {IPlugin, PluginRegistry} from '../../../../components/api/plugin-registry.factory';
import {IPlugin, PluginRegistry, IPluginRow} from '../../../../components/api/plugin-registry.factory';
import {CheNotification} from '../../../../components/notification/che-notification.factory';
import {CheWorkspace} from '../../../../components/api/workspace/che-workspace.factory';

Expand All @@ -37,7 +37,7 @@ export class WorkspacePluginsController {
isLoading: boolean;

pluginOrderBy = 'displayName';
plugins: Array<IPlugin> = [];
plugins: Map<string, IPluginRow> = new Map(); // the key is publisher/name
selectedPlugins: Array<string> = [];

pluginFilter: any;
Expand Down Expand Up @@ -82,13 +82,39 @@ export class WorkspacePluginsController {
* Loads the list of plugins from registry.
*/
loadPlugins(): void {
this.plugins = [];
this.plugins = new Map();
this.isLoading = true;
this.pluginRegistry.fetchPlugins(this.pluginRegistryLocation).then((result: Array<IPlugin>) => {
this.pluginRegistry.fetchPlugins(this.pluginRegistryLocation).then((result: Array<IPluginRow>) => {
this.isLoading = false;
result.forEach((item: IPlugin) => {
result.forEach((item: IPluginRow) => {
if (item.type !== EDITOR_TYPE) {
this.plugins.push(item);

// since plugin registry returns an array of plugins/editors with a single version we need to unite the plugin versions into one
const pluginID = `${item.publisher}/${item.name}`;

item.selected = 'latest'; // set the default selected to latest

if (this.plugins.has(pluginID)) {
const foundPlugin = this.plugins.get(pluginID);
foundPlugin.versions.push(item.version);
} else {
item.versions = [item.version];
this.plugins.set(pluginID, item);
}

}
});

this.selectedPlugins.forEach(plugin => {
// a selected plugin is in the form publisher/name/version
// find the currently selected ones and set them along with their id
const {publisher, name, version} = this.splitPluginId(plugin);
const pluginID = `${publisher}/${name}`;

if (this.plugins.has(pluginID)) {
const foundPlugin = this.plugins.get(pluginID);
foundPlugin.id = plugin;
foundPlugin.selected = version;
}
});

Expand All @@ -114,37 +140,94 @@ export class WorkspacePluginsController {
*
* @param {IPlugin} plugin
*/
updatePlugin(plugin: IPlugin): void {
updatePlugin(plugin: IPluginRow): void {
if (plugin.type !== EDITOR_TYPE) {

const pluginID = `${plugin.publisher}/${plugin.name}`;
const pluginIDWithVersion = `${plugin.publisher}/${plugin.name}/${plugin.selected}`;

this.plugins.get(pluginID).selected = plugin.selected;
this.plugins.get(pluginID).id = pluginIDWithVersion;

if (plugin.isEnabled) {
this.selectedPlugins.push(plugin.id);
this.selectedPlugins.push(pluginIDWithVersion);
} else {
this.selectedPlugins.splice(this.selectedPlugins.indexOf(plugin.id), 1);
}

this.cheWorkspace.getWorkspaceDataManager().setPlugins(this.workspace, this.selectedPlugins);
}

this.onChange();
}

/**
* Update the selected plugin version when the plugin version dropdown is changed
*
* @param {IPlugin} plugin
*/
updateSelectedPlugin(plugin: IPluginRow): void {
if (plugin.type !== EDITOR_TYPE) {
const pluginID = `${plugin.publisher}/${plugin.name}`;
const pluginIDWithVersion = `${pluginID}/${plugin.selected}`;

this.plugins.get(pluginID).selected = plugin.selected;
this.plugins.get(pluginID).id = pluginIDWithVersion;

const currentlySelectedPlugins = this.cheWorkspace.getWorkspaceDataManager().getPlugins(this.workspace);

if (plugin.isEnabled) {
currentlySelectedPlugins.splice(this.selectedPlugins.indexOf(plugin.id), 1, pluginIDWithVersion);
} else {
currentlySelectedPlugins.push(pluginIDWithVersion);
}
this.cheWorkspace.getWorkspaceDataManager().setPlugins(this.workspace, currentlySelectedPlugins);
this.selectedPlugins = currentlySelectedPlugins;
}
this.onChange();
}

/**
* Update the state of plugins.
*/
private updatePlugins(): void {
this.selectedPlugins = this.cheWorkspace.getWorkspaceDataManager().getPlugins(this.workspace);
// check each plugin's enabled state:
this.plugins.forEach((plugin: IPlugin) => {
plugin.isEnabled = this.isPluginEnabled(plugin);
this.plugins.forEach((plugin: IPluginRow) => {
const selectedPluginId = this.findInSelected(plugin);
plugin.isEnabled = !!selectedPluginId;
if (selectedPluginId) {
plugin.id = selectedPluginId;
const {publisher, name, version} = this.splitPluginId(selectedPluginId);
plugin.selected = version;
}
});
this.cheListHelper.setList(this.plugins, 'displayName');
this.cheListHelper.setList(Array.from(this.plugins.values()), 'displayName');
}

/**
*
* Finds given plugin in the list of enabled plugins and returns its ID with version
* @param {IPlugin} plugin
* @returns {boolean} the plugin's enabled state
* @returns {string | undefined} plugin ID
*/
private findInSelected(plugin: IPluginRow): string | undefined {
return this.selectedPlugins.find(selectedPluginId => {
const partialId = `${plugin.publisher}/${plugin.name}/`;
return selectedPluginId.indexOf(partialId) !== -1;
});
}

/**
* Splits a plugin ID by a separator (slash)
* @param id a string in form `${publisher}/${name}` or `${publisher}/${name}/${version}`
*/
private isPluginEnabled(plugin: IPlugin): boolean {
return this.selectedPlugins.indexOf(plugin.id) >= 0
private splitPluginId(id: string): { publisher: string, name: string, version?: string } {
const parts = id.split('/');
return {
publisher: parts[0],
name: parts[1],
version: parts[2]
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</che-list-header>
<!-- plugins list -->
<che-list class="plugins-list" flex
ng-if="workspacePluginsController.plugins && workspacePluginsController.plugins.length > 0">
ng-if="workspacePluginsController.plugins && workspacePluginsController.plugins.size > 0">
<div class="plugin-item"
ng-repeat="plugin in workspacePluginsController.cheListHelper.getVisibleItems() | orderBy:[workspacePluginsController.pluginOrderBy, 'displayName' ]">
<che-list-item flex>
Expand All @@ -61,7 +61,8 @@
</div>
<!-- Version -->
<div flex="15">
<span class="che-list-item-name" plugin-version="{{plugin.version}}">{{plugin.version}}</span>
<select class="che-version-dropdown" ng-model="plugin.selected" ng-change="workspacePluginsController.updateSelectedPlugin(plugin)" ng-init="plugin.selected" ng-options="ver for ver in plugin.versions">
</select>
</div>
<!-- Description -->
<div flex="50">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ md-tab-content .plugin-page-separator
.che-list-item-checkbox
min-width 50px
height inherit
.che-version-dropdown
width:80%;
border-color: transparent;
background-colur: #e4e4e4;

.plugin-page-separator
margin-top 40px
margin-bottom 10px
height 1px
background-color $list-separator-color

5 changes: 5 additions & 0 deletions dashboard/src/components/api/plugin-registry.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export interface IPlugin {
isEnabled: boolean;
}

export interface IPluginRow extends IPlugin {
selected: string;
versions: string[];
}


/**
* This class is handling plugin registry api
Expand Down