Skip to content

Commit

Permalink
feat: Load editor in a new window (no iframe)
Browse files Browse the repository at this point in the history
Also during the factory workflow, do not see the header + left sidebar
note: it's only if DevWorkspace engine is enabled on the instance
  • Loading branch information
benoitf committed Oct 13, 2021
1 parent 9823946 commit aea3921
Show file tree
Hide file tree
Showing 19 changed files with 127 additions and 32 deletions.
14 changes: 13 additions & 1 deletion packages/dashboard-frontend/src/Layout/Navigation/RecentItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function NavigationRecentItem(props: {
isActive={getActivity(props.item.to, props.activePath)}
className={styles.navItem}
preventDefault={true}
onClick={() => props.history.push(props.item.to)}
onClick={() => handleClick(props.history, props.item.to, props.item.workspaceId, props.item.isDevWorkspace)}
>
<span data-testid="recent-workspace-item"><WorkspaceIndicator
status={props.item.status} />{props.item.label}</span>
Expand All @@ -42,5 +42,17 @@ function NavigationRecentItem(props: {
);
}

/**
* Open the link in a new tab if it's a devWorkspace, else open in it in the current window in iframe
*/
function handleClick(history: History, location: string, workspaceId: string, isDevWorkspace: boolean) {
if (isDevWorkspace) {
const link = `#${location}`;
window.open(link, workspaceId);
} else {
history.push(location);
}
}

NavigationRecentItem.displayName = 'NavigationRecentItemComponent';
export default NavigationRecentItem;
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ class NavigationItemWorkspaceActions extends React.PureComponent<Props, State> {

public render(): React.ReactElement {
const { isExpanded } = this.state;
const { history } = this.props;
const menuAppendTo = document.getElementById('page-sidebar') || 'inline';

return (<WorkspaceActionsProvider>
return (<WorkspaceActionsProvider history={history}>
<WorkspaceActionsConsumer>
{context => (
<Dropdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ function buildRecentWorkspacesItems(workspaces: Array<Workspace>, activePath: st
to: navigateTo,
label: workspaceName,
status: workspace.status,
workspaceId: workspace.id
workspaceId: workspace.id,
isDevWorkspace: workspace.isDevWorkspace,
};
return <NavigationRecentItem key={item.to} item={item} activePath={activePath} history={history} />;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Navigation Item', () => {
status: '',
label: 'workspace',
to: '/namespace/workspace',
isDevWorkspace: false,
workspaceId: 'test-wrks-id'
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface NavigationRecentItemObject {
label: string,
status: string;
workspaceId: string;
isDevWorkspace: boolean;
}

type Props =
Expand Down
5 changes: 5 additions & 0 deletions packages/dashboard-frontend/src/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ export class Layout extends React.PureComponent<Props, State> {
isSidebarVisible: false,
isHeaderVisible,
});
} else if (event.data === 'hide-allbar') {
this.setState({
isSidebarVisible: false,
isHeaderVisible: false,
});
}
};
window.addEventListener('message', handleMessage, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
selectWorkspaceById,
selectWorkspaceByQualifiedName
} from '../../store/Workspaces/selectors';
import { selectPreferredStorageType } from '../../store/Workspaces/Settings/selectors';
import { selectPreferredStorageType, selectWorkspacesSettings } from '../../store/Workspaces/Settings/selectors';
import { buildIdeLoaderLocation, sanitizeLocation } from '../../services/helpers/location';
import { lazyInject } from '../../inversify.config';
import { KeycloakAuthService } from '../../services/keycloak/auth';
Expand Down Expand Up @@ -140,11 +140,22 @@ export class FactoryLoaderContainer extends React.PureComponent<Props, State> {
}
}

private showOnlyContentIfDevWorkspace() : void {
const cheDevworkspaceEnabled = this.props.workspacesSettings['che.devworkspaces.enabled'] === 'true';
if (cheDevworkspaceEnabled) {
// hide all bars
window.postMessage('hide-allbar', '*');
}
}

public componentDidMount(): void {
this.showOnlyContentIfDevWorkspace();
this.createWorkspaceFromFactory();
}

public async componentDidUpdate(): Promise<void> {
this.showOnlyContentIfDevWorkspace();

const { history, workspace, factoryResolver } = this.props;
if (this.state.search !== history.location.search) {
this.setState({
Expand Down Expand Up @@ -552,6 +563,7 @@ const mapStateToProps = (state: AppState) => ({
preferredStorageType: selectPreferredStorageType(state),
activeWorkspace: selectWorkspaceByQualifiedName(state),
defaultNamespace: selectDefaultNamespace(state),
workspacesSettings: selectWorkspacesSettings(state),
});

const connector = connect(
Expand Down
5 changes: 4 additions & 1 deletion packages/dashboard-frontend/src/containers/IdeLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type State = {
ideUrl?: string;
hasError: boolean;
isWaitingForRestart: boolean;
isDevWorkspace: boolean;
};

class IdeLoaderContainer extends React.PureComponent<Props, State> {
Expand Down Expand Up @@ -83,6 +84,7 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {
this.state = {
currentStep: LoadIdeSteps.INITIALIZING,
namespace,
isDevWorkspace: workspace?.isDevWorkspace || false,
workspaceName,
hasError: workspace?.hasError === true,
preselectedTabKey: this.preselectedTabKey,
Expand Down Expand Up @@ -401,12 +403,13 @@ class IdeLoaderContainer extends React.PureComponent<Props, State> {
}

render() {
const { currentStep, hasError, ideUrl, workspaceId, workspaceName, preselectedTabKey } = this.state;
const { currentStep, hasError, ideUrl, workspaceId, workspaceName, preselectedTabKey, isDevWorkspace } = this.state;
const status = this.getCurrentStatus();

return (
<IdeLoader
currentStep={currentStep}
isDevWorkspace={isDevWorkspace}
workspaceId={workspaceId || ''}
preselectedTabKey={preselectedTabKey}
ideUrl={ideUrl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { createFakeCheWorkspace } from '../../../store/__mocks__/workspace';
import { ActionCreators } from '../../../store/Workspaces';
import { AppThunk } from '../../../store';
import { Workspace } from '../../../services/workspace-adapter';
import { createHashHistory } from 'history';

jest.mock('../../../store/Workspaces/index', () => {
return {
Expand All @@ -37,6 +38,7 @@ jest.mock('../../../store/Workspaces/index', () => {

describe('Workspace Actions', () => {

const history = createHashHistory();
const actionButtonName = 'action-button';
const valueInputId = 'value-input';
const defaultWorkspaceId = 'workspace-0';
Expand Down Expand Up @@ -90,7 +92,7 @@ describe('Workspace Actions', () => {
const store = createFakeStore();
render(
<Provider store={store}>
<WorkspaceActionsProvider>
<WorkspaceActionsProvider history={history}>
<WorkspaceActionsConsumer>
{context => (
<>
Expand Down Expand Up @@ -163,7 +165,7 @@ describe('Workspace Actions', () => {
const store = createFakeStore();
render(
<Provider store={store}>
<WorkspaceActionsProvider>
<WorkspaceActionsProvider history={history}>
<WorkspaceActionsConsumer>
{context => (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/

import React from 'react';
import { Location } from 'history';
import { History, Location } from 'history';
import { connect, ConnectedProps } from 'react-redux';
import {
AlertVariant,
Expand All @@ -28,6 +28,7 @@ import {
buildDetailsLocation,
buildIdeLoaderLocation,
buildWorkspacesLocation,
toHref,
} from '../../services/helpers/location';
import {
IdeLoaderTab,
Expand All @@ -41,16 +42,19 @@ import { WorkspaceActionsContext } from './context';
import { lazyInject } from '../../inversify.config';
import { AppAlerts } from '../../services/alerts/appAlerts';
import getRandomString from '../../services/helpers/random';
import { isCheWorkspace } from '../../services/workspace-adapter';
import { isCheWorkspace, Workspace } from '../../services/workspace-adapter';

type Deferred = {
resolve: () => void;
reject: () => void;
}

type Props = MappedProps & {
type Props = MappedProps
& { history: History }
& {
children: React.ReactElement;
};

type State = {
toDelete: string[];
wantDelete: string[];
Expand Down Expand Up @@ -85,6 +89,18 @@ export class WorkspaceActionsProvider extends React.Component<Props, State> {
});
}

/**
* open the action in a new tab for DevWorkspaces
*/
async handleLocation(location: Location, workspace: Workspace): Promise<Location | void> {
if (workspace.isDevWorkspace) {
const link = toHref(this.props.history, location);
window.open(link, workspace.id);
} else {
return location;
}
}

/**
* Performs an action on the given workspace
*/
Expand All @@ -104,7 +120,7 @@ export class WorkspaceActionsProvider extends React.Component<Props, State> {
switch (action) {
case WorkspaceAction.OPEN_IDE:
{
return buildIdeLoaderLocation(workspace);
return this.handleLocation(buildIdeLoaderLocation(workspace), workspace);
}
case WorkspaceAction.EDIT_WORKSPACE:
{
Expand All @@ -115,7 +131,7 @@ export class WorkspaceActionsProvider extends React.Component<Props, State> {
await this.props.startWorkspace(workspace, {
'debug-workspace-start': true
});
return buildIdeLoaderLocation(workspace, IdeLoaderTab.Logs);
return this.handleLocation(buildIdeLoaderLocation(workspace, IdeLoaderTab.Logs), workspace);
}
case WorkspaceAction.START_IN_BACKGROUND:
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class WorkspacesListContainer extends React.PureComponent<Props> {
}

return (
<WorkspaceActionsProvider>
<WorkspaceActionsProvider history={history}>
<WorkspaceActionsConsumer>
{context => (
<WorkspacesList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import * as DevfileRegistriesStore from '../../../../store/DevfileRegistries';
import * as FactoryResolverStore from '../../../../store/FactoryResolver';
import { GitRepoLocationInput } from './GitRepoLocationInput';
import { AlertItem } from '../../../../services/helpers/types';
import { selectWorkspacesSettings } from '../../../../store/Workspaces/Settings/selectors';

type Props =
MappedProps
Expand Down Expand Up @@ -60,6 +61,16 @@ export class ImportFromGit extends React.PureComponent<Props, State> {
}

private async handleLocationChange(location: string): Promise<void> {
// if devWorkspace is enabled
// use factory workflow to load the git location
const cheDevworkspaceEnabled = this.props.workspacesSettings['che.devworkspaces.enabled'] === 'true';
if (cheDevworkspaceEnabled) {
const factoryUrl = `${window.location.origin}/#${location}`;
// open a new page to handle that
window.open(factoryUrl, '_blank');
return;
}

try {
this.setState({ isLoading: true });
await this.props.requestFactoryResolver(location);
Expand Down Expand Up @@ -134,6 +145,7 @@ export class ImportFromGit extends React.PureComponent<Props, State> {

const mapStateToProps = (state: AppState) => ({
factoryResolver: state.factoryResolver,
workspacesSettings: selectWorkspacesSettings(state),
});

const connector = connect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import { AlertItem } from '../../../services/helpers/types';
import { selectMetadataFiltered } from '../../../store/DevfileRegistries/selectors';
import { selectWorkspacesSettings } from '../../../store/Workspaces/Settings/selectors';
import * as FactoryResolverStore from '../../../store/FactoryResolver';
import stringify from '../../../services/helpers/editor';
import { updateDevfileMetadata } from '../updateDevfileMetadata';

type Props =
MappedProps
Expand Down Expand Up @@ -102,10 +100,12 @@ export class SamplesListGallery extends React.PureComponent<Props, State> {
let optionalFilesContent;
if (cheDevworkspaceEnabled) {
const link = meta.links.v2;
await this.props.requestFactoryResolver(link);
const resolver = this.props.factoryResolver.resolver;
devfileContent = stringify(updateDevfileMetadata(resolver.devfile, meta));
optionalFilesContent = resolver.optionalFilesContent;
// use factory workflow to load the getting started samples
const factoryUrl = `${window.location.origin}/#${link}`;
// open a new page to handle that
window.open(factoryUrl, '_blank');
this.isLoading = false;
return;
} else {
devfileContent = await this.props.requestDevfile(meta.links.self) as string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ describe('Samples List Gallery', () => {
let resolveFn: {
(value?: unknown): void;
};
const onCardClickedPromise = new Promise(resolve => resolveFn = resolve);
const onCardClicked = jest.fn(() => resolveFn());

// eslint-disable-next-line
Expand All @@ -120,15 +119,11 @@ describe('Samples List Gallery', () => {
(mockAxios.get as any).mockResolvedValueOnce({
data: {},
});

const windowSpy = spyOn(window, 'open');
const cardHeader = screen.getByText('Java with Spring Boot and MySQL');
fireEvent.click(cardHeader);

await onCardClickedPromise;
expect(onCardClicked).toHaveBeenCalled();
jest.runOnlyPendingTimers();
// should have been called with the v2 link
await waitFor(() => expect(requestFactoryResolverMock).toHaveBeenCalledWith('http://my-fake-repository.com/'));
expect(windowSpy).toBeCalledWith('http://localhost/#http://my-fake-repository.com/', '_blank');

});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ function renderComponent(
hasError={hasError}
status={workspaceStatus}
ideUrl={ideUrl}
isDevWorkspace={false}
/>
</Provider>,
);
Expand Down
Loading

0 comments on commit aea3921

Please sign in to comment.