Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #37630 - Display basic list of hosts on the new job_invocations page #913

Merged
merged 1 commit into from
Nov 6, 2024

Conversation

kmalyjur
Copy link
Contributor

@kmalyjur kmalyjur commented Jul 4, 2024

image

Dependent on this PR.

The next PR will add sorting, filtering by status, and permission handling.
The changes in the JobStatusIcon also affect the recent jobs card on the host detail page.

@kmalyjur kmalyjur force-pushed the job-inv-table branch 2 times, most recently from 257ee21 to 244eb88 Compare July 10, 2024 11:22
@kmalyjur kmalyjur force-pushed the job-inv-table branch 3 times, most recently from fd6ba44 to 2ba8883 Compare August 28, 2024 08:36
@kmalyjur kmalyjur marked this pull request as ready for review August 28, 2024 10:46
@MariaAga
Copy link
Member

MariaAga commented Sep 2, 2024

Going over the PR, in the old page there is a status "Awaiting start" and I dont see it in the table/pr

add_scoped_search_description_for(JobInvocation)
param :id, :identifier, :required => true
def hosts
Rails.logger.info "Params: #{params.inspect}"
Copy link
Member

Choose a reason for hiding this comment

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

Can the logger be removed?

export const columns = {
name: {
title: __('Name'),
wrapper: ({ name }) => <a href={`/new/hosts/${name}`}>{name}</a>,
Copy link
Member

Choose a reason for hiding this comment

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

Can the link to host be setting aware, example: theforeman/foreman_openscap#571

groups: {
title: __('Host group'),
wrapper: ({ hostgroup_id, hostgroup_name }) => (
<a href={`/hostgroups/${hostgroup_id}/edit`}>{hostgroup_name}</a>
Copy link
Member

Choose a reason for hiding this comment

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

If hostgroup is empty it shouldnt be a link

Copy link
Member

Choose a reason for hiding this comment

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

Well it is shown as empty and without an error so the link comment might not be relevant
image

Comment on lines 73 to 82
<a href={`/operatingsystems/${operatingsystem_id}/edit`}>
{operatingsystem_name}
</a>
),
weight: 3,
},
smart_proxy: {
title: __('Smart proxy'),
wrapper: ({ smart_proxy_name, smart_proxy_id }) => (
<a href={`/smart_proxies/${smart_proxy_id}`}>{smart_proxy_name}</a>
Copy link
Member

Choose a reason for hiding this comment

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

Same here, if the values are empty they shouldnt be links (Not sure its possible for os, but still)


return (
<TableIndexPage
apiUrl=""
Copy link
Member

Choose a reason for hiding this comment

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

Why is it empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it is not used in the TableIndexPage, I use the replacementResponse instead, however, feel free to correct me.

itemCount={response?.subtotal}
results={response?.results}
url=""
refreshData={() => {}}
Copy link
Member

Choose a reason for hiding this comment

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

Also why is this empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it isn't used either (but is required), it's only used in the Table component, but I pass my own Table to the TableIndexPage.

Comment on lines 104 to 115
{k === 'status' ? (
<JobStatusIcon
status={columns[k].status({
job_status: result?.job_status,
status_label: response?.status_label,
})}
>
{columns[k].tableTitle({
job_status: result?.job_status,
status_label: response?.status_label,
})}
</JobStatusIcon>
Copy link
Member

Choose a reason for hiding this comment

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

Can this move to the wrapper in the consts?

@@ -120,6 +121,7 @@ const JobInvocationDetailPage = ({
/>
</Flex>
</Flex>
{items.id !== undefined && <JobInvocationHostTable id={id} />}
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if its in the scope of the PR, but previously we had this:

  <div class="alert alert-warning">
    <%=
        _("The dynamic query '%{query}' was not resolved yet. The list of hosts to which it would resolve now can be seen %{here}." %
            { :query => job_invocation.targeting.search_query,
              :here => link_to(_('here'), hosts_url(:search => job_invocation.targeting.search_query))})
     %>
  </div>

if the table was empty

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The empty table in the old UI looks like this:
image

I made it to look like this now:
image

I don't know when the message from the code you sent appears. 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Looks good! the error is only when job_invocation.resolved? (I missed that)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what you mean. This empty table happens when !isPending && results.length === 0 && !errorMessage.

Copy link
Member

@MariaAga MariaAga Sep 11, 2024

Choose a reason for hiding this comment

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

When a user starts a job in the future, and has a dynamic hosts list, there will be no hosts until the job starts.
So when that happens in the old page an alert will show up.
I assume job_invocation.resolved?, in the old page, is what checks if this is the case

Copy link
Contributor Author

@kmalyjur kmalyjur Sep 18, 2024

Choose a reason for hiding this comment

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

Thank you for explaining, @asteflova helped me with rewording it and I incorporated it like this:
image

Also, I made this PR, which is needed for that.

@kmalyjur
Copy link
Contributor Author

@MariaAga Thank you for your review! I incorporated everything except for If hostgroup is empty it shouldnt be a link, I think it's not necessary, but feel free to tell me otherwise.

I also made Fixes #37805 - Add possibility to display message when table is empty on which it's dependent.

@kmalyjur kmalyjur requested a review from MariaAga September 11, 2024 13:52
Comment on lines 102 to 101
getColumnsStatus({ hostJobStatus: job_status }).title,
status: ({ job_status }) =>
getColumnsStatus({ hostJobStatus: job_status }).status,
wrapper: ({ job_status }) => {
const { title, status } = getColumnsStatus({
Copy link
Member

@MariaAga MariaAga Sep 12, 2024

Choose a reason for hiding this comment

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

Can you move getColumnsStatus calls into one call just after const Columns = () => {?

Comment on lines 100 to 101
tableTitle: ({ job_status }) =>
getColumnsStatus({ hostJobStatus: job_status }).title,
status: ({ job_status }) =>
getColumnsStatus({ hostJobStatus: job_status }).status,
wrapper: ({ job_status }) => {
const { title, status } = getColumnsStatus({
Copy link
Member

Choose a reason for hiding this comment

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

Its still 3 calls instead of one, I think that it can call getColumnsStatus only once

if (targeting?.targeting_type === 'dynamic_query') {
return {
action: {
title: 'View hosts',
Copy link
Member

Choose a reason for hiding this comment

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

Should be translated

Comment on lines 121 to 122
emptyAction={action}
emptyMessage={message}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure an action with a button would be best here, since then the user cant open it in a new tab. instead of an action can there be a link in the message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can change it as you're proposing, but I'll have to use my own EmptyState in this file or make the emptyMessage accept an object instead of a string. Is it okay?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think it should use its own EmptyState

Comment on lines 42 to 44
.job-invocation-host-table-page-section {
padding-top: 0px;
}
Copy link
Member

Choose a reason for hiding this comment

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

There is no element with this classname.
Also can the table sides have no padding like in the hosts page?

Comment on lines 37 to 57
<span className="job-planned">
<BuildIcon {...props} /> {children}
</span>
);
case JOB_RUNNING_STATUS:
return (
<span className="job-running">
<RunningIcon {...props} /> {children}
</span>
);
case JOB_CANCELLED_STATUS:
return (
<span className="job-cancelled">
<ExclamationTriangleIcon {...props} /> {children}
</span>
);
case JOB_AWAITING_STATUS:
return <span className="job-awaiting_start">{children}</span>;
default:
return (
<span className="job-info">
<span className="job-unknown">
Copy link
Member

Choose a reason for hiding this comment

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

Only the icon should have the job* classname, so the text will always be black

Copy link
Member

Choose a reason for hiding this comment

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

Also, can you import webpack/react_app/components/RecentJobsCard/styles.scss in the page, just for clearity on where the colours come from

Copy link
Contributor Author

Choose a reason for hiding this comment

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

can you import webpack/react_app/components/RecentJobsCard/styles.scss in the page

What do you please mean by that? import './styles.scss'; in the JobStatusIcon.js isn't enough?

Copy link
Member

Choose a reason for hiding this comment

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

I missed that, nvm :)

@kmalyjur kmalyjur force-pushed the job-inv-table branch 2 times, most recently from 4108d90 to 76533c7 Compare September 30, 2024 10:40
@kmalyjur kmalyjur requested a review from MariaAga September 30, 2024 11:13
Comment on lines 95 to 100
<>
{__('The dynamic query is still being processed. You can ')}
<a href={`/new/hosts?search=${targeting?.search_query}`}>
{__('view the hosts')}
</a>
{__(' targeted by the query.')}
Copy link
Member

Choose a reason for hiding this comment

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

Please use formmatedMessage for this kind of translations, example:


import { FormattedMessage } from 'react-intl';
     <FormattedMessage
        id="report-manual"
        defaultMessage={__(
          'If you wish to configure Puppet to forward its reports to Foreman, please follow {settingUpPuppetReports} and {emailReporting}'
        )}
        values={{
          settingUpPuppetReports: (
            <a href={getManualURL('3.5.4PuppetReports')}>
              {__('setting up reporting')}
            </a>
          ),
          emailReporting: (
            <a href={getWikiURL('Mail_Notifications')}>
              {__('e-mail reporting')}
            </a>
          ),
        }}
      />
      ```

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.

except translation UI code looks good, and rails look ok but im no expert there

@kmalyjur kmalyjur force-pushed the job-inv-table branch 4 times, most recently from 916d0f6 to b207ca1 Compare October 10, 2024 13:23
@kmalyjur
Copy link
Contributor Author

kmalyjur commented Oct 10, 2024

@MariaAga Could you please look at it again? I also incorporated some changes after @adamruzicka's review. Adam, could you please review the backend code?

@adamruzicka
Copy link
Contributor

total (or subtotal) counts seem to be off once you start searching
image

@adamruzicka
Copy link
Contributor

Once you set a search, you can't really unset it. It won't allow you to submit the search if the searchbar is empty, although I can't really put my finger on where it comes from

@kmalyjur
Copy link
Contributor Author

@adamruzicka thank you, I think I somehow broke it in the process 😅 should be fixed now

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.

Search clearing, subtotal, and showing the dynamic query message all work now

@adamruzicka adamruzicka merged commit 336f339 into theforeman:master Nov 6, 2024
23 checks passed
@adamruzicka
Copy link
Contributor

Thank you @kmalyjur & @MariaAga !

Comment on lines +109 to +118
const bottomPagination = (
<Pagination
ouiaId="table-hosts-bottom-pagination"
key="table-bottom-pagination"
page={params.page}
perPage={params.perPage}
itemCount={response?.subtotal}
onChange={onPagination}
/>
);
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 the same code as the table pagination, since this pr is merged already can you remove it in a later pr?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants