Skip to content

Commit f8e543d

Browse files
MariaAgaLukshio
authored andcommitted
Fixes #39060 - Update Spinner + Button in TasksTablePage to pf5
1 parent 7160f57 commit f8e543d

File tree

5 files changed

+213
-167
lines changed

5 files changed

+213
-167
lines changed

webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
11
import React from 'react';
2-
import { DropdownButton, MenuItem } from 'patternfly-react';
32
import PropTypes from 'prop-types';
3+
import { SimpleDropdown } from '@patternfly/react-templates';
4+
import { EllipsisVIcon } from '@patternfly/react-icons';
45
import { translate as __ } from 'foremanReact/common/I18n';
56

67
export const ActionSelectButton = ({
78
onCancel,
89
onResume,
910
onForceCancel,
1011
disabled,
11-
}) => (
12-
<DropdownButton
13-
title={__('Select Action')}
14-
disabled={disabled}
15-
id="selcted-action-type"
16-
>
17-
<MenuItem
18-
title={__('Cancel selected tasks')}
19-
onClick={onCancel}
20-
eventKey="1"
21-
>
22-
{__('Cancel Selected')}
23-
</MenuItem>
24-
<MenuItem
25-
title={__('Resume selected tasks')}
26-
onClick={onResume}
27-
eventKey="2"
28-
>
29-
{__('Resume Selected')}
30-
</MenuItem>
31-
<MenuItem
32-
title={__('Force Cancel selected tasks')}
33-
onClick={onForceCancel}
34-
eventKey="3"
35-
>
36-
{__('Force Cancel Selected')}
37-
</MenuItem>
38-
</DropdownButton>
39-
);
12+
}) => {
13+
const buttons = [
14+
{
15+
content: __('Cancel Selected'),
16+
onClick: onCancel,
17+
value: 1,
18+
},
19+
{
20+
content: __('Resume Selected'),
21+
onClick: onResume,
22+
value: 2,
23+
},
24+
{
25+
content: __('Force Cancel Selected'),
26+
onClick: onForceCancel,
27+
value: 3,
28+
},
29+
];
30+
return (
31+
<SimpleDropdown
32+
isDisabled={disabled}
33+
ouiaId="tasks-table-action-select-dropdown"
34+
toggleVariant="plain"
35+
popperProps={{ position: 'right' }}
36+
initialItems={buttons}
37+
toggleContent={<EllipsisVIcon aria-hidden="true" />}
38+
/>
39+
);
40+
};
4041

