Skip to content

Commit

Permalink
feat: add workspace create and overview page
Browse files Browse the repository at this point in the history
Signed-off-by: Lin Wang <wonglam@amazon.com>
  • Loading branch information
wanglam committed Oct 26, 2023
1 parent c29d506 commit 5dcb419
Show file tree
Hide file tree
Showing 24 changed files with 2,436 additions and 47 deletions.
10 changes: 10 additions & 0 deletions src/core/public/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ export interface App<HistoryLocationState = unknown> {
* ```
*/
exactRoute?: boolean;

/**
* The dependencies of one application, required feature will be automatic select and can't
* be unselect in the workspace configuration.
*/
dependencies?: {
[key: string]: {
type: 'required' | 'optional';
};
};
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@
export const WORKSPACE_UPDATE_APP_ID = 'workspace_update';
export const WORKSPACE_OVERVIEW_APP_ID = 'workspace_overview';
export const WORKSPACE_FATAL_ERROR_APP_ID = 'workspace_fatal_error';
export const WORKSPACE_CREATE_APP_ID = 'workspace_create';

// These features will be checked and disabled in checkbox on default.
export const DEFAULT_CHECKED_FEATURES_IDS = [WORKSPACE_OVERVIEW_APP_ID];

export const WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace';
export const WORKSPACE_OP_TYPE_CREATE = 'create';
8 changes: 8 additions & 0 deletions src/plugins/workspace/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export type WorkspacePermissionItem<T extends string> = {
modes: T[];
} & ({ type: 'user'; userId: string } | { type: 'group'; group: string });
28 changes: 28 additions & 0 deletions src/plugins/workspace/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import ReactDOM from 'react-dom';
import { AppMountParameters, ScopedHistory } from '../../../core/public';
import { OpenSearchDashboardsContextProvider } from '../../opensearch_dashboards_react/public';
import { WorkspaceFatalError } from './components/workspace_fatal_error';
import { WorkspaceCreatorApp } from './components/workspace_creator_app';
import { WorkspaceOverviewApp } from './components/workspace_overview_app';
import { Services } from './types';

export const renderFatalErrorApp = (params: AppMountParameters, services: Services) => {
Expand All @@ -24,3 +26,29 @@ export const renderFatalErrorApp = (params: AppMountParameters, services: Servic
ReactDOM.unmountComponentAtNode(element);
};
};

export const renderCreatorApp = ({ element }: AppMountParameters, services: Services) => {
ReactDOM.render(
<OpenSearchDashboardsContextProvider services={services}>
<WorkspaceCreatorApp />
</OpenSearchDashboardsContextProvider>,
element
);

return () => {
ReactDOM.unmountComponentAtNode(element);
};
};

export const renderOverviewApp = ({ element }: AppMountParameters, services: Services) => {
ReactDOM.render(
<OpenSearchDashboardsContextProvider services={services}>
<WorkspaceOverviewApp />
</OpenSearchDashboardsContextProvider>,
element
);

return () => {
ReactDOM.unmountComponentAtNode(element);
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { WorkspaceCreator } from './workspace_creator';
export { WorkspacePermissionSetting } from './workspace_permission_setting_panel';
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import {
EuiBottomBar,
EuiButton,
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiText,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
import React, { useState } from 'react';
import { ApplicationStart } from 'opensearch-dashboards/public';
import { WORKSPACE_OP_TYPE_CREATE, WORKSPACE_OP_TYPE_UPDATE } from '../../../common/constants';
import { WorkspaceCancelModal } from './workspace_cancel_modal';

interface WorkspaceBottomBarProps {
formId: string;
opType?: string;
numberOfErrors: number;
application: ApplicationStart;
}

// Number of saved changes will be implemented in workspace update page PR
export const WorkspaceBottomBar = ({
formId,
opType,
numberOfErrors,
application,
}: WorkspaceBottomBarProps) => {
const [isCancelModalVisible, setIsCancelModalVisible] = useState(false);
const closeCancelModal = () => setIsCancelModalVisible(false);
const showCancelModal = () => setIsCancelModalVisible(true);

return (
<div>
<EuiSpacer size="xl" />
<EuiSpacer size="xl" />
<EuiBottomBar>
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="s">
{opType === WORKSPACE_OP_TYPE_UPDATE ? (
<EuiText textAlign="left">
{i18n.translate('workspace.form.bottomBar.unsavedChanges', {
defaultMessage: '1 Unsaved change(s)',
})}
</EuiText>
) : (
<EuiText textAlign="left">
{i18n.translate('workspace.form.bottomBar.errors', {
defaultMessage: `${numberOfErrors} Error(s)`,
})}
</EuiText>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="m">
<EuiButtonEmpty
color="ghost"
onClick={showCancelModal}
data-test-subj="workspaceForm-bottomBar-cancelButton"
>
{i18n.translate('workspace.form.bottomBar.cancel', {
defaultMessage: 'Cancel',
})}
</EuiButtonEmpty>
<EuiSpacer />
{opType === WORKSPACE_OP_TYPE_CREATE && (
<EuiButton
fill
type="submit"
color="primary"
form={formId}
data-test-subj="workspaceForm-bottomBar-createButton"
>
{i18n.translate('workspace.form.bottomBar.createWorkspace', {
defaultMessage: 'Create workspace',
})}
</EuiButton>
)}
{opType === WORKSPACE_OP_TYPE_UPDATE && (
<EuiButton form={formId} type="submit" fill color="primary">
{i18n.translate('workspace.form.bottomBar.saveChanges', {
defaultMessage: 'Save changes',
})}
</EuiButton>
)}
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiBottomBar>
<WorkspaceCancelModal
application={application}
visible={isCancelModalVisible}
closeCancelModal={closeCancelModal}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { i18n } from '@osd/i18n';
import { EuiConfirmModal } from '@elastic/eui';
import { ApplicationStart } from 'opensearch-dashboards/public';
import { WORKSPACE_LIST_APP_ID } from '../../../common/constants';

interface WorkspaceCancelModalProps {
visible: boolean;
application: ApplicationStart;
closeCancelModal: () => void;
}

export const WorkspaceCancelModal = ({
application,
visible,
closeCancelModal,
}: WorkspaceCancelModalProps) => {
if (!visible) {
return null;
}

return (
<EuiConfirmModal
data-test-subj="workspaceForm-cancelModal"
title={i18n.translate('workspace.form.cancelModal.title', {
defaultMessage: 'Discard changes?',
})}
onCancel={closeCancelModal}
onConfirm={() => application?.navigateToApp(WORKSPACE_LIST_APP_ID)}
cancelButtonText={i18n.translate('workspace.form.cancelButtonText.', {
defaultMessage: 'Continue editing',
})}
confirmButtonText={i18n.translate('workspace.form.confirmButtonText.', {
defaultMessage: 'Discard changes',
})}
buttonColor="danger"
defaultFocusedButton="confirm"
>
{i18n.translate('workspace.form.cancelModal.body', {
defaultMessage: 'This will discard all changes. Are you sure?',
})}
</EuiConfirmModal>
);
};
Loading

0 comments on commit 5dcb419

Please sign in to comment.