From 01dcee95819707552cf7ab4f2b2c1efb4f65148b Mon Sep 17 00:00:00 2001 From: Lin Wang Date: Mon, 22 Jul 2024 17:02:26 +0800 Subject: [PATCH 1/4] Hide create workspace for non dashboard admin Signed-off-by: Lin Wang --- .../components/workspace_list/index.test.tsx | 15 +++++++++++- .../components/workspace_list/index.tsx | 23 ++++++++++++------- .../workspace_menu/workspace_menu.test.tsx | 17 +++++++++++++- .../workspace_menu/workspace_menu.tsx | 7 ++++-- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_list/index.test.tsx b/src/plugins/workspace/public/components/workspace_list/index.test.tsx index d939b8f84ea4..0212ebe670c4 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.test.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.test.tsx @@ -28,9 +28,16 @@ function getWrapWorkspaceListInContext( { id: 'id1', name: 'name1', features: ['use-case-all'] }, { id: 'id2', name: 'name2' }, { id: 'id3', name: 'name3', features: ['use-case-observability'] }, - ] + ], + isDashboardAdmin = true ) { const coreStartMock = coreMock.createStart(); + coreStartMock.application.capabilities = { + ...coreStartMock.application.capabilities, + dashboards: { + isDashboardAdmin, + }, + }; const services = { ...coreStartMock, @@ -135,4 +142,10 @@ describe('WorkspaceList', () => { expect(queryByText('name1')).not.toBeInTheDocument(); expect(getByText('name6')).toBeInTheDocument(); }); + + it('should hide create workspace button if not dashboard admin', async () => { + const { queryByText } = render(getWrapWorkspaceListInContext([], false)); + + expect(queryByText(/create workspace/)).toBeNull(); + }); }); diff --git a/src/plugins/workspace/public/components/workspace_list/index.tsx b/src/plugins/workspace/public/components/workspace_list/index.tsx index 04fae405af38..3d6604122e48 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.tsx @@ -26,7 +26,7 @@ import { WORKSPACE_CREATE_APP_ID } from '../../../common/constants'; import { cleanWorkspaceId } from '../../../../../core/public'; import { DeleteWorkspaceModal } from '../delete_workspace_modal'; -import { getFirstUseCaseOfFeatureConfigs, getUseCaseFromFeatureConfig } from '../../utils'; +import { getFirstUseCaseOfFeatureConfigs } from '../../utils'; import { WorkspaceUseCase } from '../../types'; const WORKSPACE_LIST_PAGE_DESCRIPTION = i18n.translate('workspace.list.description', { @@ -43,6 +43,7 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { services: { workspaces, application, http }, } = useOpenSearchDashboards(); const registeredUseCases = useObservable(registeredUseCases$); + const isDashboardAdmin = application?.capabilities?.dashboards?.isDashboardAdmin; const initialSortField = 'name'; const initialSortDirection = 'asc'; @@ -172,13 +173,19 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { incremental: true, }, toolsRight: [ - - Create workspace - , + ...(isDashboardAdmin + ? [ + + {i18n.translate('workspace.workspaceList.buttons.createWorkspace', { + defaultMessage: 'Create workspace', + })} + , + ] + : []), ], }; diff --git a/src/plugins/workspace/public/components/workspace_menu/workspace_menu.test.tsx b/src/plugins/workspace/public/components/workspace_menu/workspace_menu.test.tsx index 68ed1c67359f..6b1779a8f847 100644 --- a/src/plugins/workspace/public/components/workspace_menu/workspace_menu.test.tsx +++ b/src/plugins/workspace/public/components/workspace_menu/workspace_menu.test.tsx @@ -62,7 +62,7 @@ describe('', () => { it('should display a list of workspaces in the dropdown', () => { coreStartMock.workspaces.workspaceList$.next([ { id: 'workspace-1', name: 'workspace 1', features: [] }, - { id: 'workspace-2', name: 'workspace 2', features: [] }, + { id: 'workspace-2', name: 'workspace 2' }, ]); render(); @@ -170,4 +170,19 @@ describe('', () => { fireEvent.click(screen.getByText(/View all/i)); expect(coreStartMock.application.navigateToApp).toHaveBeenCalledWith('workspace_list'); }); + + it('should hide create workspace button for non dashboard admin', () => { + coreStartMock.application.capabilities = { + ...coreStartMock.application.capabilities, + dashboards: { + ...coreStartMock.application.capabilities.dashboards, + isDashboardAdmin: false, + }, + }; + render(); + + fireEvent.click(screen.getByTestId('workspace-select-button')); + expect(screen.getByText(/View all/i)).toBeInTheDocument(); + expect(screen.queryByText(/create workspaces/i)).toBeNull(); + }); }); diff --git a/src/plugins/workspace/public/components/workspace_menu/workspace_menu.tsx b/src/plugins/workspace/public/components/workspace_menu/workspace_menu.tsx index 77d1cd6e602e..63e6c756bb67 100644 --- a/src/plugins/workspace/public/components/workspace_menu/workspace_menu.tsx +++ b/src/plugins/workspace/public/components/workspace_menu/workspace_menu.tsx @@ -72,7 +72,7 @@ export const WorkspaceMenu = ({ coreStart, registeredUseCases$ }: Props) => { const [isPopoverOpen, setPopover] = useState(false); const currentWorkspace = useObservable(coreStart.workspaces.currentWorkspace$, null); const workspaceList = useObservable(coreStart.workspaces.workspaceList$, []); - const isDashboardAdmin = !!coreStart.application.capabilities.dashboards; + const isDashboardAdmin = coreStart.application.capabilities?.dashboards?.isDashboardAdmin; const availableUseCases = useObservable(registeredUseCases$, []); const filteredWorkspaceList = useMemo(() => { @@ -90,7 +90,10 @@ export const WorkspaceMenu = ({ coreStart, registeredUseCases$ }: Props) => { const currentWorkspaceName = currentWorkspace?.name ?? defaultHeaderName; const getUseCase = (workspace: WorkspaceObject) => { - const useCaseId = getFirstUseCaseOfFeatureConfigs(workspace?.features!); + if (!workspace.features) { + return; + } + const useCaseId = getFirstUseCaseOfFeatureConfigs(workspace.features); return availableUseCases.find((useCase) => useCase.id === useCaseId); }; From 26ae962a69836faf0b622a0b1f75a3add754d24c Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:40:53 +0000 Subject: [PATCH 2/4] Changeset file for PR #7357 created/updated --- changelogs/fragments/7357.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/7357.yml diff --git a/changelogs/fragments/7357.yml b/changelogs/fragments/7357.yml new file mode 100644 index 000000000000..801e0d0fd8e6 --- /dev/null +++ b/changelogs/fragments/7357.yml @@ -0,0 +1,2 @@ +feat: +- [Workspace]Hide create workspace button for non dashboard admin ([#7357](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7357)) \ No newline at end of file From 77e12716be896a0d9bc59c5ee720f19795b9b6d3 Mon Sep 17 00:00:00 2001 From: Lin Wang Date: Mon, 22 Jul 2024 18:10:58 +0800 Subject: [PATCH 3/4] Add more cases and update snapshot Signed-off-by: Lin Wang --- .../__snapshots__/index.test.tsx.snap | 19 ------------------- .../components/workspace_list/index.test.tsx | 8 +++++++- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap index 7281c89da589..32283810c139 100644 --- a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap +++ b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap @@ -81,25 +81,6 @@ exports[`WorkspaceList should render title and table normally 1`] = ` -
- -
{ expect(getByText('name6')).toBeInTheDocument(); }); - it('should hide create workspace button if not dashboard admin', async () => { + it('should display create workspace button for dashboard admin', async () => { + const { getByText } = render(getWrapWorkspaceListInContext([], true)); + + expect(getByText(/create workspace/)).toBeInTheDocument(); + }); + + it('should hide create workspace button for non dashboard admin', async () => { const { queryByText } = render(getWrapWorkspaceListInContext([], false)); expect(queryByText(/create workspace/)).toBeNull(); From c04e43554ca57aa11563cbcb450ba4097f990832 Mon Sep 17 00:00:00 2001 From: Lin Wang Date: Mon, 22 Jul 2024 18:49:30 +0800 Subject: [PATCH 4/4] Update match rule Signed-off-by: Lin Wang --- .../workspace/public/components/workspace_list/index.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_list/index.test.tsx b/src/plugins/workspace/public/components/workspace_list/index.test.tsx index fb2228ab1a2a..64f36fcb6c93 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.test.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.test.tsx @@ -146,12 +146,12 @@ describe('WorkspaceList', () => { it('should display create workspace button for dashboard admin', async () => { const { getByText } = render(getWrapWorkspaceListInContext([], true)); - expect(getByText(/create workspace/)).toBeInTheDocument(); + expect(getByText('Create workspace')).toBeInTheDocument(); }); it('should hide create workspace button for non dashboard admin', async () => { const { queryByText } = render(getWrapWorkspaceListInContext([], false)); - expect(queryByText(/create workspace/)).toBeNull(); + expect(queryByText('Create workspace')).toBeNull(); }); });