-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Infrastructure UI] Hosts table sorting and pagination #143834
Conversation
Pinging @elastic/infra-monitoring-ui (Team:Infra Monitoring UI) |
@crespocarlos Based on our discussion on the previous PR I am opening this one against |
There was a problem hiding this 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} /> |
There was a problem hiding this comment.
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
<EuiInMemoryTable pagination={true} sorting={true} items={items} columns={HostsTableColumns} /> | |
<EuiInMemoryTable pagination sorting items={items} columns={HostsTableColumns} /> |
export interface HostNodeRow extends HostMetics { | ||
os?: string | null | undefined; | ||
servicesOnHost?: number | null | undefined; | ||
name: string; |
There was a problem hiding this comment.
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?
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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>, |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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'> = { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 ?? '-', |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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]]; |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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?
99358e8
to
c5c5a12
Compare
c5c5a12
to
d49f071
Compare
@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 |
💚 Build Succeeded
Metrics [docs]Async chunks
History
To update your PR or re-run it, just comment with: |
There was a problem hiding this 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
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
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