Fixes #38165 - Add checkboxes and related actions: open all, rerun, open all failed#944
Conversation
| collection @hosts | ||
|
|
||
| attribute :name, :operatingsystem_id, :operatingsystem_name, :hostgroup_id, :hostgroup_name, :id | ||
| attribute :id, :name, :operatingsystem_id, :operatingsystem_name, :hostgroup_id, :hostgroup_name |
There was a problem hiding this comment.
Nope, just wrong rebase, sorry
| `Task for the host ${ | ||
| action === 'cancel' ? 'cancelled' : 'aborted' | ||
| } successfully` |
There was a problem hiding this comment.
please ues 2 different strings so we wont have to do difficult translations
adamruzicka
left a comment
There was a problem hiding this comment.
Selecting the rows one by one and clicking rerun works.
Selecting all, then unchecking one and clicking rerun runs it only on the one that was unselected.
Selecting all and clicking rerun doesn't do anything, even though the button appears active.
| <OpenAlInvocations | ||
| setShowAlert={setShowAlert} | ||
| results={results} | ||
| id={id} | ||
| /> | ||
| } | ||
| />, | ||
| <CheckboxesActions | ||
| jobID={id} | ||
| bulkParams={bulkParams} | ||
| failedHosts={failedHosts} | ||
| selectedCount={selectedCount} | ||
| currentPermissions={currentPermissions} | ||
| permissionsStatus={permissionsStatus} | ||
| />, | ||
| ]} | ||
| controller="hosts" | ||
| creatable={false} | ||
| replacementResponse={combinedResponse} | ||
| selectionToolbar={selectionToolbar} | ||
| updateSearchQuery={updateSearchQueryBulk} |
| targeting: PropTypes.object.isRequired, | ||
| finished: PropTypes.bool.isRequired, | ||
| autoRefresh: PropTypes.bool.isRequired, | ||
| initialFilter: PropTypes.string.isRequired, |
There was a problem hiding this comment.
The prop `initialFilter` is marked as required in `JobInvocationHostTable`, but its value is `undefined`.|
|
||
| return ( | ||
| <> | ||
| <RerunButton /> |
There was a problem hiding this comment.
Of course, sorry, I haven't even looked at it after rebasing
| onClick={() => { | ||
| if (failedHosts.length <= 3) { | ||
| failedHosts.forEach(id => | ||
| openLink(`/job_invocations/${id}`, () => {}) |
There was a problem hiding this comment.
This should open /show_template_invocation_by_host/:host_id/job_invocation/:id
fe71baf to
121976e
Compare
121976e to
6c1ce3a
Compare
6c1ce3a to
ccdd86d
Compare
MariaAga
left a comment
There was a problem hiding this comment.
Thanks for the addition! I did an initial review but will need to do another one once its all addressed
| section:nth-child(1) { | ||
| padding: 0; | ||
| } | ||
| .open-all-button { |
| <ToolbarItem key="selectAll"> | ||
| <SelectAllCheckbox |
There was a problem hiding this comment.
This one might be on me in foreman core
| <Modal | ||
| ouiaId="template-invocation-new-tab-modal" | ||
| title={__('Open all invocations in new tabs')} | ||
| title={__('Open all selected invocations in new tabs')} |
| onClick={() => { | ||
| results.forEach(result => { | ||
| idsArray.forEach(result => { | ||
| openLink(templateInvocationPageUrl(result.id, id), '_blank'); |
There was a problem hiding this comment.
Should also be openLink(templateInvocationPageUrl(result, id), '_blank'); as the previous one
There was a problem hiding this comment.
Might be good to test that the window.open mock function has been called on click, with the right url
| const OpenAllButton = () => ( | ||
| <Button | ||
| variant="link" | ||
| isDisabled={idsArray.length === 0} |
There was a problem hiding this comment.
Clicking on the select all checkbox doesnt enable the button
There was a problem hiding this comment.
Only if the page has a search *
ccdd86d to
1bfeae8
Compare
|
Refactored a good bit - updated the PR description accordingly. |
9012e1f to
2cd2e8b
Compare
|
I added a fix for the bottom pagination and also made some changes to the filter functionality. |
MariaAga
left a comment
There was a problem hiding this comment.
I tried to open all failed and the array for hostsToOpen was empty but the modal said The number of failed invocations is: 97
Also if I select all the open in new tab button is disabled
| const [isOpenFailed, setIsOpenFailed] = useState(false); | ||
| const idsArray = getIdsArray(bulkParams, allHostsIds, isAllSelected); | ||
| const permissions = useSelector( | ||
| state => selectTemplateInvocation(state)?.permissions |
| margin-bottom: -10px; | ||
| } | ||
|
|
||
| .pf-v5-c-toolbar__group.pf-m-button-group { |
There was a problem hiding this comment.
This needs to be under the page classname
| }, | ||
| actions: { | ||
| title: '', | ||
| title: <span className="pf-u-screen-reader">{__('Actions')}</span>, |
| [DYNAMIC_TYPE]: __('Dynamic Query'), | ||
| }; | ||
|
|
||
| export const getIdsArray = (bulkParams, allHostsIds, isAllSelected) => { |
There was a problem hiding this comment.
Not sure, but can you just use inclusionSet, exclusionSet, I think useBulkSelect should send them as well
| export const GET_REPORT_TEMPLATE_INPUTS = 'GET_REPORT_TEMPLATE_INPUTS'; | ||
| export const JOB_INVOCATION_HOSTS = 'JOB_INVOCATION_HOSTS'; | ||
| export const GET_TEMPLATE_INVOCATION = 'GET_TEMPLATE_INVOCATION'; | ||
| export const MAX_HOSTS_API_SIZE = 'MAX_HOSTS_API_SIZE'; |
There was a problem hiding this comment.
This should probably be a number since hostsToOpen.slice(0, MAX_HOSTS_API_SIZE) doesnt work for a string
ekohl
left a comment
There was a problem hiding this comment.
I'm thinking out loud here. Background is that https://issues.redhat.com/browse/SAT-26318 was opened and after looking at the new job detail page the only feedback was a request to see all output. Not just the failed ones. This PR looks like the closest we have, so I'm commenting here.
If there's a better place then I'll happily hear about that.
- Should
openbe for opening in a new tab and useexpandto open on the same page? - Does it make sense to special case the failed jobs? If you add an action to open/expand all then the user can filter the statuses to only failed.
- Could it be a bulk action on the selected items?
- Is it clear enough this opens new tabs? The "open" wording may not be clear and it could open 100 of tabs.
| href={foremanUrl( | ||
| `/job_invocations/${jobID}/rerun?${idsArray | ||
| .map(id => `host_ids[]=${id}`) | ||
| .join('&')}` |
There was a problem hiding this comment.
Does it make sense to use URLSearchParams to construct the query string? I think generally speaking it's a good practice. Here it may not matter that much, but it should deal well with escaping. [] should be escaped.
| foremanUrl(`/api/job_invocations/${jobID}/hosts`), | ||
| { | ||
| params: { | ||
| per_page: MAX_HOSTS_API_SIZE, |
There was a problem hiding this comment.
There is no pagination. What if there are more than 100 failed hosts? Will the UI give the user the impression it will open more than 100? How do you expect the user to open the ones beyond 100? I'm not sure if all is supported here or even a good idea.
There was a problem hiding this comment.
Can we (or maybe we already do) add an "open selected" button, then users can choose what to open.
I dont think anyone want to open more than 100 tabs.
And anyway users can open in a new tab indevidually.
We warn them about the 100 in the modal "{__('This will open a new tab for each invocation. The maximum is 100.')}"
There was a problem hiding this comment.
It's why I liked the suggestion to expand items in bulk on the page. That's a bit easier to manage than tabs.
There was a problem hiding this comment.
We can add it in another pr, but the open all failed in tabs was requested specifically
There was a problem hiding this comment.
Do you know if there is an issue for it now? I'd like to include it somewhere in the larger effort but it doesn't have to be this PR.
There was a problem hiding this comment.
@ekohl @MariaAga thank you for your comments!
Regarding SAT-26318 - I closed this one and I've just created SAT-35515.
Should open be for opening in a new tab and use expand to open on the same page?
Yeah I think so and I refer to it like that
We can add it in another pr, but the open all failed in tabs was requested specifically
I agree
Do you know if there is an issue for it now? I'd like to include it somewhere in the larger effort but it doesn't have to be this PR.
You mean for the failed tabs or for expanding the table?
There was a problem hiding this comment.
Regarding SAT-26318 - I closed this one and I've just created SAT-35515.
Excellent, thanks.
SAT-26318
Expanding the table, which you just created an issue for.
|
|
||
| const handleOpenHosts = async (type = 'all') => { | ||
| if (type === 'failed') { | ||
| if (failedCount <= 3) { |
There was a problem hiding this comment.
if its less than 3 we just open it in new tabs, if its more than we ask the user if they are sure they want to open X amount of tabs just so no one gets 10 new tabs by accidentally clicking the button
There was a problem hiding this comment.
My programming professor in university always insistent on constants with a descriptive name. Could we do that?
There was a problem hiding this comment.
I usually remember him in my reviews 🙃, not enough
2cd2e8b to
d2b187b
Compare
d2b187b to
986687a
Compare
|
The latest push incorporates all of your suggestions. Could you please look at it again? |
986687a to
ae8b5d9
Compare
| import { OutlinedWindowRestoreIcon } from '@patternfly/react-icons'; | ||
| import EllipsisVIcon from '@patternfly/react-icons/dist/js/icons/ellipsis-v-icon'; |
|
|
||
| const fetchFailedHosts = async () => { | ||
| const { data } = await axios.get( | ||
| foremanUrl(`/api/job_invocations/${jobID}/hosts`), |
There was a problem hiding this comment.
Sorry this is coming late in the review, took me sometime to find that this is called on tabs open and not on modal open (and I didnt see extra requests until I opened the tabs).
I think instead of axios.get on button click, it should use the Useapi, and then the request wont be repeated and the failed host list will be available to all with redux
bedde35 to
aebbac4
Compare
| `Are you sure you want to open all ${modalText} invocations in new tabs?` | ||
| )} | ||
| <br /> | ||
| {__('This will open a new tab for each invocation. The maximum is 100.')} | ||
| <br /> | ||
| {__(`The number of ${modalText} invocations is:`)}{' '} |
There was a problem hiding this comment.
should be in sptrinf https://projects.theforeman.org/projects/foreman/wiki/Translating
| onClick={() => handleOpenHosts('failed')} | ||
| isDisabled={failedCount === 0} | ||
| > | ||
| {__(`Open all failed runs (${failedCount})`)} |
| ouiaId="template-invocation-new-tab-button" | ||
| variant="link" | ||
| > | ||
| <Tooltip content="Open selected in new tab"> |
aebbac4 to
5e3883e
Compare
5e3883e to
a0ad547
Compare





Canceling and aborting + tests for the table functionality will be added in a new PR.