Skip to content

Commit

Permalink
Add update workspace page (opensearch-project#25)
Browse files Browse the repository at this point in the history
Signed-off-by: gaobinlong <[email protected]>
  • Loading branch information
gaobinlong authored and Hailong-am committed Jul 18, 2023
1 parent c346561 commit 0643fd4
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ export const WORKSPACE_ID_IN_SESSION_STORAGE = '_workspace_id_';
export const PATHS = {
create: '/create',
overview: '/overview',
update: '/update',
};
export const WORKSPACE_OP_TYPE_CREATE = 'create';
export const WORKSPACE_OP_TYPE_UPDATE = 'update';
6 changes: 6 additions & 0 deletions src/plugins/workspace/public/components/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { PATHS } from '../../common/constants';

import { WorkspaceCreator } from './workspace_creator';
import { WorkspaceUpdater } from './workspace_updater';
import { WorkspaceOverview } from './workspace_overview';

export interface RouteConfig {
Expand All @@ -26,4 +27,9 @@ export const ROUTES: RouteConfig[] = [
Component: WorkspaceOverview,
label: 'Overview',
},
{
path: PATHS.update,
Component: WorkspaceUpdater,
label: 'Update',
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { i18n } from '@osd/i18n';
import { useOpenSearchDashboards } from '../../../../../plugins/opensearch_dashboards_react/public';

import { WorkspaceForm, WorkspaceFormData } from './workspace_form';
import { WORKSPACE_OP_TYPE_CREATE } from '../../../common/constants';

export const WorkspaceCreator = () => {
const {
Expand Down Expand Up @@ -61,7 +62,11 @@ export const WorkspaceCreator = () => {
style={{ width: '100%', maxWidth: 1000 }}
>
{application && (
<WorkspaceForm application={application} onSubmit={handleWorkspaceFormSubmit} />
<WorkspaceForm
application={application}
onSubmit={handleWorkspaceFormSubmit}
opType={WORKSPACE_OP_TYPE_CREATE}
/>
)}
</EuiPageContent>
</EuiPageBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import { WorkspaceTemplate } from '../../../../../core/types';
import { AppNavLinkStatus, ApplicationStart } from '../../../../../core/public';
import { useApplications, useWorkspaceTemplate } from '../../hooks';
import { WORKSPACE_OP_TYPE_CREATE, WORKSPACE_OP_TYPE_UPDATE } from '../../../common/constants';

interface WorkspaceFeature {
id: string;
Expand Down Expand Up @@ -62,8 +63,14 @@ interface WorkspaceFormProps {
application: ApplicationStart;
onSubmit?: (formData: WorkspaceFormData) => void;
defaultValues?: WorkspaceFormData;
opType?: string;
}
export const WorkspaceForm = ({ application, onSubmit, defaultValues }: WorkspaceFormProps) => {
export const WorkspaceForm = ({
application,
onSubmit,
defaultValues,
opType,
}: WorkspaceFormProps) => {
const { workspaceTemplates, templateFeatureMap } = useWorkspaceTemplate(application);
const applications = useApplications(application);

Expand Down Expand Up @@ -199,7 +206,7 @@ export const WorkspaceForm = ({ application, onSubmit, defaultValues }: Workspac
</EuiTitle>
<EuiSpacer />
<EuiFormRow label="Name" isInvalid={!!formErrors.name} error={formErrors.name}>
<EuiFieldText onChange={handleNameInputChange} />
<EuiFieldText value={name} onChange={handleNameInputChange} />
</EuiFormRow>
<EuiFormRow
label={
Expand All @@ -208,7 +215,7 @@ export const WorkspaceForm = ({ application, onSubmit, defaultValues }: Workspac
</>
}
>
<EuiFieldText onChange={handleDescriptionInputChange} />
<EuiFieldText value={description} onChange={handleDescriptionInputChange} />
</EuiFormRow>
</EuiPanel>
<EuiSpacer />
Expand Down Expand Up @@ -329,9 +336,16 @@ export const WorkspaceForm = ({ application, onSubmit, defaultValues }: Workspac
</EuiPanel>
<EuiSpacer />
<EuiText textAlign="right">
<EuiButton form={formIdRef.current} type="submit" fill>
Create workspace
</EuiButton>
{opType === WORKSPACE_OP_TYPE_CREATE && (
<EuiButton form={formIdRef.current} type="submit" fill>
Create workspace
</EuiButton>
)}
{opType === WORKSPACE_OP_TYPE_UPDATE && (
<EuiButton form={formIdRef.current} type="submit" fill>
Update workspace
</EuiButton>
)}
</EuiText>
</EuiForm>
);
Expand Down
24 changes: 21 additions & 3 deletions src/plugins/workspace/public/components/workspace_overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,43 @@ import React from 'react';
import { EuiPageHeader, EuiButton, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { useObservable } from 'react-use';
import { of } from 'rxjs';
import { i18n } from '@osd/i18n';
import { PATHS } from '../../common/constants';
import { ApplicationStart } from '../../../../core/public';
import { WORKSPACE_APP_ID, WORKSPACE_ID_IN_SESSION_STORAGE } from '../../common/constants';

import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public';

export const WorkspaceOverview = () => {
const {
services: { workspaces },
} = useOpenSearchDashboards();
services: { workspaces, application, notifications },
} = useOpenSearchDashboards<{ application: ApplicationStart }>();

const currentWorkspace = useObservable(
workspaces ? workspaces.client.currentWorkspace$ : of(null)
);

const onUpdateWorkspaceClick = () => {
if (!currentWorkspace || !currentWorkspace.id) {
notifications?.toasts.addDanger({
title: i18n.translate('Cannot find current workspace', {
defaultMessage: 'Cannot update workspace',
}),
});
return;
}
application.navigateToApp(WORKSPACE_APP_ID, {
path: PATHS.update + '?' + WORKSPACE_ID_IN_SESSION_STORAGE + '=' + currentWorkspace.id,
});
};

return (
<>
<EuiPageHeader
pageTitle="Overview"
rightSideItems={[
<EuiButton color="danger">Delete</EuiButton>,
<EuiButton>Update</EuiButton>,
<EuiButton onClick={onUpdateWorkspaceClick}>Update</EuiButton>,
]}
/>
<EuiPanel>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { WorkspaceUpdater } from './workspace_updater';
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useCallback, useEffect, useState } from 'react';
import { EuiPage, EuiPageBody, EuiPageHeader, EuiPageContent } from '@elastic/eui';
import { useObservable } from 'react-use';
import { i18n } from '@osd/i18n';
import { of } from 'rxjs';

import { WorkspaceAttribute } from 'opensearch-dashboards/public';
import { useOpenSearchDashboards } from '../../../../../../src/plugins/opensearch_dashboards_react/public';

import { PATHS } from '../../../common/constants';
import { WorkspaceForm, WorkspaceFormData } from '../workspace_creator/workspace_form';
import {
WORKSPACE_APP_ID,
WORKSPACE_ID_IN_SESSION_STORAGE,
WORKSPACE_OP_TYPE_UPDATE,
} from '../../../common/constants';
import { ApplicationStart } from '../../../../../core/public';

export const WorkspaceUpdater = () => {
const {
services: { application, workspaces, notifications },
} = useOpenSearchDashboards<{ application: ApplicationStart }>();

const currentWorkspace = useObservable(
workspaces ? workspaces.client.currentWorkspace$ : of(null)
);

const excludedAttribute = 'id';
const { [excludedAttribute]: removedProperty, ...otherAttributes } =
currentWorkspace || ({} as WorkspaceAttribute);

const [currentWorkspaceFormData, setCurrentWorkspaceFormData] = useState<
Omit<WorkspaceAttribute, 'id'>
>(otherAttributes);

useEffect(() => {
const { id, ...others } = currentWorkspace || ({} as WorkspaceAttribute);
setCurrentWorkspaceFormData(others);
}, [workspaces, currentWorkspace, excludedAttribute]);

const handleWorkspaceFormSubmit = useCallback(
async (data: WorkspaceFormData) => {
let result;
if (!currentWorkspace) {
notifications?.toasts.addDanger({
title: i18n.translate('Cannot find current workspace', {
defaultMessage: 'Cannot update workspace',
}),
});
return;
}
try {
result = await workspaces?.client.update(currentWorkspace?.id, data);
} catch (error) {
notifications?.toasts.addDanger({
title: i18n.translate('workspace.update.failed', {
defaultMessage: 'Failed to update workspace',
}),
text: error instanceof Error ? error.message : JSON.stringify(error),
});
return;
}
if (result?.success) {
notifications?.toasts.addSuccess({
title: i18n.translate('workspace.update.success', {
defaultMessage: 'Update workspace successfully',
}),
});
application.navigateToApp(WORKSPACE_APP_ID, {
path: PATHS.overview + '?' + WORKSPACE_ID_IN_SESSION_STORAGE + '=' + currentWorkspace.id,
});
return;
}
notifications?.toasts.addDanger({
title: i18n.translate('workspace.update.failed', {
defaultMessage: 'Failed to update workspace',
}),
text: result?.error,
});
},
[notifications?.toasts, workspaces?.client, currentWorkspace, application]
);

if (!currentWorkspaceFormData.name) {
return null;
}

return (
<EuiPage paddingSize="none">
<EuiPageBody panelled>
<EuiPageHeader restrictWidth pageTitle="Update Workspace" />
<EuiPageContent
verticalPosition="center"
horizontalPosition="center"
paddingSize="none"
color="subdued"
hasShadow={false}
style={{ width: '100%', maxWidth: 1000 }}
>
{application && (
<WorkspaceForm
application={application}
onSubmit={handleWorkspaceFormSubmit}
defaultValues={currentWorkspaceFormData}
opType={WORKSPACE_OP_TYPE_UPDATE}
/>
)}
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
};

0 comments on commit 0643fd4

Please sign in to comment.