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

Cherry pick base support of DevWorkspaces on Dashboard #182

Merged
merged 13 commits into from
Mar 9, 2021
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
3 changes: 2 additions & 1 deletion .deps/EXCLUDED/prod.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This file lists dependencies that do not need CQs or auto-detection does not wor
| --- | --- |
| `che-dashboard-e2e@1.0.0` | N/A |
| `@eclipse-che/api@7.18.1` | N/A |
| `@eclipse-che/workspace-client@0.0.1-1613117389` | N/A |
| `@eclipse-che/workspace-client@0.0.1-1614934724` | N/A |
| `@eclipse-che/devworkspace-client@0.0.1-1614765743` | N/A |
| `@patternfly/react-core@4.84.4` | [CQ22936](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=22936) |
| `prettier@2.2.1` | [CQ23020](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23020) |
77 changes: 1 addition & 76 deletions .deps/dev.md

Large diffs are not rendered by default.

142 changes: 138 additions & 4 deletions .deps/prod.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"licenseCheck:run": "license-tool/run.sh"
},
"dependencies": {
"@eclipse-che/workspace-client": "^0.0.1-1613117389",
"@eclipse-che/devworkspace-client": "^0.0.1-1614934724",
"@eclipse-che/workspace-client": "^0.0.1-1613484098",
"@patternfly/react-core": "~4.84.4",
"@patternfly/react-icons": "^4.3.5",
"@patternfly/react-table": "^4.5.7",
Expand Down
1 change: 1 addition & 0 deletions src/Layout/Navigation/__tests__/RecentList.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ function createFakeStore(workspaces: che.Workspace[]): Store {
infrastructureNamespace: {} as any,
environment: {} as any,
userPreferences: {} as any,
dwPlugins: {} as any,
};
const middleware = [thunk];
const mockStore = createMockStore(middleware);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import React from 'react';
import { container } from '../../../../inversify.config';
import WebSocketBanner from '..';
import { CheWorkspaceClient } from '../../../../services/cheWorkspaceClient';
import { CheWorkspaceClient } from '../../../../services/workspace-client/cheWorkspaceClient';
import { Provider } from 'react-redux';
import { FakeStoreBuilder } from '../../../../store/__mocks__/storeBuilder';
import { BrandingData } from '../../../../services/bootstrap/branding.constant';
Expand Down
2 changes: 1 addition & 1 deletion src/components/BannerAlert/WebSocketBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Banner } from '@patternfly/react-core';
import React from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { container } from '../../../inversify.config';
import { CheWorkspaceClient } from '../../../services/cheWorkspaceClient';
import { CheWorkspaceClient } from '../../../services/workspace-client/cheWorkspaceClient';
import { AppState } from '../../../store';

