Skip to content

Conversation

@kfamilonidis
Copy link
Contributor

@kfamilonidis kfamilonidis commented Oct 16, 2025

Upgrade common/ActionButtons and replace Enzyme tests with React Testing Library. Fix styling and replace bgStyle with equivalent variant props.

Acceptance Criteria:

  • ActionButtons: actions should appear in dropdown list when more than 1.
    • /webhooks -> index table.
    • /foreman_tasks/tasks -> index table

followed by #10766

@github-actions github-actions bot added the UI label Oct 16, 2025
@kfamilonidis kfamilonidis force-pushed the pf5-buttons branch 2 times, most recently from 12b46df to 5d9ee95 Compare October 16, 2025 12:13
@MariaAga MariaAga requested a review from Copilot October 16, 2025 12:31
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR upgrades button components from PatternFly 3 to PatternFly 5 and replaces Enzyme-based tests with React Testing Library tests. The changes ensure consistent button styling and improve test quality across the application.

  • Migrated ActionButtons, DeleteButton, DiffModal, ForemanModalFooter, ExportButton, SubmitOrCancel, and other button components from PF3 to PF5
  • Replaced deprecated bsStyle props with variant props and updated button styling properties
  • Converted all component tests from Enzyme snapshot testing to React Testing Library with proper assertions

Reviewed Changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
ActionButtons.js Replaced SplitButton with Dropdown and MenuToggle components for PF5 compatibility
ExportButton.js Updated Button import and props, added ouiaId for testing
PersonalAccessToken.js Migrated button styling from className to variant/size props
DeleteButton.js Updated Button props and added ouiaId
Actions.js Updated form action buttons with PF5 props and ouiaIds
DiffModal.js Updated close button styling
ForemanModalFooter.js Updated close button with PF5 variant
SubmitBtn.js/CancelBtn.js Updated button variants and added ouiaIds
Test files Converted from Enzyme snapshots to RTL with proper assertions and interactions

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@kfamilonidis kfamilonidis force-pushed the pf5-buttons branch 5 times, most recently from c23a763 to 46df6d4 Compare October 20, 2025 11:52
Copy link
Contributor

@Lukshio Lukshio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks,
I only found some things to change.

Copy link
Member

@MariaAga MariaAga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a duplication of webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/ActionButtons.js
Since common/actionButtons is used in plugins, I think the best way would be to move TableIndexPage/ActionButtons import to import from common, and combine the two components

@kfamilonidis
Copy link
Contributor Author

This looks like a duplication of webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/ActionButtons.js Since common/actionButtons is used in plugins, I think the best way would be to move TableIndexPage/ActionButtons import to import from common, and combine the two components

It's not a duplicate, the WebhooksIndexPage uses ActionButtons as table/row, while JobsInvocationDetail page (that uses PF4/TableIndexPage/ActionButtons, through TableIndex) as toolbar. There are few more occurrences of TableIndexPage but haven't found other Button dependencies that relate to ActionButtons functionality. Also, the PF4/TableIndexPage/ActionButtons.js are using upgraded buttons already.

foreman_tasks/tasks also uses this change from import common/ActionButtons/ActionButtons in ForemanTasks/Components/common/ActionButtons/ActionButton.js

@kfamilonidis kfamilonidis requested a review from MariaAga October 22, 2025 16:15
@MariaAga
Copy link
Member

MariaAga commented Oct 23, 2025

@MariSvirik Is it ok that in PF5 we will have 2 types of action buttons in the table? (kebab and button) or should we choose one, and which?
(She is on PTO so we will probably get an answer next week)
Screenshot From 2025-10-23 09-15-06
Screenshot From 2025-10-23 09-08-55

@kfamilonidis
Copy link
Contributor Author

I think that this PR with reduced scope of only one item in the list is safe to progress.

@MariaAga
Copy link
Member

I talked to Maria S, who talked to other designers as well, and its ok to have the 2 different table buttons, so I will review this task as it is

@kfamilonidis kfamilonidis changed the title Fixes #38822: update pf3 buttons to pf5 Refs #38822: update pf3 buttons to pf5 Nov 12, 2025
{...firstButton.action}
bsSize="small"
<Dropdown
ouiaId="action-buttons-dropdown"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to check if theres an ID we can use, so every table row button wont have the same ouiaId

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct. Good catch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not been implemented

