Fixes #38306 - dont load all outputs in job details#968
Conversation
5b99512 to
28fccd0
Compare
adamruzicka
left a comment
There was a problem hiding this comment.
As far as the functionality goes, I have no concerns, although it could use some polishing.
| end | ||
|
|
||
| def list_template_invocations_task_by_hosts | ||
| hosts = Host.search_for(params[:host_query]) |
There was a problem hiding this comment.
This would find all the hosts which match the search, not just the hosts which are in the job. That could get out of hand very quickly
| :task_id => template_invocation_task.id, | ||
| :task_cancellable => template_invocation_task.cancellable?, | ||
| :permissions => { | ||
| :view_foreman_tasks => User.current.allowed_to?(:view_foreman_tasks), |
There was a problem hiding this comment.
We could be more specific and instead of asking "Can the user view tasks in general?" we could ask "Can the user view this host's task?".
| :view_foreman_tasks => User.current.allowed_to?(:view_foreman_tasks), | |
| :view_foreman_tasks => User.current.can?(:view_foreman_tasks, template_invocation_task, |
Alternatively, in the old ui we use this
authorized_for(:permission => :view_foreman_tasks, :auth_object => task)
| :task_cancellable => template_invocation_task.cancellable?, | ||
| :permissions => { | ||
| :view_foreman_tasks => User.current.allowed_to?(:view_foreman_tasks), | ||
| :cancel_job_invocations => User.current.allowed_to?(:cancel_job_invocations), |
There was a problem hiding this comment.
Same thing as above, in the old ui we use
authorized_for(:permission => :cancel_job_invocations, :auth_object => job_invocation)
| match 'experimental/job_invocations_detail/:id', to: 'react#index', :via => [:get], as: 'new_job_invocation_detail' | ||
| match 'job_invocations_detail/:id/host_invocation/:host_id', to: 'react#index', :via => [:get], as: 'new_job_invocation_detail_by_host' | ||
| get 'show_template_invocation_by_host/:host_id/job_invocation/:id', to: 'template_invocations#show_template_invocation_by_host' | ||
| get 'list_template_invocations_task_by_hosts', to: 'template_invocations#list_template_invocations_task_by_hosts' |
There was a problem hiding this comment.
disclaimer: I know there's a precedent for this kind of naming and I've approved the previous instance in the past, but back then we were under time pressure while now we have time.
Our api tries (and usually succeeds) in being REST-ful. Among other things, there are certain expectations about how routes should be formed. The rails routing guide[1] is a nice introduction.
In this case, template invocations cannot exist on their own so the path to get them shouldn't be top-level. They always have to belong to a job invocation, so endpoints for retrieving information about template invocations should be nested under a path which determines a job invocation, so something like /job_invocations/<JID>/template_invocations?search=.... If I'm reading it correctly then in here you're passing the job invocation id as a parameter, which also works, but still the pat-based approach would be preferable.
Additionally, I'm afraid users don't really care about template invocations, they care about "hosts in a job" and maybe it wouldn't hurt to indulge them in that regard. Maybe something like /job_invocations/<JID>/hosts?search=... would be a better fit? The answer would include all the task-level details and permissions and so on, without exposing our internals too much. Also, by mentioning "hosts" in the path, you set expectations about the search.
There was a problem hiding this comment.
Even though I agree with everything written here, is that necessary in this case? I guess you also agreed on a similar case before just because it's not an API endpoint? I mean, users still might use that, but it won't be explicitly "marketed" via API docs or something like a direct page, where you could copy/save the link from the browser.
On the other hand, if we want to explicitly expose this action to the users, I'd vote for a proper API endpoint, if not, this seems okay?..
There was a problem hiding this comment.
is that necessary in this case?
Was that meant to react to my whole comment or just parts of it? None of it is strictly necessary and the last paragraph probably falls into the nice-to-have bucket, but we should at least be consistent, even if just for our own sake.
I guess you also agreed on a similar case before just because it's not an API endpoint?
That's true, but I'd also say we can do better if we have time?
if we want to explicitly expose this action to the users, I'd vote for a proper API endpoint
I wasn't proposing to make this a "proper, user-facing and stable" api endpoint. But it is still an api endpoint of sorts, even if it is just frontend-facing and sort of private.
this seems okay?
Well, it works so there's that, but being a bit more consistent would be nice.
There was a problem hiding this comment.
Nevermind me, somehow with all these workarounds for UI I forgot to follow Rails' how-tos
There was a problem hiding this comment.
Thats for the explanations, is the issue just with the url or also with the method name list_template_invocations_task_by_hosts ?
There was a problem hiding this comment.
re-remembering this pr:
/job_invocations/<JID>/hosts? already exists, and gives info about the host and some of its details, this endpoint only gives a list of hosts ids and their task ids
The answer would include all the task-level details and permissions and so on, without exposing our internals too much.
Could you explain what you mean here?
There was a problem hiding this comment.
is the issue just with the url or also with the method name list_template_invocations_task_by_hosts ?
I would say both. Usually the route and the corresponding method are named in a similar way so if we change one, we should also change the other.
/job_invocations/<JID>/hosts? already exists
Where? I'm aware of /api(/:apiv)/job_invocations/:id/hosts, but that's slightly different.
Could you explain what you mean here?
Something along the lines of this. Just don't explicitly call out template invocations in there
{
"result": {
"hosts": [
{ "hostname": "foo.example.com",
"id": 7,
"permissions": { "view_task": true, "cancel_job": true, "execute_job": true },
"task": { "cancellable": true, id: "12345-..." }
},
...
]
}
}28fccd0 to
26f6706
Compare
|
@kmalyjur Can you review the ui part of this? |
kmalyjur
left a comment
There was a problem hiding this comment.
The UI part is great, thank you.
@adamruzicka, I think it can be merged?
26f6706 to
b8e69da
Compare
|
Hi @adamruzicka @MariaAga, just checking in on this PR - any updates? |
adamruzicka
left a comment
There was a problem hiding this comment.
If I expand multiple rows, only the last one that I expand keeps refreshing, the others just stop refreshing. I have a feeling that #978 might help with that. If that is the case, then I'd rather have the other pr merged first.
There was a problem hiding this comment.
Pull Request Overview
This PR refactors job details output loading by switching from the useAPI hook to redux selectors for handling template invocations and introduces a new API endpoint to list template invocations by host. Key changes include:
- Replacing direct API hook usage with redux selectors for template invocation data and status.
- Adding new selectors, constants, routes, and controller actions for listing template invocations.
- Updating tests and UI components to accommodate the new data flow.
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| webpack/JobInvocationDetail/tests/TemplateInvocation.test.js | Replaced APIHooks mocking with redux selectors for controlling invocation status and data in tests. |
| webpack/JobInvocationDetail/TemplateInvocationPage.js | Updated the selector usage to accept hostID as a parameter. |
| webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js | Changed from the single invocation selector to a list selector and updated task structure extraction; minor spelling issues in toast messages. |
| webpack/JobInvocationDetail/TemplateInvocation.js | Removed useAPI in favor of redux selectors; added isExpanded prop and refactored task extraction, but potential issues with the intervalId variable and default value for finished. |
| webpack/JobInvocationDetail/JobInvocationSelectors.js | Updated the template invocation selector to be hostID parameterized and added a new selector for the list of template invocations. |
| webpack/JobInvocationDetail/JobInvocationHostTable.js | Introduced a new API call for hosts and passed isExpanded down to the TemplateInvocation component. |
| webpack/JobInvocationDetail/JobInvocationConstants.js | Added a new constant for listing template invocations. |
| lib/foreman_remote_execution/engine.rb | Updated permissions to support new endpoints for job invocations and template invocations. |
| config/routes.rb | Added a new route for listing job hosts. |
| app/controllers/template_invocations_controller.rb | Updated JSON render response to include the merged task attributes. |
| app/controllers/job_invocations_controller.rb | Introduced a new action to return hosts with associated template invocations. |
Comments suppressed due to low confidence (3)
webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js:87
- There is a typo in the success toast message: 'succesfully' should be spelled 'successfully'.
successToast: () => __('Task for the host cancelled succesfully'),
webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js:105
- There is a typo in the abort toast message: 'succesfully' should be spelled 'successfully'.
successToast: () => __('task aborted succesfully'),
webpack/JobInvocationDetail/TemplateInvocation.js:87
- The variable 'intervalId' is used but not declared in the component scope; this may lead to unexpected errors. Consider declaring intervalId using a ref (e.g., useRef) to properly manage its lifecycle.
if (intervalId) clearInterval(intervalId);
|
Needs a rebase |
b8e69da to
833a8ab
Compare
|
rebased, added a logic ( |
ofedoren
left a comment
There was a problem hiding this comment.
Thanks, @MariaAga, just two ignorable nits, but otherwise LGTM and seems to work as expected.
@adamruzicka, any concerns?
| const dispatch = useDispatch(); | ||
|
|
||
| useEffect(() => { | ||
| const getData = async () => { |
There was a problem hiding this comment.
Is it okay to define a function in useEffect hook?..
|
Needs yet another rebase |
|
On my end it doesn't seem to be refreshing. When I expand the row, the data gets loaded once, but that's it. To get a fresh view I have to collapse the row and expand it again |
833a8ab to
c7ce1c3
Compare
|
rebased, @adamruzicka I think this is what youre describing? https://issues.redhat.com/browse/SAT-35992 |
That doesn't sound like it. Furthermore, the issue I was having went away when I applied this suggestion |
c7ce1c3 to
696be1a
Compare
|
updated |
|
Thank you @MariaAga ! |
Created list_template_invocations_task_by_hosts so we can still see the kebab actions for all hosts without needed to expend anything