-
Notifications
You must be signed in to change notification settings - Fork 935
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Workspace] Refactor get start card at new home page (#7920)
* refactor started card Signed-off-by: yubonluo <[email protected]> * refactor new home page get start card Signed-off-by: yubonluo <[email protected]> * Changeset file for PR #7920 created/updated * revert code Signed-off-by: yubonluo <[email protected]> * optimize the code Signed-off-by: yubonluo <[email protected]> --------- Signed-off-by: yubonluo <[email protected]> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
- Loading branch information
1 parent
9697f33
commit d13007a
Showing
14 changed files
with
601 additions
and
427 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
refactor: | ||
- [Workspace] Refactor get start card at new home page ([#7920](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7920)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 198 additions & 0 deletions
198
src/plugins/workspace/public/components/home_get_start_card/setup_get_start_card.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { ContentManagementPluginStart } from '../../../../../plugins/content_management/public'; | ||
import { coreMock } from '../../../../../core/public/mocks'; | ||
import { registerGetStartedCardToNewHome } from './setup_get_start_card'; | ||
import { createMockedRegisteredUseCases$ } from '../../mocks'; | ||
import { WorkspaceObject } from 'opensearch-dashboards/public'; | ||
|
||
describe('Setup use get start card at new home page', () => { | ||
const navigateToApp = jest.fn(); | ||
|
||
const getMockCore = (workspaceList: WorkspaceObject[], isDashboardAdmin: boolean) => { | ||
const coreStartMock = coreMock.createStart(); | ||
coreStartMock.application.capabilities = { | ||
...coreStartMock.application.capabilities, | ||
dashboards: { isDashboardAdmin }, | ||
}; | ||
coreStartMock.workspaces.workspaceList$.next(workspaceList); | ||
coreStartMock.application = { | ||
...coreStartMock.application, | ||
navigateToApp, | ||
}; | ||
jest.spyOn(coreStartMock.application, 'getUrlForApp').mockImplementation((appId: string) => { | ||
return `https://test.com/app/${appId}`; | ||
}); | ||
return coreStartMock; | ||
}; | ||
const registerContentProviderMock = jest.fn(); | ||
const registeredUseCases$ = createMockedRegisteredUseCases$(); | ||
const useCasesMock = [ | ||
{ | ||
id: 'dataAdministration', | ||
title: 'Data administration', | ||
description: 'Apply policies or security on your data.', | ||
features: [ | ||
{ | ||
id: 'data_administration_landing', | ||
title: 'Overview', | ||
}, | ||
], | ||
systematic: true, | ||
order: 1000, | ||
}, | ||
{ | ||
id: 'essentials', | ||
title: 'Essentials', | ||
description: | ||
'Analyze data to derive insights, identify patterns and trends, and make data-driven decisions.', | ||
features: [ | ||
{ | ||
id: 'essentials_overview', | ||
title: 'Overview', | ||
}, | ||
{ | ||
id: 'discover', | ||
title: 'Discover', | ||
}, | ||
], | ||
systematic: false, | ||
order: 7000, | ||
}, | ||
]; | ||
registeredUseCases$.next(useCasesMock); | ||
|
||
const contentManagementStartMock: ContentManagementPluginStart = { | ||
registerContentProvider: registerContentProviderMock, | ||
renderPage: jest.fn(), | ||
updatePageSection: jest.fn(), | ||
}; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should return a tooltip message when there are no workspaces and the user is not dashboard admin', () => { | ||
const core = getMockCore([], false); | ||
registerGetStartedCardToNewHome(core, contentManagementStartMock, registeredUseCases$); | ||
|
||
const calls = registerContentProviderMock.mock.calls; | ||
expect(calls.length).toBe(1); | ||
|
||
const firstCall = calls[0]; | ||
expect(firstCall[0].getTargetArea()).toMatchInlineSnapshot(` | ||
Array [ | ||
"osd_homepage/get_started", | ||
] | ||
`); | ||
expect(firstCall[0].getContent()).toMatchInlineSnapshot(` | ||
Object { | ||
"cardProps": Object { | ||
"layout": "horizontal", | ||
}, | ||
"description": "Analyze data to derive insights, identify patterns and trends, and make data-driven decisions.", | ||
"getIcon": [Function], | ||
"id": "essentials", | ||
"kind": "card", | ||
"order": 1000, | ||
"title": "Essentials", | ||
"toolTipContent": "Contact your administrator to create a workspace or to be added to an existing one.", | ||
} | ||
`); | ||
}); | ||
|
||
it('should return a getTitle function when there are no workspaces and the user is dashboard admin', () => { | ||
const core = getMockCore([], true); | ||
registerGetStartedCardToNewHome(core, contentManagementStartMock, registeredUseCases$); | ||
|
||
const calls = registerContentProviderMock.mock.calls; | ||
expect(calls.length).toBe(1); | ||
|
||
const firstCall = calls[0]; | ||
expect(firstCall[0].getTargetArea()).toMatchInlineSnapshot(` | ||
Array [ | ||
"osd_homepage/get_started", | ||
] | ||
`); | ||
expect(firstCall[0].getContent()).toMatchInlineSnapshot(` | ||
Object { | ||
"cardProps": Object { | ||
"layout": "horizontal", | ||
}, | ||
"description": "Analyze data to derive insights, identify patterns and trends, and make data-driven decisions.", | ||
"getIcon": [Function], | ||
"getTitle": [Function], | ||
"id": "essentials", | ||
"kind": "card", | ||
"order": 1000, | ||
} | ||
`); | ||
}); | ||
|
||
it('should return a getTitle function for multiple workspaces', () => { | ||
const workspaces = [ | ||
{ id: 'workspace-1', name: 'workspace 1', features: ['use-case-essentials'] }, | ||
{ id: 'workspace-2', name: 'workspace 2', features: ['use-case-essentials'] }, | ||
]; | ||
const core = getMockCore(workspaces, true); | ||
registerGetStartedCardToNewHome(core, contentManagementStartMock, registeredUseCases$); | ||
|
||
const calls = registerContentProviderMock.mock.calls; | ||
expect(calls.length).toBe(1); | ||
|
||
const firstCall = calls[0]; | ||
expect(firstCall[0].getTargetArea()).toMatchInlineSnapshot(` | ||
Array [ | ||
"osd_homepage/get_started", | ||
] | ||
`); | ||
expect(firstCall[0].getContent()).toMatchInlineSnapshot(` | ||
Object { | ||
"cardProps": Object { | ||
"layout": "horizontal", | ||
}, | ||
"description": "Analyze data to derive insights, identify patterns and trends, and make data-driven decisions.", | ||
"getIcon": [Function], | ||
"getTitle": [Function], | ||
"id": "essentials", | ||
"kind": "card", | ||
"order": 1000, | ||
} | ||
`); | ||
}); | ||
|
||
it('should return a clickable card when there is one workspace', () => { | ||
const workspaces = [ | ||
{ id: 'workspace-1', name: 'workspace 1', features: ['use-case-essentials'] }, | ||
]; | ||
const core = getMockCore(workspaces, true); | ||
registerGetStartedCardToNewHome(core, contentManagementStartMock, registeredUseCases$); | ||
|
||
const calls = registerContentProviderMock.mock.calls; | ||
expect(calls.length).toBe(1); | ||
|
||
const firstCall = calls[0]; | ||
expect(firstCall[0].getTargetArea()).toMatchInlineSnapshot(` | ||
Array [ | ||
"osd_homepage/get_started", | ||
] | ||
`); | ||
expect(firstCall[0].getContent()).toMatchInlineSnapshot(` | ||
Object { | ||
"cardProps": Object { | ||
"layout": "horizontal", | ||
}, | ||
"description": "Analyze data to derive insights, identify patterns and trends, and make data-driven decisions.", | ||
"getIcon": [Function], | ||
"id": "essentials", | ||
"kind": "card", | ||
"onClick": [Function], | ||
"order": 1000, | ||
"title": "Essentials", | ||
} | ||
`); | ||
}); | ||
}); |
76 changes: 76 additions & 0 deletions
76
src/plugins/workspace/public/components/home_get_start_card/setup_get_start_card.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
import React from 'react'; | ||
import { CoreStart } from 'opensearch-dashboards/public'; | ||
import { EuiIcon } from '@elastic/eui'; | ||
import { BehaviorSubject } from 'rxjs'; | ||
import { i18n } from '@osd/i18n'; | ||
import { | ||
ContentManagementPluginStart, | ||
HOME_CONTENT_AREAS, | ||
} from '../../../../content_management/public'; | ||
import { WorkspaceUseCase } from '../../types'; | ||
import { getFirstUseCaseOfFeatureConfigs, getUseCaseUrl } from '../../utils'; | ||
import { UseCaseCardTitle } from './use_case_card_title'; | ||
|
||
const createContentCard = (useCase: WorkspaceUseCase, core: CoreStart) => { | ||
const { workspaces, application, http } = core; | ||
const workspaceList = workspaces.workspaceList$.getValue(); | ||
const isDashboardAdmin = application.capabilities?.dashboards?.isDashboardAdmin; | ||
const filterWorkspaces = workspaceList.filter( | ||
(workspace) => getFirstUseCaseOfFeatureConfigs(workspace?.features || []) === useCase.id | ||
); | ||
if (filterWorkspaces.length === 0 && !isDashboardAdmin) { | ||
return { | ||
title: useCase.title, | ||
toolTipContent: i18n.translate('workspace.getStartCard.noWorkspace.toolTip', { | ||
defaultMessage: | ||
'Contact your administrator to create a workspace or to be added to an existing one.', | ||
}), | ||
}; | ||
} else if (filterWorkspaces.length === 1) { | ||
const useCaseUrl = getUseCaseUrl(useCase, filterWorkspaces[0], application, http); | ||
return { | ||
onClick: () => { | ||
application.navigateToUrl(useCaseUrl); | ||
}, | ||
title: useCase.title, | ||
}; | ||
} | ||
return { | ||
getTitle: () => | ||
React.createElement(UseCaseCardTitle, { | ||
filterWorkspaces, | ||
useCase, | ||
core, | ||
}), | ||
}; | ||
}; | ||
|
||
export const registerGetStartedCardToNewHome = ( | ||
core: CoreStart, | ||
contentManagement: ContentManagementPluginStart, | ||
registeredUseCases$: BehaviorSubject<WorkspaceUseCase[]> | ||
) => { | ||
const availableUseCases = registeredUseCases$.getValue().filter((item) => !item.systematic); | ||
availableUseCases.forEach((useCase, index) => { | ||
const content = createContentCard(useCase, core); | ||
contentManagement.registerContentProvider({ | ||
id: `home_get_start_${useCase.id}`, | ||
getTargetArea: () => [HOME_CONTENT_AREAS.GET_STARTED], | ||
getContent: () => ({ | ||
id: useCase.id, | ||
kind: 'card', | ||
order: (index + 1) * 1000, | ||
description: useCase.description, | ||
...content, | ||
getIcon: () => React.createElement(EuiIcon, { size: 'xl', type: 'logoOpenSearch' }), | ||
cardProps: { | ||
layout: 'horizontal', | ||
}, | ||
}), | ||
}); | ||
}); | ||
}; |
Oops, something went wrong.