Skip to content

Commit

Permalink
update to funtional component
Browse files Browse the repository at this point in the history
Signed-off-by: Hailong Cui <[email protected]>
  • Loading branch information
Hailong-am committed Jul 21, 2024
1 parent 8477709 commit 59fb602
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 153 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.',
});
Expand All @@ -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<WorkspaceObject[]>([]);
const [filter, setFilter] = useState('viewed');

export class WorkspaceListCard extends Component<WorkspaceListCardProps, WorkspaceListCardState> {
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) => ({

Check warning on line 62 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L62

Added line #L62 was not covered by tests
id: item.id,
name: this.state.availiableWorkspaces.find((ws) => ws.id === item.id)?.name!,
name: availableWorkspaces.find((ws) => ws.id === item.id)?.name!,

Check warning on line 64 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L64

Added line #L64 was not covered by tests
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,
Expand All @@ -96,122 +74,119 @@ export class WorkspaceListCard extends Component<WorkspaceListCardProps, Workspa
}));
}
return [];

Check warning on line 76 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L76

Added line #L76 was not covered by tests
}
}, [filter, availableWorkspaces]);

private handleSwitchWorkspace = (id: string) => {
const { application, http } = this.props.core;
const handleSwitchWorkspace = (id: string) => {
const { application, http } = props.core;

Check warning on line 80 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L80

Added line #L80 was not covered by tests
if (application && http) {
navigateToWorkspaceDetail({ application, http }, id);

Check warning on line 82 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L82

Added line #L82 was not covered by tests
}
};

render() {
const workspaceList = this.loadWorkspaceListItems();
const { application } = this.props.core;

const isDashboardAdmin = application.capabilities.dashboards?.isDashboardAdmin;

return (
<EuiPanel paddingSize="s" hasBorder={false} hasShadow={false}>
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem grow={3}>
<EuiTitle>
<h4>Workspaces</h4>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={1}>
<EuiToolTip position="bottom" content={WORKSPACE_LIST_CARD_DESCRIPTIOIN}>
<EuiIcon type="iInCircle" aria-label="workspace list card descriptioni" />
const { application } = props.core;

const isDashboardAdmin = application.capabilities.dashboards?.isDashboardAdmin;

return (
<EuiPanel paddingSize="s" hasBorder={false} hasShadow={false}>
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem grow={3}>
<EuiTitle>
<h4>Workspaces</h4>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={1}>
<EuiToolTip position="bottom" content={WORKSPACE_LIST_CARD_DESCRIPTION}>
<EuiIcon type="iInCircle" aria-label="workspace list card description" />
</EuiToolTip>
</EuiFlexItem>
<EuiFlexItem grow={5}>
<EuiSelect
value={filter}
data-test-subj="workspace_filter"
onChange={(e) => {
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',
}),
},
]}
/>
</EuiFlexItem>
{isDashboardAdmin && (
<EuiFlexItem grow={false}>
<EuiToolTip position="top" content="Create workspace">
<EuiButtonIcon
data-test-subj="create_workspace"
aria-label="create workspace"
display="base"
iconType="plus"
size="m"
onClick={() => {
application.navigateToApp(WORKSPACE_CREATE_APP_ID);

Check warning on line 136 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L136

Added line #L136 was not covered by tests
}}
/>
</EuiToolTip>
</EuiFlexItem>
<EuiFlexItem grow={5}>
<EuiSelect
value={this.state.filter}
data-test-subj="workspace_filter"
onChange={(e) => {
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',
}),
},
]}
/>
</EuiFlexItem>
{isDashboardAdmin && (
<EuiFlexItem grow={false}>
<EuiToolTip position="top" content="Create workspace">
<EuiButtonIcon
data-test-subj="create_workspace"
aria-label="create workspace"
display="base"
iconType="plus"
size="m"
)}
</EuiFlexGroup>

<EuiSpacer />
<EuiListGroup flush={true} bordered={false} style={{ minHeight: '300px' }}>
{workspaceList && workspaceList.length === 0 ? (
<EuiEmptyPrompt
iconType="database"
titleSize="xs"
title={<p>No Workspaces found</p>}
body={i18n.translate('workspace.list.card.empty', {
values: {
filter,
},
defaultMessage: 'Workspaces you have recently {filter} will appear here.',
})}
/>
) : (
<EuiDescriptionList
type="column"
titleProps={{ style: { width: '70%' } }}
descriptionProps={{ style: { width: '30%' } }}
listItems={workspaceList.map((workspace) => ({
title: (
<EuiLink
onClick={() => {
application.navigateToApp(WORKSPACE_CREATE_APP_ID);
handleSwitchWorkspace(workspace.id);

Check warning on line 167 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L167

Added line #L167 was not covered by tests
}}
/>
</EuiToolTip>
</EuiFlexItem>
)}
</EuiFlexGroup>

<EuiSpacer />
<EuiListGroup flush={true} bordered={false} style={{ minHeight: '300px' }}>
{workspaceList && workspaceList.length === 0 ? (
<EuiEmptyPrompt
iconType="database"
titleSize="xs"
title={<p>No Workspaces found</p>}
body={i18n.translate('workspace.list.card.empty', {
values: {
filter: this.state.filter,
},
defaultMessage: 'Workspaces you have recently {filter} will appear here.',
})}
/>
) : (
<EuiDescriptionList
type="column"
titleProps={{ style: { width: '70%' } }}
descriptionProps={{ style: { width: '30%' } }}
listItems={workspaceList.map((workspace) => ({
title: (
<EuiLink
onClick={() => {
this.handleSwitchWorkspace(workspace.id);
}}
>
<EuiText size="s">{workspace.name}</EuiText>
</EuiLink>
),
description: (
<EuiText size="s" color="subdued" className="eui-textRight">
{moment(workspace.time).fromNow()}
</EuiText>
),
}))}
/>
)}
</EuiListGroup>

<EuiLink
onClick={() => {
application.navigateToApp(WORKSPACE_LIST_APP_ID);
}}
>
<EuiText size="s">View all</EuiText>
</EuiLink>
</EuiPanel>
);
}
}
>
<EuiText size="s">{workspace.name}</EuiText>
</EuiLink>
),
description: (
<EuiText size="s" color="subdued" className="eui-textRight">
{moment(workspace.time).fromNow()}
</EuiText>
),
}))}
/>
)}
</EuiListGroup>

<EuiLink
onClick={() => {
application.navigateToApp(WORKSPACE_LIST_APP_ID);

Check warning on line 185 in src/plugins/workspace/public/components/service_card/workspace_list_card.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/workspace/public/components/service_card/workspace_list_card.tsx#L185

Added line #L185 was not covered by tests
}}
>
<EuiText size="s">View all</EuiText>
</EuiLink>
</EuiPanel>
);
};

0 comments on commit 59fb602

Please sign in to comment.