Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions workspaces/frontend/src/__tests__/cypress/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
coverage
results
cypress/downloads/
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { home } from '~/__tests__/cypress/cypress/pages/home';

describe('WorkspaceDetailsActivity Component', () => {
beforeEach(() => {
home.visit();
});

// This tests depends on the mocked workspaces data at home page, needs revisit once workspace data fetched from BE
it('open workspace details, open activity tab, check all fields match', () => {
cy.findAllByTestId('table-body').first().findByTestId('action-column').click();
cy.findByTestId('action-view-details').click();
cy.findByTestId('activityTab').click();
cy.findByTestId('lastActivity').should('have.text', '2/16/2025, 4:40:00 AM');
cy.findByTestId('lastUpdate').should('have.text', '2/16/2025, 4:41:40 AM');
cy.findByTestId('pauseTime').should('have.text', '2/16/2025, 4:38:20 AM');
cy.findByTestId('pendingRestart').should('have.text', 'No');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { Workspace } from '~/shared/types';
import { WorkspaceDetailsOverview } from '~/app/pages/Workspaces/Details/WorkspaceDetailsOverview';
import { WorkspaceDetailsActions } from '~/app/pages/Workspaces/Details/WorkspaceDetailsActions';
import { WorkspaceDetailsActivity } from '~/app/pages/Workspaces/Details/WorkspaceDetailsActivity';

type WorkspaceDetailsProps = {
workspace: Workspace;
Expand All @@ -39,7 +40,7 @@ export const WorkspaceDetails: React.FunctionComponent<WorkspaceDetailsProps> =
};

return (
<DrawerPanelContent>
<DrawerPanelContent data-testid="workspaceDetails">
<DrawerHead>
<Title headingLevel="h6">{workspace.name}</Title>
<WorkspaceDetailsActions onEditClick={onEditClick} onDeleteClick={onDeleteClick} />
Expand All @@ -56,9 +57,16 @@ export const WorkspaceDetails: React.FunctionComponent<WorkspaceDetailsProps> =
</TabContentBody>
</TabContent>
</Tab>
<Tab eventKey={1} title={<TabTitleText>Activity</TabTitleText>} aria-label="Activity">
<Tab
eventKey={1}
title={<TabTitleText>Activity</TabTitleText>}
aria-label="Activity"
data-testid="activityTab"
>
<TabContent id="activitySectionBodyPadding">
<TabContentBody hasPadding>Activity</TabContentBody>
<TabContentBody hasPadding>
<WorkspaceDetailsActivity workspace={workspace} />
</TabContentBody>
</TabContent>
</Tab>
<Tab eventKey={2} title={<TabTitleText>Logs</TabTitleText>} aria-label="Logs">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import {
DescriptionList,
DescriptionListTerm,
DescriptionListGroup,
DescriptionListDescription,
Divider,
} from '@patternfly/react-core';
import { Workspace } from '~/shared/types';
import { formatTimestamp } from '~/shared/utilities/WorkspaceUtils';

type WorkspaceDetailsActivityProps = {
workspace: Workspace;
};

export const WorkspaceDetailsActivity: React.FunctionComponent<WorkspaceDetailsActivityProps> = ({
workspace,
}) => {
const { activity, pauseTime, pendingRestart } = workspace.status;

return (
<DescriptionList isHorizontal>
<DescriptionListGroup>
<DescriptionListTerm>Last Activity</DescriptionListTerm>
<DescriptionListDescription data-testid="lastActivity">
{formatTimestamp(activity.lastActivity)}
</DescriptionListDescription>
</DescriptionListGroup>
<Divider />
<DescriptionListGroup>
<DescriptionListTerm>Last Update</DescriptionListTerm>
<DescriptionListDescription data-testid="lastUpdate">
{formatTimestamp(activity.lastUpdate)}
</DescriptionListDescription>
</DescriptionListGroup>
<Divider />
<DescriptionListGroup>
<DescriptionListTerm>Pause Time</DescriptionListTerm>
<DescriptionListDescription data-testid="pauseTime">
{formatTimestamp(pauseTime)}
</DescriptionListDescription>
</DescriptionListGroup>
<Divider />
<DescriptionListGroup>
<DescriptionListTerm>Pending Restart</DescriptionListTerm>
<DescriptionListDescription data-testid="pendingRestart">
{pendingRestart ? 'Yes' : 'No'}
</DescriptionListDescription>
</DescriptionListGroup>
<Divider />
</DescriptionList>
);
};
18 changes: 12 additions & 6 deletions workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { WorkspaceStartActionModal } from '~/app/pages/Workspaces/workspaceActio
import { WorkspaceRestartActionModal } from '~/app/pages/Workspaces/workspaceActions/WorkspaceRestartActionModal';
import { WorkspaceStopActionModal } from '~/app/pages/Workspaces/workspaceActions/WorkspaceStopActionModal';
import Filter, { FilteredColumn } from 'shared/components/Filter';
import { formatRam } from 'shared/utilities/WorkspaceResources';
import { formatRam } from 'shared/utilities/WorkspaceUtils';

export enum ActionType {
ViewDetails,
Expand Down Expand Up @@ -102,11 +102,11 @@ export const Workspaces: React.FunctionComponent = () => {
},
status: {
activity: {
lastActivity: 0,
lastUpdate: 0,
lastActivity: 1739673600,
lastUpdate: 1739673700,
},
pauseTime: 0,
pendingRestart: true,
pauseTime: 1739673500,
pendingRestart: false,
podTemplateOptions: {
imageConfig: {
desired: '',
Expand Down Expand Up @@ -384,14 +384,17 @@ export const Workspaces: React.FunctionComponent = () => {
const workspaceState = workspace.status.state;
const workspaceActions = [
{
id: 'view-details',
title: 'View Details',
onClick: () => viewDetailsClick(workspace),
},
{
id: 'edit',
title: 'Edit',
onClick: () => editAction(workspace),
},
{
id: 'delete',
title: 'Delete',
onClick: () => handleDeleteClick(workspace),
},
Expand All @@ -400,17 +403,20 @@ export const Workspaces: React.FunctionComponent = () => {
},
workspaceState !== WorkspaceState.Running
? {
id: 'start',
title: 'Start',
onClick: () => startRestartAction(workspace, ActionType.Start),
}
: {
id: 'restart',
title: 'Restart',
onClick: () => startRestartAction(workspace, ActionType.Restart),
},
] as IActions;

if (workspaceState === WorkspaceState.Running) {
workspaceActions.push({
id: 'stop',
title: 'Stop',
onClick: () => stopAction(workspace),
});
Expand Down Expand Up @@ -633,7 +639,7 @@ export const Workspaces: React.FunctionComponent = () => {
<ActionsColumn
items={workspaceDefaultActions(workspace).map((action) => ({
...action,
'data-testid': `action-${typeof action.title === 'string' ? action.title.toLowerCase() : ''}`,
'data-testid': `action-${action.id || ''}`,
}))}
/>
</Td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ export const formatRam = (valueInKb: number): string => {

return `${value.toFixed(2)} ${units[index]}`;
};

// Helper function to format UNIX timestamps
export const formatTimestamp = (timestamp: number): string =>
timestamp && timestamp > 0 ? new Date(timestamp * 1000).toLocaleString() : '-';
Loading