From 765527aef26c6fe3b285dbccd04898e2dc580fe5 Mon Sep 17 00:00:00 2001 From: Qxisylolo Date: Wed, 14 Aug 2024 18:37:58 +0800 Subject: [PATCH] [WorkSpace] Refractor homepage assets list section (#7702) * refractor assets section Signed-off-by: Qxisylolo * refractor assets section Signed-off-by: Qxisylolo * refractor assets section_1 Signed-off-by: Qxisylolo * Changeset file for PR #7702 created/updated * add new test Signed-off-by: Qxisylolo * delete border Signed-off-by: Qxisylolo --------- Signed-off-by: Qxisylolo Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> --- changelogs/fragments/7702.yml | 2 + .../management_section/recent_work.test.tsx | 22 ++- .../public/management_section/recent_work.tsx | 171 +++++++++++++----- .../saved_objects_management/public/plugin.ts | 18 +- 4 files changed, 151 insertions(+), 62 deletions(-) create mode 100644 changelogs/fragments/7702.yml diff --git a/changelogs/fragments/7702.yml b/changelogs/fragments/7702.yml new file mode 100644 index 000000000000..fe4b48169a40 --- /dev/null +++ b/changelogs/fragments/7702.yml @@ -0,0 +1,2 @@ +feat: +- Refractor the homepage assets list section ([#7702](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7702)) \ No newline at end of file diff --git a/src/plugins/saved_objects_management/public/management_section/recent_work.test.tsx b/src/plugins/saved_objects_management/public/management_section/recent_work.test.tsx index 6441ce280f68..4992a0247b09 100644 --- a/src/plugins/saved_objects_management/public/management_section/recent_work.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/recent_work.test.tsx @@ -10,6 +10,7 @@ import { RecentWork } from './recent_work'; import { coreMock } from '../../../../core/public/mocks'; import { ChromeRecentlyAccessedHistoryItem } from 'opensearch-dashboards/public'; import { SavedObjectWithMetadata } from '../types'; +import { APP_ID } from '../plugin'; const mockedRecentItems: ChromeRecentlyAccessedHistoryItem[] = [ { @@ -60,7 +61,7 @@ const getStartMockForRecentWork = () => { describe('', () => { it('render with emty recent work', async () => { const { findByText } = render(); - await findByText('No recent work'); + await findByText('No assets found'); }); it('render with recent works', async () => { @@ -85,14 +86,27 @@ describe('', () => { const allCards = await findAllByTestId('recentlyCard'); expect(allCards.length).toBe(2); expect(allCards[0].querySelector('.euiCard__titleAnchor')?.textContent).toEqual( - mockedRecentItems[0].label + mockedRecentItems[0].label.charAt(0).toUpperCase() + mockedRecentItems[0].label.slice(1) ); // click the filter button - fireEvent.click(getByTestId('filterButton-recently%20updated')); + fireEvent.click(getByTestId('filterButton-Recently%20updated')); const allCardsAfterSort = await findAllByTestId('recentlyCard'); expect(allCardsAfterSort[0].querySelector('.euiCard__titleAnchor')?.textContent).toEqual( - mockedRecentItems[1].label + mockedRecentItems[1].label.charAt(0).toUpperCase() + mockedRecentItems[1].label.slice(1) ); }); + + it('should be able to show view all button', () => { + const { getByText } = render(); + expect(getByText('View all')).toBeInTheDocument(); + }); + + it('shoule be able to be linked to the expected page when clicking View all button', () => { + const coreStartMock = getStartMockForRecentWork(); + const { getByText } = render(); + const mockedViewAllButton = getByText('View all'); + fireEvent.click(mockedViewAllButton); + expect(coreStartMock.application.navigateToApp).toHaveBeenCalledWith(APP_ID); + }); }); diff --git a/src/plugins/saved_objects_management/public/management_section/recent_work.tsx b/src/plugins/saved_objects_management/public/management_section/recent_work.tsx index 2e5b45e2cd63..04cae46c1cea 100644 --- a/src/plugins/saved_objects_management/public/management_section/recent_work.tsx +++ b/src/plugins/saved_objects_management/public/management_section/recent_work.tsx @@ -9,14 +9,18 @@ import { EuiFlexItem, EuiCard, EuiPanel, - EuiSpacer, + EuiFlexGrid, EuiFlexGroup, EuiTitle, EuiFilterGroup, EuiFilterButton, EuiComboBox, EuiIcon, + EuiLink, EuiEmptyPrompt, + EuiToolTip, + EuiSpacer, + EuiText, } from '@elastic/eui'; import { i18n } from '@osd/i18n'; import { @@ -26,18 +30,19 @@ import { } from 'opensearch-dashboards/public'; import { useObservable } from 'react-use'; import { SavedObjectWithMetadata } from 'src/plugins/saved_objects_management/common'; +import { APP_ID } from '../plugin'; import { createRecentNavLink } from '../../../../core/public'; const allOption = i18n.translate('savedObjectsManagement.recentWorkSection.all.items', { - defaultMessage: 'all items', + defaultMessage: 'All items', }); const recentlyViewed = i18n.translate('savedObjectsManagement.recentWorkSection.recentlyViewed', { - defaultMessage: 'recently viewed', + defaultMessage: 'Recently viewed', }); const recentlyUpdated = i18n.translate('savedObjectsManagement.recentWorkSection.recentlyUpdated', { - defaultMessage: 'recently updated', + defaultMessage: 'Recently updated', }); const sortKeyMap = { @@ -102,14 +107,18 @@ export const RecentWork = (props: { core: CoreStart; workspaceEnabled?: boolean const options: string[] = [allOption]; detailedSavedObjects .filter((item) => !item.error) - .forEach((recentAccessItem: ChromeRecentlyAccessedHistoryItem) => { - if (recentAccessItem.meta?.type && options.indexOf(recentAccessItem.meta.type) === -1) { - options.push(recentAccessItem.meta.type); + .forEach((recentAccessItem) => { + if (recentAccessItem?.type && options.indexOf(recentAccessItem?.type) === -1) { + options.push(recentAccessItem?.type); } }); return options.map((option: string) => ({ label: option, value: option })); }, [detailedSavedObjects]); + const capitalTheFirstLetter = function (recentAccessItem: DetailedRecentlyAccessedItem) { + return recentAccessItem.type.charAt(0).toUpperCase() + recentAccessItem.type.slice(1); + }; + const itemsForDisplay = useMemo(() => { const sortedResult = [...detailedSavedObjects] .filter((item) => !item.error) @@ -156,13 +165,30 @@ export const RecentWork = (props: { core: CoreStart; workspaceEnabled?: boolean - -
- {i18n.translate('savedObjectsManagement.recentWorkSection.title', { - defaultMessage: 'Assets', - })} -
-
+ + + +

+ {i18n.translate('savedObjectsManagement.recentWorkSection.title', { + defaultMessage: 'Assets', + })} +

+
+
+ + + + + +
@@ -170,8 +196,8 @@ export const RecentWork = (props: { core: CoreStart; workspaceEnabled?: boolean {[recentlyViewed, recentlyUpdated].map((item) => ( setSelectedSort(item)} data-test-subj={`filterButton-${encodeURIComponent(item)}`} > @@ -208,47 +234,80 @@ export const RecentWork = (props: { core: CoreStart; workspaceEnabled?: boolean core.http.basePath, core.application.navigateToUrl ); + content = ( + + + + + + {capitalTheFirstLetter(recentAccessItem)} + + + + } data-test-subj="recentlyCard" - description="" + description={

{recentAccessItem.label}

} textAlign="left" href={recentNavLink.href} footer={ <> -
- - {recentAccessItem.type} -
- -
- {selectedSort === recentlyViewed - ? i18n.translate('savedObjectsManagement.recentWorkSection.viewedAt', { - defaultMessage: 'Viewed', - }) - : i18n.translate('savedObjectsManagement.recentWorkSection.updatedAt', { - defaultMessage: 'Updated', - })} - :{' '} - - {selectedSort === recentlyViewed - ? moment(recentAccessItem?.lastAccessedTime).fromNow() - : moment(recentAccessItem?.updatedAt).fromNow()} - -
- {workspaceEnabled && ( -
- {i18n.translate('savedObjectsManagement.recentWorkSection.workspace', { - defaultMessage: 'Workspace', - })} - : {recentAccessItem.workspaceName || 'N/A'} -
- )} + + + + {selectedSort === recentlyViewed + ? i18n.translate( + 'savedObjectsManagement.recentWorkSection.viewedAt', + { + defaultMessage: 'Viewed', + } + ) + : i18n.translate( + 'savedObjectsManagement.recentWorkSection.updatedAt', + { + defaultMessage: 'Updated', + } + )} + :{' '} + + + + + + {selectedSort === recentlyViewed + ? moment(recentAccessItem?.lastAccessedTime).fromNow() + : moment(recentAccessItem?.updatedAt).fromNow()} + + + + + {workspaceEnabled && ( + <> + + + {i18n.translate( + 'savedObjectsManagement.recentWorkSection.workspace', + { + defaultMessage: 'Workspace', + } + )} + : + + + + + {recentAccessItem.workspaceName || 'N/A'} + + + + )} + } onClick={recentNavLink.onClick} @@ -262,15 +321,27 @@ export const RecentWork = (props: { core: CoreStart; workspaceEnabled?: boolean
) : ( } title={

{i18n.translate('savedObjectsManagement.recentWorkSection.empty.title', { - defaultMessage: 'No recent work', + defaultMessage: 'No assets found', })}

} + body={i18n.translate('savedObjectsManagement.recentWorkSection.empty.body', { + defaultMessage: "Assets you've recently viewed or updated will appear here.", + })} /> )} + + core.application.navigateToApp(APP_ID)}> + + {i18n.translate('home.list.card.view_all', { + defaultMessage: 'View all', + })} + +
); }; diff --git a/src/plugins/saved_objects_management/public/plugin.ts b/src/plugins/saved_objects_management/public/plugin.ts index e557c81e87a6..d91fb3db2271 100644 --- a/src/plugins/saved_objects_management/public/plugin.ts +++ b/src/plugins/saved_objects_management/public/plugin.ts @@ -68,6 +68,8 @@ import { RecentWork } from './management_section/recent_work'; import { HOME_CONTENT_AREAS } from '../../../plugins/home/public'; import { getScopedBreadcrumbs } from '../../opensearch_dashboards_react/public'; +export const APP_ID = 'objects'; + export interface SavedObjectsManagementPluginSetup { actions: SavedObjectsManagementActionServiceSetup; columns: SavedObjectsManagementColumnServiceSetup; @@ -141,7 +143,7 @@ export class SavedObjectsManagementPlugin const opensearchDashboardsSection = management.sections.section.opensearchDashboards; opensearchDashboardsSection.registerApp({ - id: 'objects', + id: APP_ID, title: i18n.translate('savedObjectsManagement.managementSectionLabel', { defaultMessage: 'Saved objects', }), @@ -160,7 +162,7 @@ export class SavedObjectsManagementPlugin if (core.chrome.navGroup.getNavGroupEnabled()) { core.application.register({ - id: 'objects', + id: APP_ID, title: i18n.translate('savedObjectsManagement.assets.label', { defaultMessage: 'Assets', }), @@ -187,14 +189,14 @@ export class SavedObjectsManagementPlugin core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.settingsAndSetup, [ { - id: 'objects', + id: APP_ID, order: 300, }, ]); core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.observability, [ { - id: 'objects', + id: APP_ID, category: DEFAULT_APP_CATEGORIES.manage, order: 300, }, @@ -202,7 +204,7 @@ export class SavedObjectsManagementPlugin core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.search, [ { - id: 'objects', + id: APP_ID, category: DEFAULT_APP_CATEGORIES.manage, order: 300, }, @@ -210,7 +212,7 @@ export class SavedObjectsManagementPlugin core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS['security-analytics'], [ { - id: 'objects', + id: APP_ID, category: DEFAULT_APP_CATEGORIES.manage, order: 300, }, @@ -218,7 +220,7 @@ export class SavedObjectsManagementPlugin core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.essentials, [ { - id: 'objects', + id: APP_ID, category: DEFAULT_APP_CATEGORIES.manage, order: 300, }, @@ -226,7 +228,7 @@ export class SavedObjectsManagementPlugin core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.all, [ { - id: 'objects', + id: APP_ID, category: DEFAULT_APP_CATEGORIES.manage, order: 300, },