Copy link
Contributor Author

@kfamilonidis kfamilonidis Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, correct, I changed the top most button id. The DropDown though it could be relying on any random id, it doesn't rely on any action, I can put random or the first of the collection.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 26 to 77
<Button
ouiaId="action-button"
size="sm"
variant="primary"
isDisabled={buttons[0].action?.disabled}
{...buttons[0].action}
>
{buttons[0].title}
</Button>
);
const firstButton = buttons.shift();

const [firstButton, ...restButtons] = buttons;

return (
<SplitButton
title={firstButton.title}
{...firstButton.action}
bsSize="small"
<Dropdown
ouiaId="action-buttons-dropdown"
isOpen={isOpen}
onOpenChange={openState => setIsOpen(openState)}
toggle={toggleRef => (
<MenuToggle
ref={toggleRef}
onClick={onToggleClick}
isExpanded={isOpen}
splitButtonOptions={{
variant: 'action',
items: [
<MenuToggleAction
id={`split-button-action-${firstButton.action?.id}}-toggle-button`}
key="split-action"
aria-label={firstButton.title}
onClick={firstButton.action?.onClick}
>
{firstButton.title}
</MenuToggleAction>,
],
}}
aria-label="Menu toggle with action split button"
/>
)}
shouldFocusToggleOnSelect
>
{buttons.map(button => (
<MenuItem key={button.title} title={button.title} {...button.action}>
{button.title}
</MenuItem>
))}
</SplitButton>
<DropdownList className="action-buttons">
{restButtons.map(button => (
<DropdownItem
ouiaId={`${button.action?.id}-dropdown-item-id`}
key={`${button.action?.id}-dropdown-item-key`}
title={button.title}
onClick={button.action?.onClick}
isDisabled={button.action?.disabled}
>
{button.title}
</DropdownItem>
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buttons with href attributes (like the 'second' button in fixtures) may not render correctly. PatternFly 5's Button component requires the component="a" prop to render as an anchor tag. The single button case should be updated:

<Button
  ouiaId="action-button"
  size="sm"
  variant="primary"
  component={buttons[0].action?.href ? 'a' : undefined}
  isDisabled={buttons[0].action?.disabled}
  {...buttons[0].action}
>

For DropdownItem, PatternFly 5 uses the to prop for the href value and also may need component="a" depending on the version. Verify the correct API usage for links in dropdown items.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@kfamilonidis kfamilonidis Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this is a valid point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a generic component, it needs to be able to handle onClick but href as well.

<DropdownItem
            ouiaId={`${button.action?.id}-dropdown-item-id`}
            key={`${button.action?.id}-dropdown-item-key`}
            title={button.title}
            onClick={button.action?.onClick}
            isDisabled={button.action?.disabled}
            to={button.action?.to}
            component={button.action?.href ? 'a' : undefined}
           {...button.action}
          >

Copy link
Member

@MariaAga MariaAga Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the same for the MenuToggleAction probably

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no url for href

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't be the test changed to accept getByRole('link')?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but onClick is typically used for safe, controlled actions like API calls, while a standard a tag is a simple link. These can be different use cases where the 'a' tag is a simple link to somewhere, but onClick connected to only to safe actions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kfamilonidis How does that effect changing the test to accept getByRole('link') so we can have both urls and onclick?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are links that perform certain actions, in this use cases (one, many buttons) all buttons are triggering a modal. Considering that these actions are safe, it would be safe to say and is very easy to change all the buttons to a tag and tested by getByRole('link').

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the request is for the split button to support urls, is for future needs not the current ones, and we can have buttons that need to just be an a tag that open a new tab. Or do you suggest to implement opening in a new tab in a different way?
Example of usage with the other type of table action dropdown: https://github.com/theforeman/foreman_remote_execution/blob/master/webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js#L22

@kfamilonidis
Copy link
Contributor Author

kfamilonidis commented Nov 14, 2025

All comments have been implemented.

Copy link
Contributor Author

@kfamilonidis kfamilonidis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To @MariaAga credit, id was found missing.

@kfamilonidis kfamilonidis force-pushed the pf5-buttons branch 6 times, most recently from bcc58ac to f46578a Compare November 25, 2025 13:33
Upgrade ActionButtons and replace Enzyme tests with RTL.
Fix styling an replace bgStyle with equivalent variant props.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants