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

Rework switcher for ephemeral mode to the dropdown with storage types #58

Merged
merged 23 commits into from
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions gulp/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ var serverOptions = {

var options = minimist(process.argv.slice(2), serverOptions);

if (options.server.endsWith('/')) {
options.server = options.server.substr(0, options.server.length - 1);
}

var patterns = ['/api', '/ext', '/ws', '/datasource', '/java-ca', '/im', '/che', '/admin', '/workspace-loader'];

var proxies = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import { CustomWorkspaceTabController } from './custom-workspace-tab.controller'
import { CustomWorkspaceTabDirective } from './custom-workspace-tab.directive';
import { DevfileSelectRowComponent } from './devfile-select-row/devfile-select-row.component';
import { InfrastructureNamespaceRowComponent } from './infrastructure-namespace-row/infrastructure-namespace-row.component';
import { TemporaryStorageRowComponent } from './temporary-storage-row/temporary-storage-row.component';
import { StorageTypeRowComponent } from './storage-type-row/storage-type-row.component';
import { WorkspaceNameRowComponent } from './workspace-name-row/workspace-name-row.component';

export class CustomWorkspaceTabConfig {

constructor(register: che.IRegisterService) {
register.component('devfileSelectRow', DevfileSelectRowComponent);
register.component('infrastructureNamespaceRow', InfrastructureNamespaceRowComponent);
register.component('temporaryStorageRow', TemporaryStorageRowComponent);
register.component('storageTypeRow', StorageTypeRowComponent);
register.component('workspaceNameRow', WorkspaceNameRowComponent);
register.controller('CustomWorkspaceTabController', CustomWorkspaceTabController);
register.directive('customWorkspaceTab', CustomWorkspaceTabDirective);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { IChePfButtonProperties } from '../../../components/che-pf-widget/button
import { CreateWorkspaceSvc } from '../../workspaces/create-workspace/create-workspace.service';
import { IInfrastructureNamespaceRowBindingProperties } from './infrastructure-namespace-row/infrastructure-namespace-row.component';
import { IWorkspaceNameRowBindingProperties } from './workspace-name-row/workspace-name-row.component';
import { ITemporaryStorageRowBindingProperties } from './temporary-storage-row/temporary-storage-row.component';
import { IStorageTypeRowBindingProperties } from './storage-type-row/storage-type-row.component';
import { IDevfileSelectRowBindingProperties } from './devfile-select-row/devfile-select-row.component';
import { IDevfileEditorBindingProperties } from '../../../components/widget/devfile-editor/devfile-editor.component';
import { StorageType } from '../../../components/service/storage-type.service';

export class CustomWorkspaceTabController implements ng.IController {

Expand All @@ -29,7 +30,7 @@ export class CustomWorkspaceTabController implements ng.IController {
createButton: IChePfButtonProperties;
infrastructureNamespaceProperties: IInfrastructureNamespaceRowBindingProperties;
workspaceNameProperties: IWorkspaceNameRowBindingProperties;
temporaryStorageProperties: ITemporaryStorageRowBindingProperties;
storageTypeProperties: IStorageTypeRowBindingProperties;
devfileSelectProperties: IDevfileSelectRowBindingProperties;
devfileEditorProperties: IDevfileEditorBindingProperties;

Expand All @@ -38,8 +39,7 @@ export class CustomWorkspaceTabController implements ng.IController {

private namespace: string;
private workspaceName: string;
private temporaryStorage: boolean;
private temporaryStorageDefault: boolean;
private storageType: StorageType;
private stackName: string;
private devfile: che.IWorkspaceDevfile;
private editorState: che.IValidation;
Expand Down Expand Up @@ -75,16 +75,15 @@ export class CustomWorkspaceTabController implements ng.IController {
this.updateProperties(true);
},
};
this.temporaryStorageProperties = {
onChange: (temporary, defaultValue) => {
this.temporaryStorage = temporary;
this.temporaryStorageDefault = defaultValue;
this.storageTypeProperties = {
onChangeStorageType: (storageType) => {
this.storageType = storageType;
if (!this.devfile) {
this.devfile = this.minDevfile;
}
this.updateDevfile();
this.updateProperties(true);
},
}
};
this.devfileSelectProperties = {
onError: () => {
Expand Down Expand Up @@ -142,24 +141,32 @@ export class CustomWorkspaceTabController implements ng.IController {
if (!this.devfile) {
return;
}

if (this.temporaryStorage === this.temporaryStorageDefault) {
if (this.devfile.attributes && this.devfile.attributes.persistVolumes) {
switch (this.storageType) {
case StorageType.persistent:
if (this.devfile.attributes) {
delete this.devfile.attributes.persistVolumes;
delete this.devfile.attributes.asyncPersist;
if (Object.keys(this.devfile.attributes).length === 0) {
delete this.devfile.attributes;
}
}
} else {
if (!this.devfile.attributes) {
this.devfile.attributes = {};
}
if (this.temporaryStorage) {
break;
case StorageType.ephemeral:
if (!this.devfile.attributes) {
this.devfile.attributes = {};
}
this.devfile.attributes.persistVolumes = 'false';
} else {
this.devfile.attributes.persistVolumes = 'true';
}
delete this.devfile.attributes.asyncPersist;
break;
case StorageType.async:
if (!this.devfile.attributes) {
this.devfile.attributes = {};
}
this.devfile.attributes.persistVolumes = 'false';
this.devfile.attributes.asyncPersist = 'true';
break
}

if (this.workspaceName) {
if (!this.devfile.metadata) {
this.devfile.metadata = {}
Expand Down Expand Up @@ -187,9 +194,16 @@ export class CustomWorkspaceTabController implements ng.IController {
return;
}
if (this.devfile.attributes && this.devfile.attributes.persistVolumes) {
this.temporaryStorageProperties.temporary = this.devfile.attributes.persistVolumes === 'false';
const val = (this.devfile.attributes.persistVolumes === 'false');
if (val) {
if (this.devfile.attributes.asyncPersist === 'true') {
this.storageTypeProperties.storageType = StorageType.async;
} else {
this.storageTypeProperties.storageType = StorageType.ephemeral;
}
}
} else {
this.temporaryStorageProperties.temporary = undefined;
this.storageTypeProperties.storageType = undefined;
}
if (this.devfile.metadata && this.devfile.metadata.name) {
this.workspaceName = this.devfile.metadata.name;
Expand All @@ -199,14 +213,15 @@ export class CustomWorkspaceTabController implements ng.IController {
if (this.devfile.metadata) {
this.workspaceNameProperties.generateName = this.devfile.metadata.generateName;
}

if (forceEditorUpdate) {
this.devfileEditorProperties.devfile = angular.copy(this.devfile);
}
}

private createWorkspace(): ng.IPromise<che.IWorkspace> {
const stackName = this.stackName || '';
return this.createWorkspaceSvc.createWorkspaceFromDevfile(this.namespace, this.devfile, {stackName}, true);
return this.createWorkspaceSvc.createWorkspaceFromDevfile(this.namespace, this.devfile, { stackName }, true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
name="customWorkspaceTabController.workspaceNameProperties.name"
on-change="customWorkspaceTabController.workspaceNameProperties.onChange($name)"></workspace-name-row>

<!-- Temporary Storage -->
<temporary-storage-row temporary="customWorkspaceTabController.temporaryStorageProperties.temporary"
on-change="customWorkspaceTabController.temporaryStorageProperties.onChange($temporary, $default)"></temporary-storage-row>
<!-- Storage Type -->
<storage-type-row storage-type="customWorkspaceTabController.storageTypeProperties.storageType"
on-change-storage-type="customWorkspaceTabController.storageTypeProperties.onChangeStorageType($storageType, $default)"
></storage-type-row>
</ng-form>
<!-- Devfile -->
<devfile-select-row on-load="customWorkspaceTabController.devfileSelectProperties.onLoad($devfile, $stackName)"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 { StorageTypeRowController } from './storage-type-row.controller';
import { StorageType } from '../../../../components/service/storage-type.service';

export interface IStorageTypeRowBindingProperties {
storageType?: StorageType;
onChangeStorageType: ($storageType: StorageType) => void;
}

export interface IStorageTypeRowComponentBindings {
storageType?: StorageType;
onChangeStorageType: (eventObj: { $storageType: StorageType }) => void;
}

interface IStorageTypeRowComponentScopeBindings {
bindings: { [key in keyof IStorageTypeRowComponentBindings]: string };
}

export class StorageTypeRowComponent implements ng.IComponentOptions, IStorageTypeRowComponentScopeBindings {

templateUrl = 'app/get-started/custom-workspace-tab/storage-type-row/storage-type-row.html';
controller = StorageTypeRowController;
controllerAs = 'ctrl';

bindings = {
storageType : '<',
onChangeStorageType: '&'
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 { IStorageTypeRowComponentBindings } from './storage-type-row.component';
import { IChePfSelectProperties } from '../../../../components/che-pf-widget/select/che-pf-select-typeahead.directive';
import { ChePfModalService } from '../../../../components/che-pf-widget/modal/che-pf-modal.service';
import { StorageTypeService, StorageType } from '../../../../components/service/storage-type.service';

type OnChangesObject = {
[key in keyof IStorageTypeRowComponentBindings]: ng.IChangesObject<IStorageTypeRowComponentBindings[key]>;
};

export class StorageTypeRowController implements ng.IController, IStorageTypeRowComponentBindings {

static $inject = [
'chePfModalService',
'storageTypeService',
];

// component bindings
isReady: boolean = false;
onChangeStorageType: (eventObj: { '$storageType': StorageType; }) => void;

// used in template
selectorId = 'storage-type-selector';

// template fields
storageSelect: IChePfSelectProperties<StorageType>;
descriptionButtonTitle: string;

// injected services
private chePfModalService: ChePfModalService;
private storageTypeService: StorageTypeService;

private initPromise: ng.IPromise<void>;
private preferredStorageType: StorageType;

constructor(
chePfModalService: ChePfModalService,
storageTypeService: StorageTypeService,
) {
this.chePfModalService = chePfModalService;
this.storageTypeService = storageTypeService;
}

$onInit(): void {
this.descriptionButtonTitle = 'Learn more about storage types';

this.initPromise = this.storageTypeService.ready
.then(() => {
const items = this.storageTypeService.getAvailableTypes()
.map(type => StorageType[type]);
this.storageSelect = {
config: {
id: this.selectorId,
items,
placeholder: 'Select a storage template'
},
value: this.storageTypeService.getPreferredType(),
onSelect: storageType => this.onStorageTypeChanged(storageType),
};
this.isReady = true;
});
}

$onChanges(onChangesObj: OnChangesObject): void {
if (!this.initPromise) {
return;
}
this.initPromise.then(() => {
if (onChangesObj.storageType.currentValue === undefined) {
this.storageSelect.value = this.preferredStorageType;
return;
}
this.storageSelect.value = onChangesObj.storageType.currentValue;
});
}

showStorageTypeModal(): ng.IPromise<void> {
const storageTypes = this.storageTypeService.getAvailableTypes();
const content = this.storageTypeService.getHtmlDescriptions(storageTypes);
return this.chePfModalService.showModal(content);
}

onStorageTypeChanged(storageType: StorageType): void {
this.onChangeStorageType({ '$storageType': storageType })
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--

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="storage-type-row pf-c-form__group">
<label class="pf-c-form__label" for="{{ctrl.selectorId}}">
<span class="pf-c-form__label-text">Storage Type</span>&nbsp;
</label>

<div class="pf-l-flex">
<div class="pf-l-flex-item">
<div ng-if="ctrl.isReady"
class="pf-c-form__horizontal-group">
<che-pf-select-single class="storage-type-selector" config="ctrl.storageSelect.config"
value="ctrl.storageSelect.value" on-select="ctrl.storageSelect.onSelect($value)">
</che-pf-select-single>
</div>
</div>
<div class="pf-l-flex-item">
<che-pf-link-button title="{{ctrl.descriptionButtonTitle}}" ng-click="ctrl.showStorageTypeModal()">
</che-pf-link-button>
</div>
</div>

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.storage-type-row
.storage-type-selector
display block
width 350px
Loading