4142
ActionSelectButton.propTypes = {
4243
disabled: PropTypes.bool,
Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,81 @@
1-
import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2-
1+
import React from 'react';
2+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
34
import { ActionSelectButton } from '../ActionSelectButton';
45

5-
const fixtures = {
6-
'renders with minimal props': {
7-
onCancel: jest.fn(),
8-
onResume: jest.fn(),
9-
onForceCancel: jest.fn(),
10-
},
11-
};
6+
const mockOnCancel = jest.fn();
7+
const mockOnResume = jest.fn();
8+
const mockOnForceCancel = jest.fn();
9+
10+
describe('ActionSelectButton', () => {
11+
const renderComponent = (props = {}) => {
12+
const defaultProps = {
13+
onCancel: mockOnCancel,
14+
onResume: mockOnResume,
15+
onForceCancel: mockOnForceCancel,
16+
disabled: false,
17+
};
18+
return render(<ActionSelectButton {...defaultProps} {...props} />);
19+
};
20+
21+
beforeEach(() => {
22+
jest.clearAllMocks();
23+
});
24+
25+
it('renders with minimal props', () => {
26+
renderComponent();
27+
28+
const toggle = screen.getByRole('button');
29+
expect(toggle).toBeInTheDocument();
30+
expect(toggle).not.toBeDisabled();
31+
});
32+
33+
it('renders disabled when disabled prop is true', () => {
34+
renderComponent({ disabled: true });
35+
36+
const toggle = screen.getByRole('button');
37+
expect(toggle).toBeDisabled();
38+
});
39+
40+
it('opens dropdown and shows action options when toggle is clicked', async () => {
41+
renderComponent();
42+
const toggle = screen.getByRole('button');
43+
fireEvent.click(toggle);
44+
45+
await waitFor(() => {
46+
expect(screen.getByText('Cancel Selected')).toBeInTheDocument();
47+
expect(screen.getByText('Resume Selected')).toBeInTheDocument();
48+
expect(screen.getByText('Force Cancel Selected')).toBeInTheDocument();
49+
});
50+
});
51+
52+
it('calls onCancel when Cancel Selected is clicked', async () => {
53+
renderComponent();
54+
fireEvent.click(screen.getByRole('button'));
55+
await waitFor(() => {
56+
expect(screen.getByText('Cancel Selected')).toBeInTheDocument();
57+
});
58+
fireEvent.click(screen.getByText('Cancel Selected'));
59+
expect(mockOnCancel).toHaveBeenCalledTimes(1);
60+
});
61+
62+
it('calls onResume when Resume Selected is clicked', async () => {
63+
renderComponent();
64+
fireEvent.click(screen.getByRole('button'));
65+
await waitFor(() => {
66+
expect(screen.getByText('Resume Selected')).toBeInTheDocument();
67+
});
68+
fireEvent.click(screen.getByText('Resume Selected'));
69+
expect(mockOnResume).toHaveBeenCalledTimes(1);
70+
});
1271

13-
describe('ActionSelectButton', () =>
14-
testComponentSnapshotsWithFixtures(ActionSelectButton, fixtures));
72+
it('calls onForceCancel when Force Cancel Selected is clicked', async () => {
73+
renderComponent();
74+
fireEvent.click(screen.getByRole('button'));
75+
await waitFor(() => {
76+
expect(screen.getByText('Force Cancel Selected')).toBeInTheDocument();
77+
});
78+
fireEvent.click(screen.getByText('Force Cancel Selected'));
79+
expect(mockOnForceCancel).toHaveBeenCalledTimes(1);
80+
});
81+
});

webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap

Lines changed: 0 additions & 43 deletions
This file was deleted.

webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import React, { useState } from 'react';
22
import PropTypes from 'prop-types';
33
import URI from 'urijs';
44
import { getURIsearch } from 'foremanReact/common/urlHelpers';
5-
import { Spinner, Button, Icon } from 'patternfly-react';
5+
import { Button, ToolbarItem, Spinner } from '@patternfly/react-core';
6+
import { RedoIcon } from '@patternfly/react-icons';
67
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
78
import { translate as __ } from 'foremanReact/common/I18n';
89
import { getURIQuery } from 'foremanReact/common/helpers';
9-
import ExportButton from 'foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton';
1010
import { STATUS } from 'foremanReact/constants';
1111
import TasksDashboard from '../TasksDashboard';
1212
import TasksTable from './TasksTable';
@@ -127,25 +127,44 @@ const TasksTablePage = ({
127127
header={createHeader(props.actionName)}
128128
breadcrumbOptions={getBreadcrumbs(props.actionName)}
129129
toolbarButtons={
130-
<React.Fragment>
131-
<Button onClick={() => props.reloadPage(url, props.parentTaskID)}>
132-
<Icon type="fa" name="refresh" /> {__('Refresh Data')}
133-
</Button>
134-
{props.status === STATUS.PENDING && <Spinner size="md" loading />}
135-
<ExportButton
136-
url={getCSVurl(history.location.pathname, uriQuery)}
137-
title={__('Export All')}
138-
/>
139-
<ActionSelectButton
140-
disabled={
141-
!props.permissions.edit ||
142-
!(props.selectedRows.length || props.allRowsSelected)
143-
}
144-
onCancel={() => openModal(CANCEL_SELECTED_MODAL)}
145-
onResume={() => openModal(RESUME_SELECTED_MODAL)}
146-
onForceCancel={() => openModal(FORCE_UNLOCK_SELECTED_MODAL)}
147-
/>
148-
</React.Fragment>
130+
<>
131+
<ToolbarItem>
132+
<Button
133+
ouiaId="tasks-table-refresh-data"
134+
variant="primary"
135+
onClick={() => props.reloadPage(url, props.parentTaskID)}
136+
icon={<RedoIcon />}
137+
>
138+
{__('Refresh Data')}
139+
</Button>
140+
</ToolbarItem>
141+
{props.status === STATUS.PENDING && (
142+
<ToolbarItem>
143+
<Spinner size="lg" />
144+
</ToolbarItem>
145+
)}
146+
<ToolbarItem>
147+
<Button
148+
ouiaId="tasks-table-export-all"
149+
variant="secondary"
150+
component="a"
151+
href={getCSVurl(history.location.pathname, uriQuery)}
152+
>
153+
{__('Export All')}
154+
</Button>
155+
</ToolbarItem>
156+
<ToolbarItem>
157+
<ActionSelectButton
158+
disabled={
159+
!props.permissions.edit ||
160+
!(props.selectedRows.length || props.allRowsSelected)
161+
}
162+
onCancel={() => openModal(CANCEL_SELECTED_MODAL)}
163+
onResume={() => openModal(RESUME_SELECTED_MODAL)}
164+
onForceCancel={() => openModal(FORCE_UNLOCK_SELECTED_MODAL)}
165+
/>
166+
</ToolbarItem>
167+
</>
149168
}
150169
searchQuery={getURIsearch()}
151170
beforeToolbarComponent={

0 commit comments

Comments
 (0)