Skip to content

Commit e5baae2

Browse files
opensearch-trigger-bot[bot]github-actions[bot]opensearch-changeset-bot[bot]
authored
[Workspace]Update details panel UI in workspace create page (#8375) (#8416)
* Update details panel UI in workspace create page * Changeset file for PR #8375 created/updated * Fix details panel title not rendered --------- (cherry picked from commit 71ab7bb) Signed-off-by: Lin Wang <[email protected]> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
1 parent ea5f614 commit e5baae2

File tree

5 files changed

+156
-70
lines changed

5 files changed

+156
-70
lines changed

changelogs/fragments/8375.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
feat:
2+
- [Workspace]Update details panel UI in workspace create page ([#8375](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8375))
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React from 'react';
7+
import {
8+
EuiColorPicker,
9+
EuiDescribedFormGroup,
10+
EuiFieldText,
11+
EuiFlexGroup,
12+
EuiFlexItem,
13+
EuiFormControlLayout,
14+
EuiFormRow,
15+
EuiPanel,
16+
EuiText,
17+
} from '@elastic/eui';
18+
import { EuiColorPickerOutput } from '@elastic/eui/src/components/color_picker/color_picker';
19+
import { i18n } from '@osd/i18n';
20+
import { WorkspaceDescriptionField, WorkspaceNameField } from '../workspace_form';
21+
import { generateRightSidebarScrollProps, RightSidebarScrollField } from './utils';
22+
23+
interface CreatorDetailsPanelProps {
24+
color?: string;
25+
name?: string;
26+
description?: string;
27+
onColorChange: (text: string, output: EuiColorPickerOutput) => void;
28+
onNameChange: (name: string) => void;
29+
onDescriptionChange: (description: string) => void;
30+
}
31+
32+
export const CreatorDetailsPanel = ({
33+
color,
34+
name,
35+
description,
36+
onColorChange,
37+
onNameChange,
38+
onDescriptionChange,
39+
}: CreatorDetailsPanelProps) => {
40+
return (
41+
<EuiPanel>
42+
<EuiText size="s">
43+
<h2>
44+
{i18n.translate('workspace.creator.details.panel.title', {
45+
defaultMessage: 'Workspace details',
46+
})}
47+
</h2>
48+
</EuiText>
49+
<EuiDescribedFormGroup
50+
title={
51+
<h4 {...generateRightSidebarScrollProps(RightSidebarScrollField.Name)}>
52+
{i18n.translate('workspace.creator.details.panel.fields.name.title', {
53+
defaultMessage: 'Workspace name',
54+
})}
55+
</h4>
56+
}
57+
description={i18n.translate('workspace.creator.details.panel.fields.name.description', {
58+
defaultMessage:
59+
'Use a unique name for the workspace. Valid characters are a-z, A-Z, 0-9, (), [], _ (underscore), - (hyphen) and (space). You can also select a color for the workspace icon.',
60+
})}
61+
>
62+
<EuiFlexGroup gutterSize="s">
63+
<EuiFlexItem style={{ maxWidth: 64 }} grow={false}>
64+
<EuiFormRow
65+
label={i18n.translate('workspace.creator.details.panel.fields.color.label', {
66+
defaultMessage: 'Color',
67+
})}
68+
{...generateRightSidebarScrollProps(RightSidebarScrollField.Color)}
69+
>
70+
<EuiColorPicker
71+
color={color}
72+
onChange={onColorChange}
73+
compressed
74+
button={
75+
<EuiFormControlLayout
76+
icon={{
77+
type: 'arrowDown',
78+
side: 'right',
79+
}}
80+
style={{ color }}
81+
compressed
82+
>
83+
{/** Add empty value here to keep the same UI with name input. Use read only will render a different background */}
84+
<EuiFieldText icon={{ type: 'swatchInput', size: 'm' }} value="" compressed />
85+
</EuiFormControlLayout>
86+
}
87+
/>
88+
</EuiFormRow>
89+
</EuiFlexItem>
90+
<EuiFlexItem>
91+
<WorkspaceNameField
92+
onChange={onNameChange}
93+
value={name}
94+
placeholder={i18n.translate(
95+
'workspace.creator.details.panel.fields.name.placeholder',
96+
{
97+
defaultMessage: 'Enter the name for the workspace',
98+
}
99+
)}
100+
showDescription={false}
101+
/>
102+
</EuiFlexItem>
103+
</EuiFlexGroup>
104+
</EuiDescribedFormGroup>
105+
<EuiDescribedFormGroup
106+
title={
107+
<h4 {...generateRightSidebarScrollProps(RightSidebarScrollField.Description)}>
108+
{i18n.translate('workspace.creator.details.panel.fields.description.title', {
109+
defaultMessage: 'Workspace description',
110+
})}
111+
</h4>
112+
}
113+
>
114+
<WorkspaceDescriptionField value={description} onChange={onDescriptionChange} />
115+
</EuiDescribedFormGroup>
116+
</EuiPanel>
117+
);
118+
};

src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ describe('WorkspaceCreator', () => {
232232
});
233233

234234
it('create workspace with detailed information', async () => {
235-
const { getByTestId } = render(<WorkspaceCreator />);
235+
const { getByTestId, getByRole } = render(<WorkspaceCreator />);
236236

237237
// Ensure workspace create form rendered
238238
await waitFor(() => {
@@ -246,18 +246,15 @@ describe('WorkspaceCreator', () => {
246246
fireEvent.input(descriptionInput, {
247247
target: { value: 'test workspace description' },
248248
});
249-
const colorSelector = getByTestId(
250-
'euiColorPickerAnchor workspaceForm-workspaceDetails-colorPicker'
251-
);
252-
fireEvent.input(colorSelector, {
253-
target: { value: '#000000' },
254-
});
249+
const colorSelector = getByTestId('euiColorPickerAnchor');
250+
fireEvent.click(colorSelector);
251+
fireEvent.click(getByRole('option', { name: 'Select #54B399 as the color' }));
255252
fireEvent.click(getByTestId('workspaceUseCase-observability'));
256253
fireEvent.click(getByTestId('workspaceForm-bottomBar-createButton'));
257254
expect(workspaceClientCreate).toHaveBeenCalledWith(
258255
expect.objectContaining({
259256
name: 'test workspace name',
260-
color: '#000000',
257+
color: '#54B399',
261258
description: 'test workspace description',
262259
features: expect.arrayContaining(['use-case-observability']),
263260
}),

src/plugins/workspace/public/components/workspace_creator/workspace_creator_form.tsx

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,7 @@
44
*/
55

66
import React, { useCallback, useRef } from 'react';
7-
import {
8-
EuiSpacer,
9-
EuiTitle,
10-
EuiForm,
11-
EuiText,
12-
EuiCompressedFormRow,
13-
EuiColorPicker,
14-
EuiFlexItem,
15-
EuiFlexGroup,
16-
} from '@elastic/eui';
7+
import { EuiSpacer, EuiTitle, EuiForm, EuiText, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
178
import { i18n } from '@osd/i18n';
189
import {
1910
useWorkspaceForm,
@@ -23,12 +14,11 @@ import {
2314
SelectDataSourcePanel,
2415
usersAndPermissionsCreatePageTitle,
2516
WorkspaceFormProps,
26-
WorkspaceNameField,
27-
WorkspaceDescriptionField,
2817
} from '../workspace_form';
2918

3019
import { WorkspaceFormSummaryPanel } from './workspace_form_summary_panel';
3120
import { generateRightSidebarScrollProps, RightSidebarScrollField } from './utils';
21+
import { CreatorDetailsPanel } from './creator_details_panel';
3222

3323
import './workspace_creator_form.scss';
3424

@@ -84,7 +74,7 @@ export const WorkspaceCreatorForm = (props: WorkspaceCreatorFormProps) => {
8474

8575
return (
8676
<EuiFlexGroup className="workspaceCreateFormContainer">
87-
<EuiFlexItem style={{ maxWidth: 768 }}>
77+
<EuiFlexItem style={{ maxWidth: 848 }}>
8878
<EuiForm
8979
id={formId}
9080
onSubmit={handleFormSubmit}
@@ -97,13 +87,15 @@ export const WorkspaceCreatorForm = (props: WorkspaceCreatorFormProps) => {
9787
<EuiSpacer />
9888
</>
9989
)}
100-
<EuiTitle size="xs">
101-
<h3>
102-
{i18n.translate('workspace.creator.form.customizeTitle', {
103-
defaultMessage: 'Customize the workspace',
104-
})}
105-
</h3>
106-
</EuiTitle>
90+
<CreatorDetailsPanel
91+
name={formData.name}
92+
color={formData.color}
93+
description={formData.description}
94+
onNameChange={handleNameInputChange}
95+
onColorChange={handleColorChange}
96+
onDescriptionChange={setDescription}
97+
/>
98+
<EuiSpacer size="m" />
10799
<div {...generateRightSidebarScrollProps(RightSidebarScrollField.UseCase)}>
108100
<WorkspaceUseCase
109101
value={formData.useCase}
@@ -113,40 +105,6 @@ export const WorkspaceCreatorForm = (props: WorkspaceCreatorFormProps) => {
113105
/>
114106
</div>
115107
<EuiSpacer size="m" />
116-
<div {...generateRightSidebarScrollProps(RightSidebarScrollField.Name)} />
117-
<WorkspaceNameField
118-
value={formData.name}
119-
onChange={handleNameInputChange}
120-
error={formErrors.name?.message}
121-
/>
122-
<EuiSpacer size="m" />
123-
<div {...generateRightSidebarScrollProps(RightSidebarScrollField.Description)} />
124-
<WorkspaceDescriptionField value={formData.description} onChange={setDescription} />
125-
<EuiSpacer size="m" />
126-
<EuiCompressedFormRow
127-
label={i18n.translate('workspace.form.workspaceDetails.color.label', {
128-
defaultMessage: 'Workspace icon color',
129-
})}
130-
isInvalid={!!formErrors.color}
131-
error={formErrors.color?.message}
132-
{...generateRightSidebarScrollProps(RightSidebarScrollField.Color)}
133-
>
134-
<div>
135-
<EuiText size="xs" color="subdued">
136-
{i18n.translate('workspace.form.workspaceDetails.color.description', {
137-
defaultMessage:
138-
'Select a background color for the icon representing this workspace.',
139-
})}
140-
</EuiText>
141-
<EuiSpacer size={'s'} />
142-
<EuiColorPicker
143-
color={formData.color}
144-
onChange={handleColorChange}
145-
data-test-subj="workspaceForm-workspaceDetails-colorPicker"
146-
/>
147-
</div>
148-
</EuiCompressedFormRow>
149-
<EuiSpacer />
150108
{/* SelectDataSourcePanel is only visible for dashboard admin and when data source is enabled*/}
151109
{isDashboardAdmin && isDataSourceEnabled && (
152110
<>

src/plugins/workspace/public/components/workspace_form/fields/workspace_name_field.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ export interface WorkspaceNameFieldProps {
1414
onChange: (newValue: string) => void;
1515
error?: string;
1616
readOnly?: boolean;
17+
placeholder?: string;
18+
showDescription?: boolean;
1719
}
1820

1921
export const WorkspaceNameField = ({
2022
value,
2123
error,
2224
readOnly,
2325
onChange,
26+
placeholder,
27+
showDescription = true,
2428
}: WorkspaceNameFieldProps) => {
2529
const handleChange = useCallback(
2630
(e) => {
@@ -46,11 +50,15 @@ export const WorkspaceNameField = ({
4650
},
4751
})}
4852
</EuiTextColor>
49-
<br />
50-
{i18n.translate('workspace.form.workspaceDetails.name.helpText', {
51-
defaultMessage:
52-
'Use a unique name for the workspace. Valid characters are a-z, A-Z, 0-9, (), [], _ (underscore), - (hyphen) and (space).',
53-
})}
53+
{showDescription && (
54+
<>
55+
<br />
56+
{i18n.translate('workspace.form.workspaceDetails.name.helpText', {
57+
defaultMessage:
58+
'Use a unique name for the workspace. Valid characters are a-z, A-Z, 0-9, (), [], _ (underscore), - (hyphen) and (space).',
59+
})}
60+
</>
61+
)}
5462
</>
5563
}
5664
isInvalid={!!error || charactersOverflow}
@@ -61,9 +69,12 @@ export const WorkspaceNameField = ({
6169
onChange={handleChange}
6270
readOnly={readOnly}
6371
data-test-subj="workspaceForm-workspaceDetails-nameInputText"
64-
placeholder={i18n.translate('workspace.form.workspaceDetails.name.placeholder', {
65-
defaultMessage: 'Enter a name',
66-
})}
72+
placeholder={
73+
placeholder ||
74+
i18n.translate('workspace.form.workspaceDetails.name.placeholder', {
75+
defaultMessage: 'Enter a name',
76+
})
77+
}
6778
/>
6879
</EuiCompressedFormRow>
6980
);

0 commit comments

Comments
 (0)