-
-
-
-
-
-
{
- it('renders correctly', () => {
- const tree = render();
- expect(tree.container).toMatchSnapshot();
- });
-});
diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_faq_panel.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_faq_panel.tsx
deleted file mode 100644
index 218e9a7618cf..000000000000
--- a/src/plugins/workspace/public/components/workspace_creator/workspace_faq_panel.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright OpenSearch Contributors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import React from 'react';
-import { EuiCard, EuiSpacer, EuiText } from '@elastic/eui';
-import { i18n } from '@osd/i18n';
-
-const WorkspaceFaqItem = ({ question, answer }: { question: string; answer: string }) => {
- return (
-
- {question}
- {answer}
-
- );
-};
-
-const FAQs = [
- {
- question: i18n.translate('workspace.form.faq.panel.question1', {
- defaultMessage: 'Can I change the workspace use case later?',
- }),
- answer: i18n.translate('workspace.form.faq.panel.answer1', {
- defaultMessage: 'You can only change to the All use case after workspace creation.',
- }),
- },
- {
- question: i18n.translate('workspace.form.faq.panel.question2', {
- defaultMessage: 'Why can’t I find the data sources I want to attached to the workspace? ',
- }),
- answer: i18n.translate('workspace.form.faq.panel.answer2', {
- defaultMessage:
- 'Available data sources to all workspaces here are configured by OpenSearch admin. Contact OpenSearch admin within your organization to add the requested data source. ',
- }),
- },
- {
- question: i18n.translate('workspace.form.faq.panel.question3', {
- defaultMessage:
- 'Do the added team members automatically gain access to the attached data sources?',
- }),
- answer: i18n.translate('workspace.form.faq.panel.answer3', {
- defaultMessage:
- 'No. Adding team members will only grant them access to the created workspace. To grant access to the attached data sources, contact the data source admin within your organization.',
- }),
- },
-];
-
-export const WorkspaceFaqPanel = () => {
- return (
-
- {FAQs.map(({ question, answer }, index) => (
-
-
- {index !== FAQs.length - 1 && (
- <>
-
-
- >
- )}
-
- ))}
-
- );
-};
diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.test.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.test.tsx
index cfe9e5833631..20975d2a064e 100644
--- a/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.test.tsx
+++ b/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.test.tsx
@@ -5,13 +5,10 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
-import {
- WorkspaceFormSummaryPanel,
- ExpandableTextList,
- FieldSummaryItem,
-} from './workspace_form_summary_panel';
+import { WorkspaceFormSummaryPanel, FieldSummaryItem } from './workspace_form_summary_panel';
import { RightSidebarScrollField } from './utils';
import { WorkspacePermissionItemType } from '../workspace_form';
+import { applicationServiceMock } from '../../../../../../src/core/public/mocks';
describe('WorkspaceFormSummaryPanel', () => {
const formData = {
@@ -26,9 +23,24 @@ describe('WorkspaceFormSummaryPanel', () => {
{ id: 'data-source-3', name: 'Data Source 3' },
],
permissionSettings: [
- { id: 1, type: WorkspacePermissionItemType.User, userId: 'user1' },
- { id: 2, type: WorkspacePermissionItemType.Group, group: 'group1' },
- { id: 3, type: WorkspacePermissionItemType.User, userId: 'user2' },
+ {
+ id: 1,
+ type: WorkspacePermissionItemType.User,
+ userId: 'user1',
+ modes: ['library_write', 'write'],
+ },
+ {
+ id: 2,
+ type: WorkspacePermissionItemType.Group,
+ group: 'group1',
+ modes: ['library_read', 'read'],
+ },
+ {
+ id: 3,
+ type: WorkspacePermissionItemType.User,
+ userId: 'user2',
+ modes: ['library_write', 'read'],
+ },
],
};
@@ -48,25 +60,36 @@ describe('WorkspaceFormSummaryPanel', () => {
},
];
+ const applicationMock = applicationServiceMock.createStartContract();
+
it('renders summary panel with correct data', () => {
render(
);
expect(screen.getByText('Summary')).toBeInTheDocument();
- expect(screen.getByText('Use Case 1')).toBeInTheDocument();
- expect(screen.getByText('This is Use Case 1')).toBeInTheDocument();
- expect(screen.getByText('Test Workspace')).toBeInTheDocument();
+ expect(screen.getByText('Workspace name')).toBeInTheDocument();
expect(screen.getByText('This is a test workspace')).toBeInTheDocument();
- expect(screen.getByText('#000000')).toBeInTheDocument();
+ expect(screen.getByText('Test Workspace')).toBeInTheDocument();
+ expect(screen.getByText('Use Case 1')).toBeInTheDocument();
expect(screen.getByText('Data Source 1')).toBeInTheDocument();
+ expect(screen.getByText('Data Source 2')).toBeInTheDocument();
+ expect(screen.getByText('Data Source 3')).toBeInTheDocument();
expect(screen.getByText('user1')).toBeInTheDocument();
+ expect(screen.getByText('Owner')).toBeInTheDocument();
expect(screen.getByText('group1')).toBeInTheDocument();
+ expect(screen.getByText('Read')).toBeInTheDocument();
+ expect(screen.getByText('+1 more')).toBeInTheDocument();
expect(screen.queryByText('user2')).toBeNull();
+ expect(screen.getByText('Cancel')).toBeInTheDocument();
+ expect(screen.getByText('Create workspace')).toBeInTheDocument();
});
it('renders placeholders for empty form data', () => {
@@ -81,6 +104,9 @@ describe('WorkspaceFormSummaryPanel', () => {
}}
availableUseCases={availableUseCases}
permissionEnabled
+ formId="id"
+ application={applicationMock}
+ isSubmitting={false}
/>
);
@@ -100,10 +126,6 @@ describe('WorkspaceFormSummaryPanel', () => {
);
expect(descriptionPlaceholder).toHaveTextContent('—');
- // Color placeholder
- const colorPlaceholder = screen.getByTestId('workspaceFormRightSideBarSummary-color-Value');
- expect(colorPlaceholder).toHaveTextContent('—');
-
// Data sources placeholder
const dataSourcesPlaceholder = screen.getByTestId(
'workspaceFormRightSideBarSummary-dataSource-Value'
@@ -112,34 +134,32 @@ describe('WorkspaceFormSummaryPanel', () => {
// Permissions placeholder
const permissionsPlaceholder = screen.getByTestId(
- 'workspaceFormRightSideBarSummary-member-Value'
+ 'workspaceFormRightSideBarSummary-collaborators-Value'
);
expect(permissionsPlaceholder).toHaveTextContent('—');
});
-});
-
-describe('ExpandableTextList', () => {
- it('renders all texts when expanded', () => {
- const texts = ['Text 1', 'Text 2', 'Text 3', 'Text 4'];
- render();
-
- expect(screen.getByText('Text 1')).toBeInTheDocument();
- expect(screen.getByText('Text 2')).toBeInTheDocument();
- expect(screen.queryByText('Text 3')).not.toBeInTheDocument();
- expect(screen.queryByText('Text 4')).not.toBeInTheDocument();
- fireEvent.click(screen.getByText('Show all'));
+ it('renders all items when expanded and hide some items when click show less', () => {
+ render(
+
+ );
+ expect(screen.getByText('user1')).toBeInTheDocument();
+ expect(screen.getByText('group1')).toBeInTheDocument();
+ expect(screen.queryByText('user2')).toBeNull();
+ fireEvent.click(screen.getByText('+1 more'));
- expect(screen.getByText('Text 3')).toBeInTheDocument();
- expect(screen.getByText('Text 4')).toBeInTheDocument();
- });
- it('should not show "Show all" button when all texts can be displayed', () => {
- const texts = ['Text 1', 'Text 2'];
- render();
+ expect(screen.getByText('user2')).toBeInTheDocument();
+ expect(screen.getByText('Show less')).toBeInTheDocument();
- expect(screen.getByText('Text 1')).toBeInTheDocument();
- expect(screen.getByText('Text 2')).toBeInTheDocument();
- expect(screen.queryByText('Show all')).not.toBeInTheDocument();
+ fireEvent.click(screen.getByText('Show less'));
+ expect(screen.queryByText('user2')).toBeNull();
});
});
@@ -149,14 +169,14 @@ describe('FieldSummaryItem', () => {
Content for Name
);
- expect(screen.getByText('Name')).toBeInTheDocument();
+ expect(screen.getByText('Workspace name')).toBeInTheDocument();
expect(screen.getByText('Content for Name')).toBeInTheDocument();
});
it('renders placeholder when no content is provided', () => {
render();
- expect(screen.getByText('Name')).toBeInTheDocument();
+ expect(screen.getByText('Workspace name')).toBeInTheDocument();
expect(screen.getByText('—')).toBeInTheDocument();
});
@@ -172,7 +192,7 @@ describe('FieldSummaryItem', () => {
);
- fireEvent.click(screen.getByText('Name'));
+ fireEvent.click(screen.getByText('Workspace name'));
expect(scrollIntoViewMock).toHaveBeenCalledWith({
behavior: 'smooth',
diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.tsx
index 126afb741595..28efcee4d69e 100644
--- a/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.tsx
+++ b/src/plugins/workspace/public/components/workspace_creator/workspace_form_summary_panel.tsx
@@ -13,18 +13,20 @@ import {
EuiText,
EuiTextColor,
EuiLink,
+ EuiBadge,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
+import { ApplicationStart } from 'opensearch-dashboards/public';
import { WorkspaceFormDataState } from '../workspace_form';
import { WorkspaceUseCase } from '../../types';
import { RightSidebarScrollField, RIGHT_SIDEBAR_SCROLL_KEY } from './utils';
+import { WorkspaceCreateActionPanel } from './workspace_create_action_panel';
+import { WorkspacePermissionMode } from '../../../common/constants';
+import { getPermissionModeName } from '../workspace_form/utils';
const SCROLL_FIELDS = {
- [RightSidebarScrollField.UseCase]: i18n.translate('workspace.form.summary.panel.useCase.title', {
- defaultMessage: 'Use case',
- }),
[RightSidebarScrollField.Name]: i18n.translate('workspace.form.summary.panel.name.title', {
- defaultMessage: 'Name',
+ defaultMessage: 'Workspace name',
}),
[RightSidebarScrollField.Description]: i18n.translate(
'workspace.form.summary.panel.description.title',
@@ -32,8 +34,11 @@ const SCROLL_FIELDS = {
defaultMessage: 'Description',
}
),
- [RightSidebarScrollField.Color]: i18n.translate('workspace.form.summary.panel.color.title', {
- defaultMessage: 'Workspace icon',
+ [RightSidebarScrollField.UseCase]: i18n.translate('workspace.form.summary.panel.useCase.title', {
+ defaultMessage: 'Use case',
+ }),
+ [RightSidebarScrollField.Color]: i18n.translate('workspace.form.summary.panel.color', {
+ defaultMessage: 'Color',
}),
[RightSidebarScrollField.DataSource]: i18n.translate(
'workspace.form.summary.panel.dataSources.title',
@@ -41,11 +46,19 @@ const SCROLL_FIELDS = {
defaultMessage: 'Data sources',
}
),
- [RightSidebarScrollField.Member]: i18n.translate('workspace.form.summary.panel.members.title', {
- defaultMessage: 'Members',
- }),
+ [RightSidebarScrollField.Collaborators]: i18n.translate(
+ 'workspace.form.summary.panel.collaborators.title',
+ {
+ defaultMessage: 'Collaborators',
+ }
+ ),
};
+interface UserAndGroups {
+ key: string;
+ modes: WorkspacePermissionMode[] | undefined;
+}
+
export const FieldSummaryItem = ({
field,
children,
@@ -86,110 +99,148 @@ export const FieldSummaryItem = ({
};
export const ExpandableTextList = ({
- texts,
+ items,
collapseDisplayCount,
}: {
- texts: string[];
+ items: React.JSX.Element[];
collapseDisplayCount: number;
}) => {
const [isExpanded, setIsExpanded] = useState(false);
- const uniqueTexts = Array.from(new Set(texts));
- const displayedTexts = isExpanded ? uniqueTexts : uniqueTexts.slice(0, collapseDisplayCount);
+ const displayedItems = isExpanded ? items : items.slice(0, collapseDisplayCount);
return (
<>
- {displayedTexts.map((text) => (
-
- {text}
-
- ))}
- {uniqueTexts.length > collapseDisplayCount && (
+ {displayedItems}
+ {items.length > collapseDisplayCount && (
{
setIsExpanded((flag) => !flag);
}}
>
- {isExpanded
- ? i18n.translate('workspace.form.summary.members.showLess', {
+
+
+ {isExpanded ? (
+
+ {i18n.translate('workspace.form.summary.items.showLess', {
defaultMessage: 'Show less',
- })
- : i18n.translate('workspace.form.summary.members.showAll', {
- defaultMessage: 'Show all',
})}
+
+ ) : (
+
+ {i18n.translate('workspace.form.summary.items.showAll', {
+ defaultMessage: '+{itemsOfNumber} more',
+ values: { itemsOfNumber: items.length - collapseDisplayCount },
+ })}
+
+ )}
)}
>
);
};
+const mapUserAndGroupToList = (userAndGroups: UserAndGroups[]) => {
+ return userAndGroups.map((userAndGroup) => {
+ return (
+
+ {userAndGroup.key}
+ {userAndGroup.modes && (
+
+ {getPermissionModeName(userAndGroup.modes)}
+
+ )}
+
+ );
+ });
+};
+
interface WorkspaceFormSummaryPanelProps {
formData: WorkspaceFormDataState;
availableUseCases: WorkspaceUseCase[];
permissionEnabled?: boolean;
+ formId: string;
+ application: ApplicationStart;
+ isSubmitting: boolean;
}
export const WorkspaceFormSummaryPanel = ({
formData,
availableUseCases,
permissionEnabled,
+ formId,
+ application,
+ isSubmitting,
}: WorkspaceFormSummaryPanelProps) => {
const useCase = availableUseCases.find((item) => item.id === formData.useCase);
- const userAndGroups = formData.permissionSettings.flatMap((setting) => {
- if ('userId' in setting && !!setting.userId) {
- return [setting.userId];
+ const userAndGroups: UserAndGroups[] = formData.permissionSettings.flatMap((setting) => {
+ const modesExist = 'modes' in setting && !!setting.modes;
+ if ('userId' in setting && !!setting.userId && modesExist) {
+ return [{ key: setting.userId, modes: setting.modes }];
}
- if ('group' in setting && !!setting.group) {
- return [setting.group];
+ if ('group' in setting && !!setting.group && modesExist) {
+ return [{ key: setting.group, modes: setting.modes }];
}
return [];
});
+ const useCaseIcon = useCase?.icon || 'logoOpenSearch';
return (
-
- {useCase && (
- <>
- {useCase.title}
- {useCase.description}
- >
- )}
-
- {formData.name}
-
- {formData.description?.trim()}
-
-
- {formData.color && (
+
+
+ {formData.name && (
- {useCase?.icon && (
-
-
-
- )}
+
+
+
- {formData.color}
+ {formData.name}
)}
+
+ {formData.description?.trim()}
+
+
+ {useCase && {useCase.title}}
+
{formData.selectedDataSourceConnections.length > 0 && (
name)}
- collapseDisplayCount={2}
+ items={formData.selectedDataSourceConnections.map((connection) => (
+
+ ))}
+ collapseDisplayCount={3}
/>
)}
{permissionEnabled && (
-
+
{userAndGroups.length > 0 && (
-
+
)}
)}
+
);
};
diff --git a/src/plugins/workspace/public/components/workspace_form/constants.ts b/src/plugins/workspace/public/components/workspace_form/constants.ts
index d614046c84d2..8d63d200e0de 100644
--- a/src/plugins/workspace/public/components/workspace_form/constants.ts
+++ b/src/plugins/workspace/public/components/workspace_form/constants.ts
@@ -122,3 +122,33 @@ export const DetailTabTitles: { [key in DetailTab]: string } = {
export const PERMISSION_TYPE_LABEL_ID = 'workspace-form-permission-type-label';
export const PERMISSION_COLLABORATOR_LABEL_ID = 'workspace-form-permission-collaborator-label';
export const PERMISSION_ACCESS_LEVEL_LABEL_ID = 'workspace-form-permission-access-level-label';
+
+export const permissionModeOptions = [
+ {
+ value: PermissionModeId.Read,
+ inputDisplay: i18n.translate(
+ 'workspace.form.permissionSettingPanel.permissionModeOptions.read',
+ {
+ defaultMessage: 'Read',
+ }
+ ),
+ },
+ {
+ value: PermissionModeId.ReadAndWrite,
+ inputDisplay: i18n.translate(
+ 'workspace.form.permissionSettingPanel.permissionModeOptions.readAndWrite',
+ {
+ defaultMessage: 'Read & Write',
+ }
+ ),
+ },
+ {
+ value: PermissionModeId.Owner,
+ inputDisplay: i18n.translate(
+ 'workspace.form.permissionSettingPanel.permissionModeOptions.owner',
+ {
+ defaultMessage: 'Owner',
+ }
+ ),
+ },
+];
diff --git a/src/plugins/workspace/public/components/workspace_form/index.ts b/src/plugins/workspace/public/components/workspace_form/index.ts
index 225d17bfe547..a58b2918a1b3 100644
--- a/src/plugins/workspace/public/components/workspace_form/index.ts
+++ b/src/plugins/workspace/public/components/workspace_form/index.ts
@@ -23,6 +23,7 @@ export {
selectDataSourceTitle,
workspaceDetailsTitle,
workspaceUseCaseTitle,
+ permissionModeOptions,
} from './constants';
export {
convertPermissionsToPermissionSettings,
diff --git a/src/plugins/workspace/public/components/workspace_form/utils.test.ts b/src/plugins/workspace/public/components/workspace_form/utils.test.ts
index 7671f08ee706..9f2557ecbfa5 100644
--- a/src/plugins/workspace/public/components/workspace_form/utils.test.ts
+++ b/src/plugins/workspace/public/components/workspace_form/utils.test.ts
@@ -10,6 +10,7 @@ import {
getNumberOfChanges,
getNumberOfErrors,
isWorkspacePermissionSetting,
+ getPermissionModeName,
} from './utils';
import { WorkspacePermissionMode } from '../../../common/constants';
import { WorkspacePermissionItemType, optionIdToWorkspacePermissionModesMap } from './constants';
@@ -695,3 +696,25 @@ describe('isWorkspacePermissionSetting', () => {
expect(result).toBe(false);
});
});
+
+describe('getPermissionModeName', () => {
+ it('should return Owner for a valid WorkspacePermissionMode mode', () => {
+ const result = getPermissionModeName(['library_write', 'write'] as WorkspacePermissionMode[]);
+ expect(result).toBe('Owner');
+ });
+
+ it('should return Read & write for a valid WorkspacePermissionMode mode', () => {
+ const result = getPermissionModeName(['library_write', 'read'] as WorkspacePermissionMode[]);
+ expect(result).toBe('Read & Write');
+ });
+
+ it('should return Read for a valid WorkspacePermissionMode mode', () => {
+ const result = getPermissionModeName(['library_read', 'read'] as WorkspacePermissionMode[]);
+ expect(result).toBe('Read');
+ });
+
+ it('should return Read for a invalid WorkspacePermissionMode mode', () => {
+ const result = getPermissionModeName([] as WorkspacePermissionMode[]);
+ expect(result).toBe('Read');
+ });
+});
diff --git a/src/plugins/workspace/public/components/workspace_form/utils.ts b/src/plugins/workspace/public/components/workspace_form/utils.ts
index 79c5501e9102..f6497315a262 100644
--- a/src/plugins/workspace/public/components/workspace_form/utils.ts
+++ b/src/plugins/workspace/public/components/workspace_form/utils.ts
@@ -10,6 +10,7 @@ import { CURRENT_USER_PLACEHOLDER, WorkspacePermissionMode } from '../../../comm
import { isUseCaseFeatureConfig } from '../../utils';
import {
optionIdToWorkspacePermissionModesMap,
+ permissionModeOptions,
WorkspaceOperationType,
WorkspacePermissionItemType,
} from './constants';
@@ -90,6 +91,16 @@ export const getPermissionModeId = (modes: WorkspacePermissionMode[]) => {
return PermissionModeId.Read;
};
+export const getPermissionModeName = (modes: WorkspacePermissionMode[]) => {
+ for (const key in optionIdToWorkspacePermissionModesMap) {
+ if (optionIdToWorkspacePermissionModesMap[key].every((mode) => modes?.includes(mode))) {
+ return permissionModeOptions.find((option) => option.value === key)?.inputDisplay;
+ }
+ }
+ return permissionModeOptions.find((option) => option.value === PermissionModeId.Read)
+ ?.inputDisplay;
+};
+
export const convertPermissionSettingsToPermissions = (
permissionItems: WorkspacePermissionSetting[] | undefined
) => {
diff --git a/src/plugins/workspace/public/components/workspace_form/workspace_permission_setting_input.tsx b/src/plugins/workspace/public/components/workspace_form/workspace_permission_setting_input.tsx
index bd156537940c..1b94fa315633 100644
--- a/src/plugins/workspace/public/components/workspace_form/workspace_permission_setting_input.tsx
+++ b/src/plugins/workspace/public/components/workspace_form/workspace_permission_setting_input.tsx
@@ -9,7 +9,6 @@ import {
EuiFlexItem,
EuiButtonIcon,
EuiSuperSelect,
- EuiSuperSelectOption,
EuiFieldText,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
@@ -20,39 +19,9 @@ import {
PERMISSION_TYPE_LABEL_ID,
PERMISSION_COLLABORATOR_LABEL_ID,
PERMISSION_ACCESS_LEVEL_LABEL_ID,
+ permissionModeOptions,
} from './constants';
import { getPermissionModeId } from './utils';
-import { PermissionModeId } from '../../../../../core/public';
-
-const permissionModeOptions = [
- {
- value: PermissionModeId.Read,
- inputDisplay: i18n.translate(
- 'workspace.form.permissionSettingPanel.permissionModeOptions.read',
- {
- defaultMessage: 'Read',
- }
- ),
- },
- {
- value: PermissionModeId.ReadAndWrite,
- inputDisplay: i18n.translate(
- 'workspace.form.permissionSettingPanel.permissionModeOptions.readAndWrite',
- {
- defaultMessage: 'Read & Write',
- }
- ),
- },
- {
- value: PermissionModeId.Owner,
- inputDisplay: i18n.translate(
- 'workspace.form.permissionSettingPanel.permissionModeOptions.owner',
- {
- defaultMessage: 'Owner',
- }
- ),
- },
-];
const typeOptions = [
{