type Props = MappedProps & {};
Expand Down
11 changes: 9 additions & 2 deletions src/components/DevfileEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Props =
devfile: che.WorkspaceDevfile;
decorationPattern?: string;
onChange: (devfile: che.WorkspaceDevfile, isValid: boolean) => void;
isReadonly?: boolean;
};
type State = {
errorMessage: string;
Expand Down Expand Up @@ -100,7 +101,7 @@ export class DevfileEditor extends React.PureComponent<Props, State> {
}
const jsonSchema = this.props.devfileRegistries.schema || {};
const items = this.props.plugins.plugins;
const components = jsonSchema && jsonSchema.properties ? jsonSchema.properties.components : undefined;
const components = jsonSchema && jsonSchema.oneOf && jsonSchema.oneOf.length > 0 && jsonSchema.oneOf[0].properties ? jsonSchema.oneOf[0].properties.components : undefined;
if (components) {
const mountSources = components.items.properties.mountSources;
// mount sources is specific only for some of component types but always appears
Expand Down Expand Up @@ -168,6 +169,7 @@ export class DevfileEditor extends React.PureComponent<Props, State> {
const element = $('.devfile-editor .monaco').get(0);
if (element) {
const value = stringify(this.props.devfile);
MONACO_CONFIG.readOnly = this.props.isReadonly !== undefined ? this.props.isReadonly : false;
this.editor = monaco.editor.create(element, Object.assign(
{ value },
MONACO_CONFIG,
Expand Down Expand Up @@ -224,10 +226,15 @@ export class DevfileEditor extends React.PureComponent<Props, State> {
const href = this.props.branding.data.docs.devfile;
const { errorMessage } = this.state;

let message = errorMessage;
if (this.props.isReadonly !== undefined && this.props.isReadonly === true) {
message = 'DevWorkspace editor support has not been enabled. Editor is in Readonly mode.';
}

return (
<div className='devfile-editor'>
<div className='monaco'>&nbsp;</div>
<div className='error'>{errorMessage}</div>
<div className='error'>{message}</div>
<a target='_blank' rel='noopener noreferrer' href={href}>Devfile Documentation</a>
</div>
);
Expand Down
8 changes: 4 additions & 4 deletions src/containers/FactoryLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export class FactoryLoaderContainer extends React.PureComponent<Props, State> {
}
this.setState({ currentStep: LoadFactorySteps.OPEN_IDE });
try {
await this.props.requestWorkspace(workspace.id);
await this.props.requestWorkspace(workspace);
} catch (e) {
this.showAlert(`Getting workspace detail data failed. ${e}`);
}
Expand Down Expand Up @@ -281,11 +281,11 @@ export class FactoryLoaderContainer extends React.PureComponent<Props, State> {
if (this.state.currentStep !== LoadFactorySteps.START_WORKSPACE
&& this.state.currentStep !== LoadFactorySteps.OPEN_IDE) {
try {
await this.props.requestWorkspace(workspace.id);
await this.props.requestWorkspace(workspace);
if (WorkspaceStatus[workspace.status] === WorkspaceStatus.STOPPED) {
await this.props.startWorkspace(workspace.id);
await this.props.startWorkspace(workspace);
this.setState({ currentStep: LoadFactorySteps.START_WORKSPACE });
} else if (WorkspaceStatus[workspace.status] === WorkspaceStatus.RUNNING) {
} else if (WorkspaceStatus[workspace.status] === WorkspaceStatus.RUNNING || WorkspaceStatus[workspace.status] === WorkspaceStatus.STARTING) {
this.setState({ currentStep: LoadFactorySteps.START_WORKSPACE });
}
} catch (e) {
Expand Down
12 changes: 6 additions & 6 deletions src/containers/IdeLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {

private async verboseModeHandler(workspace: che.Workspace) {
try {
await this.props.startWorkspace(workspace.id, { 'debug-workspace-start': true });
await this.props.startWorkspace(workspace, { 'debug-workspace-start': true });
this.props.deleteWorkspaceLogs(workspace.id);
this.setState({
currentStep: LoadIdeSteps.INITIALIZING,
Expand Down Expand Up @@ -280,16 +280,16 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {
this.setState({ currentStep: LoadIdeSteps.OPEN_IDE, ideUrl });
}

private async openIDE(workspaceId: string): Promise<void> {
private async openIDE(cheWorkspace: che.Workspace): Promise<void> {
this.setState({ currentStep: LoadIdeSteps.OPEN_IDE });
try {
await this.props.requestWorkspace(workspaceId);
await this.props.requestWorkspace(cheWorkspace);
} catch (e) {
this.showAlert(`Getting workspace detail data failed. ${e}`);
return;
}
const workspace = this.props.allWorkspaces.find(workspace =>
workspace.id === workspaceId);
workspace.id === cheWorkspace.id);
if (workspace && workspace.runtime) {
await this.updateIdeUrl(workspace.runtime);
}
Expand Down Expand Up @@ -317,7 +317,7 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {
this.setState({ workspaceId: workspace.id });
if ((workspace.runtime || this.state.currentStep === LoadIdeSteps.START_WORKSPACE) &&
workspace.status === WorkspaceStatus[WorkspaceStatus.RUNNING]) {
return this.openIDE(workspace.id);
return this.openIDE(workspace);
}
} else {
this.showAlert('Failed to find the target workspace.');
Expand All @@ -327,7 +327,7 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {
this.setState({ currentStep: LoadIdeSteps.START_WORKSPACE });
if (workspace.status === WorkspaceStatus[WorkspaceStatus.STOPPED] && (this.state.hasError !== true)) {
try {
await this.props.startWorkspace(`${workspace.id}`);
await this.props.startWorkspace(workspace);
} catch (e) {
this.showAlert(`Workspace ${this.state.workspaceName} failed to start. ${e}`);
return;
Expand Down
3 changes: 2 additions & 1 deletion src/containers/WorkspaceActions/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import { AppThunk } from '../../../store';
jest.mock('../../../store/Workspaces/index', () => {
return {
actionCreators: {
deleteWorkspace: (id: string): AppThunk<Action, Promise<void>> => async (): Promise<void> => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
deleteWorkspace: (workspace: che.Workspace): AppThunk<Action, Promise<void>> => async (): Promise<void> => {
return Promise.resolve();
},
} as ActionCreators,
Expand Down
8 changes: 4 additions & 4 deletions src/containers/WorkspaceActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,19 @@ export class WorkspaceActionsProvider extends React.Component<Props, State> {
}
case WorkspaceAction.START_DEBUG_AND_OPEN_LOGS:
{
await this.props.startWorkspace(workspace.id, {
await this.props.startWorkspace(workspace, {
'debug-workspace-start': true
});
return buildIdeLoaderPath(workspace, IdeLoaderTab.Logs);
}
case WorkspaceAction.START_IN_BACKGROUND:
{
await this.props.startWorkspace(workspace.id);
await this.props.startWorkspace(workspace);
}
break;
case WorkspaceAction.STOP_WORKSPACE:
{
await this.props.stopWorkspace(workspace.id);
await this.props.stopWorkspace(workspace);
}
break;
case WorkspaceAction.ADD_PROJECT:
Expand All @@ -122,7 +122,7 @@ export class WorkspaceActionsProvider extends React.Component<Props, State> {
});

try {
await this.props.deleteWorkspace(workspace.id);
await this.props.deleteWorkspace(workspace);
this.deleting.delete(id);
this.setState({
isDeleted: Array.from(this.deleting),
Expand Down
10 changes: 5 additions & 5 deletions src/containers/__tests__/FactoryLoader.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ describe('Factory Loader container', () => {

jest.runOnlyPendingTimers();
expect(showAlertMock).not.toHaveBeenCalled();
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace.id));
await waitFor(() => expect(startWorkspaceMock).toHaveBeenCalledWith(workspace.id));
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace));
await waitFor(() => expect(startWorkspaceMock).toHaveBeenCalledWith(workspace));
expect(LoadFactorySteps[elementCurrentStep.innerHTML]).toEqual(LoadFactorySteps[LoadFactorySteps.START_WORKSPACE]);
});

Expand Down Expand Up @@ -153,11 +153,11 @@ describe('Factory Loader container', () => {
'when the workspace is stopped unless they are pushed to a remote code repository.'
);
expect(setWorkspaceIdMock).toHaveBeenCalledWith(workspace.id);
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace.id));
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace));
await waitFor(() => expect(startWorkspaceMock).not.toHaveBeenCalled());

jest.runOnlyPendingTimers();
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace.id));
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace));
expect(LoadFactorySteps[elementCurrentStep.innerHTML]).toEqual(LoadFactorySteps[LoadFactorySteps.OPEN_IDE]);
});

Expand Down Expand Up @@ -204,7 +204,7 @@ describe('Factory Loader container', () => {
expect(createWorkspaceFromDevfileMock).not.toHaveBeenCalled();

jest.runOnlyPendingTimers();
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace.id));
await waitFor(() => expect(requestWorkspaceMock).toHaveBeenCalledWith(workspace));
expect(LoadFactorySteps[elementCurrentStep.innerHTML]).toEqual(LoadFactorySteps[LoadFactorySteps.OPEN_IDE]);
});

Expand Down
4 changes: 2 additions & 2 deletions src/containers/__tests__/IdeLoader.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ jest.mock('../../store/Workspaces/index', () => {
return {
actionCreators: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
requestWorkspace: (id: string): AppThunk<Action, Promise<void>> => async (): Promise<void> => { requestWorkspaceMock(); },
requestWorkspace: (workspace: che.Workspace): AppThunk<Action, Promise<void>> => async (): Promise<void> => { requestWorkspaceMock(); },
// eslint-disable-next-line @typescript-eslint/no-unused-vars
startWorkspace: (id: string): AppThunk<Action, Promise<void>> => async (): Promise<void> => { startWorkspaceMock(); },
startWorkspace: (workspace: che.Workspace): AppThunk<Action, Promise<void>> => async (): Promise<void> => { startWorkspaceMock(); },
requestWorkspaces: (): AppThunk<Action, Promise<void>> => async (): Promise<void> => {
return Promise.resolve();
},
Expand Down
4 changes: 3 additions & 1 deletion src/inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ import getDecorators from 'inversify-inject-decorators';
import { KeycloakSetupService } from './services/keycloak/setup';
import { KeycloakAuthService } from './services/keycloak/auth';
import { Debounce } from './services/helpers/debounce';
import { CheWorkspaceClient } from './services/cheWorkspaceClient';
import { CheWorkspaceClient } from './services/workspace-client/cheWorkspaceClient';
import { AppAlerts } from './services/alerts/appAlerts';
import { IssuesReporterService } from './services/bootstrap/issuesReporter';
import { DevWorkspaceClient } from './services/workspace-client/devWorkspaceClient';

const container = new Container();
const { lazyInject } = getDecorators(container);
Expand All @@ -28,6 +29,7 @@ container.bind(KeycloakSetupService).toSelf().inSingletonScope();
container.bind(KeycloakAuthService).toSelf().inSingletonScope();
container.bind(Debounce).toSelf();
container.bind(CheWorkspaceClient).toSelf().inSingletonScope();
container.bind(DevWorkspaceClient).toSelf().inSingletonScope();
container.bind(AppAlerts).toSelf().inSingletonScope();

export { container, lazyInject };
12 changes: 7 additions & 5 deletions src/pages/GetStarted/CustomWorkspaceTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,17 @@ export class CustomWorkspaceTab extends React.PureComponent<Props, State> {
return;
}
this.setState({ devfile });
const storageType = attributesToType(devfile.attributes);
if (storageType !== this.state.storageType) {
this.setState({ storageType });
if (devfile?.attributes) {
const storageType = attributesToType(devfile.attributes);
if (storageType !== this.state.storageType) {
this.setState({ storageType });
}
}
const workspaceName = devfile.metadata.name || '';
const workspaceName = devfile?.metadata?.name || '';
if (workspaceName !== this.state.workspaceName) {
this.setState({ workspaceName });
}
const generateName = devfile.metadata.generateName;
const generateName = devfile?.metadata?.generateName;
if (generateName !== this.state.generateName) {
this.setState({ generateName });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ function createFakeStore(metadata?: che.DevfileMetaData[]): Store {
infrastructureNamespace: {} as any,
environment: {} as any,
userPreferences: {} as any,
dwPlugins: {} as any,
};
const middleware = [thunk];
const mockStore = createMockStore(middleware);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ function createFakeStore(metadata?: che.DevfileMetaData[]): Store {
infrastructureNamespace: {} as any,
environment: {} as any,
userPreferences: {} as any,
dwPlugins: {} as any,
};
const middleware = [thunk];
const mockStore = createMockStore(middleware);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function createFakeStore(metadata?: che.DevfileMetaData[]): Store {
infrastructureNamespace: {} as any,
environment: {} as any,
userPreferences: {} as any,
dwPlugins: {} as any,
};
const middleware = [thunk];
const mockStore = createMockStore(middleware);
Expand Down
1 change: 1 addition & 0 deletions src/pages/GetStarted/__tests__/GetStarted.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ function createFakeStore(): Store {
infrastructureNamespace: {} as any,
environment: {} as any,
userPreferences: {} as any,
dwPlugins: {} as any,
};
const middleware = [thunk];
const mockStore = createMockStore(middleware);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/GetStarted/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class GetStarted extends React.PureComponent<Props, State> {

// force start for the new workspace
try {
await this.props.startWorkspace(`${workspace.id}`);
await this.props.startWorkspace(workspace);
this.props.history.push(`/ide/${workspace.namespace}/${workspaceName}`);
} catch (error) {
const errorMessage = `Workspace ${workspaceName} failed to start`;
Expand Down
2 changes: 2 additions & 0 deletions src/pages/WorkspaceDetails/DevfileTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import DevfileEditor, { DevfileEditor as Editor } from '../../../components/Devf
import EditorTools from './EditorTools';

import './DevfileTab.styl';
import { isDevWorkspace } from '../../../services/helpers/devworkspace';

type Props = {
onSave: (workspace: che.Workspace) => Promise<void>;
Expand Down Expand Up @@ -124,6 +125,7 @@ export class EditorTab extends React.PureComponent<Props, State> {
onChange={(devfile, isValid) => {
this.onDevfileChange(devfile, isValid);
}}
isReadonly={isDevWorkspace(originDevfile)}
/>
<Button onClick={() => this.cancelChanges()} variant="secondary" className="cancle-button"
isDisabled={!this.state.hasChanges && this.state.isDevfileValid}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import { FakeStoreBuilder } from '../../../../../store/__mocks__/storeBuilder';
jest.mock('../../../../../store/Workspaces/index', () => {
return {
actionCreators: {
startWorkspace: (workspaceId: string, params?: ResourceQueryParams): AppThunk<any, Promise<void>> => async (): Promise<void> => {
startWorkspace: (workspace: che.Workspace, params?: ResourceQueryParams): AppThunk<any, Promise<void>> => async (): Promise<void> => {
return Promise.resolve();
},
stopWorkspace: (workspaceId: string): AppThunk<any, Promise<void>> => async (): Promise<void> => {
stopWorkspace: (workspace: che.Workspace): AppThunk<any, Promise<void>> => async (): Promise<void> => {
return Promise.resolve();
}
} as ActionCreators,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/WorkspacesList/Rows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function buildRow(
/* projects list */
const workspaceProjects = workspace.devfile.projects || [];
const projects = workspaceProjects
.map(project => project.source.location || project.name)
.map(project => project.source?.location || project.name)
.join(', \n') || '-';

/* Open IDE link */
Expand Down
Loading