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

[Infrastructure UI] Hosts table sorting and pagination #143834

Conversation

jennypavlova
Copy link
Member

@jennypavlova jennypavlova commented Oct 24, 2022

Closes #143510

Summary

This PR adds pagination and column sorting to the hosts' table. I use default pagination settings (10 per page with the options to show 25 and 50). In order to avoid a change in the snapshot API for now I implemented it the same way as the inventory table view. If we see that the loading is slow and we need to optimize it we can change the snapshot API as well
image

Testing:
I opened the inventory page in table view and compared the way pagination and sorting work there with the hosts' table using different sorting types ( ascending/descending order for each column )

Something I found out with the sorting while testing: (using EuiInMemoryTable ) When we have a text value (like the host.name) and we sort it (alphabetically for example) we will show first all the hosts starting with a capital letter (sorted alphabetically) and then the other hosts (sorted alphabetically) so the order will be for example Hosta, Hostb, ahost, bhost. It works the same way on the inventory page so I guess the sorting is implemented to be case-sensitive on purpose.

Old PR: neptunian#3

@jennypavlova jennypavlova added the release_note:skip Skip the PR/issue when compiling release notes label Oct 24, 2022
@jennypavlova jennypavlova marked this pull request as ready for review October 24, 2022 09:27
@jennypavlova jennypavlova requested a review from a team as a code owner October 24, 2022 09:27
@elasticmachine
Copy link
Contributor

Pinging @elastic/infra-monitoring-ui (Team:Infra Monitoring UI)

@jennypavlova
Copy link
Member Author

@crespocarlos Based on our discussion on the previous PR I am opening this one against main ( I got a warning that the comments may be lost if I change the old one so I will keep it to track the comments there until we merge this one)

@jennypavlova jennypavlova self-assigned this Oct 24, 2022
Copy link
Contributor

@crespocarlos crespocarlos left a comment

Choose a reason for hiding this comment

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

Cool! Paging and sorting works. Perhaps we could try to look into the type changes and see if we can try to simplify it.

items={items}
columns={HostsTableColumns}
/>
<EuiInMemoryTable pagination={true} sorting={true} items={items} columns={HostsTableColumns} />
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: a shorthand for the boolean props, when we pass true, could be

Suggested change
<EuiInMemoryTable pagination={true} sorting={true} items={items} columns={HostsTableColumns} />
<EuiInMemoryTable pagination sorting items={items} columns={HostsTableColumns} />

Comment on lines 15 to 18
export interface HostNodeRow extends HostMetics {
os?: string | null | undefined;
servicesOnHost?: number | null | undefined;
name: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this could be simplified, since we're already declaring the attributes as ?, which means they can be undefined, we could remove undefined from the union type. wdyt?

Suggested change
export interface HostNodeRow extends HostMetics {
os?: string | null | undefined;
servicesOnHost?: number | null | undefined;
name: string;
export interface HostNodeRow extends HostMetics {
os?: string | null;
servicesOnHost?: number | null;
name?: string | null;

os?: string | null | undefined;
servicesOnHost?: number | null | undefined;
name: string;
}

export interface HostMetics {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could achieve the same results, without changing the types here. I played with it and EuiInMemoryTable complains that item type is not compatible because name is now declared as a mandatory field. If we make it optional, it should work without these changes here and on HostsTableColumns - correct me if I'm wrong or missing something.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added it as mandatory because we should always have a hostname and it won't be a case to have a hostname equal to null, right 🤔 ? Yes in general we can have it as optional similar to os to set - if we have a host without a name but do we have this case?

@@ -41,59 +42,63 @@ export const HostsTableColumns: Array<EuiBasicTableColumn<HostNodeRow>> = [
defaultMessage: 'Operating System',
}),
field: 'os',
sortable: true,
render: (os: string) => <EuiText size="s">{os ?? '-'}</EuiText>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we don't need this os ?? '-' anymore because we're handling null values in use_host_tables?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, true, forgot it after the change. Removed 👍

return nodes.map(({ metrics, path }) => ({
...last(path),
const items: HostNodeRow[] = useMemo(() => {
const valuesMapping: Record<keyof HostMetics, 'value' | 'avg' | 'max'> = {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a smart solution :). If we don't need to make the changes on hosts_table_column we may not need this anymore - which would be even simpler

Copy link
Member Author

Choose a reason for hiding this comment

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

I changed the columns because for the sorting we need the fields to have the value as a number or string - the value we want to use for sorting the table - so for example memory: {avg: 1, value: 2, max: 3} should be memory: 1 because we show the avg in the table and for sorting the column the average value (1) will be used ( similar to all the columns ). That's why I changed the structure there.

};
return nodes.map(({ metrics, path, name }) => ({
name,
os: last(path)?.os ?? '-',
Copy link
Contributor

Choose a reason for hiding this comment

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

If you prefer, you can get rid of lodash by doing the following:

const lastPath = { ...path.at(-1), os: path.at(-1)?.os ?? '-' };

new TS cool feature

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice idea, thank you!

...metrics.reduce((data, metric) => {
data[metric.name as keyof HostMetics] = metric;
const metricName = metric.name as keyof HostMetics;
data[metricName] = metric[valuesMapping[metricName]];
Copy link
Contributor

@crespocarlos crespocarlos Oct 25, 2022

Choose a reason for hiding this comment

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

Should we handle null values here too? In case these any of these metrics are null, should we set the default value to 0?

Copy link
Member Author

Choose a reason for hiding this comment

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

The NumberCell component will handle the null case and will display N/A in that case - I think it's more accurate when the metric is not present instead of showing 0 - what do you think?

@jennypavlova jennypavlova force-pushed the 143510-trying-hosts-table-sorting-and-pagination branch from 99358e8 to c5c5a12 Compare October 25, 2022 17:39
@jennypavlova jennypavlova force-pushed the 143510-trying-hosts-table-sorting-and-pagination branch from c5c5a12 to d49f071 Compare October 25, 2022 17:41
@jennypavlova
Copy link
Member Author

@crespocarlos As discussed I changed the mapping so we can have the same metric values format as we have now and changed the field names inside HostsTableColumns. Also changed label to name and removed not used values from the path object.

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
infra 1009.5KB 1009.6KB +158.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @jennypavlova

Copy link
Contributor

@crespocarlos crespocarlos left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for taking the time to discuss the possibilities to improve the code

@jennypavlova jennypavlova merged commit 2de4f15 into elastic:main Oct 26, 2022
@kibanamachine kibanamachine added v8.6.0 backport:skip This commit does not require backporting labels Oct 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Epic: Host Observability release_note:skip Skip the PR/issue when compiling release notes Team:Infra Monitoring UI - DEPRECATED DEPRECATED - Label for the Infra Monitoring UI team. Use Team:obs-ux-infra_services v8.6.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Infrastructure UI] Add table pagination and columns sorting
6 participants