diff --git a/src/plugins/workspace/public/components/service_card/__snapshots__/workspace_list_card.test.tsx.snap b/src/plugins/workspace/public/components/service_card/__snapshots__/workspace_list_card.test.tsx.snap index ca48a73e7a40..35970676eb7e 100644 --- a/src/plugins/workspace/public/components/service_card/__snapshots__/workspace_list_card.test.tsx.snap +++ b/src/plugins/workspace/public/components/service_card/__snapshots__/workspace_list_card.test.tsx.snap @@ -24,7 +24,7 @@ exports[`workspace list card render normally should show workspace list card cor class="euiToolTipAnchor" > diff --git a/src/plugins/workspace/public/components/service_card/workspace_list_card.tsx b/src/plugins/workspace/public/components/service_card/workspace_list_card.tsx index 451fd33e90ad..12b14325ce11 100644 --- a/src/plugins/workspace/public/components/service_card/workspace_list_card.tsx +++ b/src/plugins/workspace/public/components/service_card/workspace_list_card.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { Component } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { EuiPanel, EuiLink, @@ -21,16 +21,15 @@ import { EuiEmptyPrompt, } from '@elastic/eui'; import { i18n } from '@osd/i18n'; -import { Subscription } from 'rxjs'; import moment from 'moment'; import { orderBy } from 'lodash'; import { CoreStart, WorkspaceObject } from '../../../../../core/public'; import { navigateToWorkspaceDetail } from '../utils/workspace'; import { WORKSPACE_CREATE_APP_ID, WORKSPACE_LIST_APP_ID } from '../../../common/constants'; -import { WorkspaceEntry, recentWorkspaceManager } from '../../recent_workspace_manager'; +import { recentWorkspaceManager } from '../../recent_workspace_manager'; -const WORKSPACE_LIST_CARD_DESCRIPTIOIN = i18n.translate('workspace.list.card.descriptionh', { +const WORKSPACE_LIST_CARD_DESCRIPTION = i18n.translate('workspace.list.card.description', { defaultMessage: 'Workspaces are dedicated environments for organizing and collaborating on your data, dashboards, and analytics workflows. Each Workspace acts as a self-contained space with its own set of saved objects and access controls.', }); @@ -41,53 +40,32 @@ export interface WorkspaceListCardProps { core: CoreStart; } -export interface WorkspaceListItem { - id: string; - name: string; - time?: string | number; -} - -export interface WorkspaceListCardState { - availiableWorkspaces: WorkspaceObject[]; - filter: string; - recentWorkspaces: WorkspaceEntry[]; -} +export const WorkspaceListCard = (props: WorkspaceListCardProps) => { + const [availableWorkspaces, setAvailableWorkspaces] = useState([]); + const [filter, setFilter] = useState('viewed'); -export class WorkspaceListCard extends Component { - private workspaceSub?: Subscription; - constructor(props: WorkspaceListCardProps) { - super(props); - this.state = { - availiableWorkspaces: [], - recentWorkspaces: recentWorkspaceManager.getRecentWorkspaces() || [], - filter: 'viewed', - }; - } - - componentDidMount() { - this.workspaceSub = this.props.core.workspaces.workspaceList$.subscribe((list) => { - this.setState({ - availiableWorkspaces: list || [], - }); + useEffect(() => { + const workspaceSub = props.core.workspaces.workspaceList$.subscribe((list) => { + setAvailableWorkspaces(list || []); }); - } - - componentWillUnmount() { - this.workspaceSub?.unsubscribe(); - } + return () => { + workspaceSub.unsubscribe(); + }; + }, [props.core]); - private loadWorkspaceListItems() { - if (this.state.filter === 'viewed') { - return orderBy(this.state.recentWorkspaces, ['timestamp'], ['desc']) - .filter((ws) => this.state.availiableWorkspaces.some((a) => a.id === ws.id)) + const workspaceList = useMemo(() => { + const recentWorkspaces = recentWorkspaceManager.getRecentWorkspaces() || []; + if (filter === 'viewed') { + return orderBy(recentWorkspaces, ['timestamp'], ['desc']) + .filter((ws) => availableWorkspaces.some((a) => a.id === ws.id)) .slice(0, MAX_ITEM_IN_LIST) .map((item) => ({ id: item.id, - name: this.state.availiableWorkspaces.find((ws) => ws.id === item.id)?.name!, + name: availableWorkspaces.find((ws) => ws.id === item.id)?.name!, time: item.timestamp, })); - } else if (this.state.filter === 'updated') { - return orderBy(this.state.availiableWorkspaces, ['lastUpdatedTime'], ['desc']) + } else if (filter === 'updated') { + return orderBy(availableWorkspaces, ['lastUpdatedTime'], ['desc']) .slice(0, MAX_ITEM_IN_LIST) .map((ws) => ({ id: ws.id, @@ -96,122 +74,119 @@ export class WorkspaceListCard extends Component { - const { application, http } = this.props.core; + const handleSwitchWorkspace = (id: string) => { + const { application, http } = props.core; if (application && http) { navigateToWorkspaceDetail({ application, http }, id); } }; - render() { - const workspaceList = this.loadWorkspaceListItems(); - const { application } = this.props.core; - - const isDashboardAdmin = application.capabilities.dashboards?.isDashboardAdmin; - - return ( - - - - -

Workspaces

-
-
- - - + const { application } = props.core; + + const isDashboardAdmin = application.capabilities.dashboards?.isDashboardAdmin; + + return ( + + + + +

Workspaces

+
+
+ + + + + + + { + setFilter(e.target.value); + }} + options={[ + { + value: 'viewed', + text: i18n.translate('workspace.list.card.filter.viewed', { + defaultMessage: 'Recently viewed', + }), + }, + { + value: 'updated', + text: i18n.translate('workspace.list.card.filter.updated', { + defaultMessage: 'Recently updated', + }), + }, + ]} + /> + + {isDashboardAdmin && ( + + + { + application.navigateToApp(WORKSPACE_CREATE_APP_ID); + }} + /> - - { - this.setState({ filter: e.target.value }); - }} - options={[ - { - value: 'viewed', - text: i18n.translate('workspace.list.card.filter.viewed', { - defaultMessage: 'Recently viewed', - }), - }, - { - value: 'updated', - text: i18n.translate('workspace.list.card.filter.updated', { - defaultMessage: 'Recently updated', - }), - }, - ]} - /> - - {isDashboardAdmin && ( - - - + + + + {workspaceList && workspaceList.length === 0 ? ( + No Workspaces found

} + body={i18n.translate('workspace.list.card.empty', { + values: { + filter, + }, + defaultMessage: 'Workspaces you have recently {filter} will appear here.', + })} + /> + ) : ( + ({ + title: ( + { - application.navigateToApp(WORKSPACE_CREATE_APP_ID); + handleSwitchWorkspace(workspace.id); }} - /> -
-
- )} -
- - - - {workspaceList && workspaceList.length === 0 ? ( - No Workspaces found

} - body={i18n.translate('workspace.list.card.empty', { - values: { - filter: this.state.filter, - }, - defaultMessage: 'Workspaces you have recently {filter} will appear here.', - })} - /> - ) : ( - ({ - title: ( - { - this.handleSwitchWorkspace(workspace.id); - }} - > - {workspace.name} - - ), - description: ( - - {moment(workspace.time).fromNow()} - - ), - }))} - /> - )} -
- - { - application.navigateToApp(WORKSPACE_LIST_APP_ID); - }} - > - View all - -
- ); - } -} + > + {workspace.name} + + ), + description: ( + + {moment(workspace.time).fromNow()} + + ), + }))} + /> + )} + + + { + application.navigateToApp(WORKSPACE_LIST_APP_ID); + }} + > + View all + +
+ ); +};