-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Fleet] Integration Policies List view #83634
Changes from 21 commits
81bfb6e
4609b59
1182f4e
c79b575
a26d96f
5a0c3c0
d153745
f488243
c5194a0
2befd92
296d4d8
b3a728a
e8e152f
a779846
6db69c3
86f6eac
0791a19
2c80f9b
d2e75c0
ff7cce0
825f9c6
2d044c7
5696283
8668097
7af206c
43d965b
e9e1d8b
67e63ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiText } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n/react'; | ||
import React, { CSSProperties, memo } from 'react'; | ||
import { EuiLinkProps } from '@elastic/eui/src/components/link/link'; | ||
|
||
const MIN_WIDTH: CSSProperties = { minWidth: 0 }; | ||
const NO_WRAP_WHITE_SPACE: CSSProperties = { whiteSpace: 'nowrap' }; | ||
|
||
export type LinkAndRevisionProps = EuiLinkProps & { | ||
revision?: string | number; | ||
}; | ||
|
||
/** | ||
* Components shows a link for a given value along with a revision number to its right. The display | ||
* value is truncated if it is longer than the width of where it is displayed, while the revision | ||
* always remain visible | ||
*/ | ||
export const LinkAndRevision = memo<LinkAndRevisionProps>( | ||
({ revision, className, ...euiLinkProps }) => { | ||
return ( | ||
<EuiFlexGroup gutterSize="s" alignItems="baseline" style={MIN_WIDTH} responsive={false}> | ||
<EuiFlexItem grow={false} className="eui-textTruncate"> | ||
<EuiLink className={`eui-textTruncate ${className ?? ''}`} {...euiLinkProps} /> | ||
</EuiFlexItem> | ||
{revision && ( | ||
<EuiFlexItem grow={true}> | ||
<EuiText color="subdued" size="xs" style={NO_WRAP_WHITE_SPACE}> | ||
<FormattedMessage | ||
id="xpack.fleet.policyNameLink.revisionNumber" | ||
defaultMessage="rev. {revNumber}" | ||
values={{ revNumber: revision }} | ||
/> | ||
</EuiText> | ||
</EuiFlexItem> | ||
)} | ||
</EuiFlexGroup> | ||
); | ||
} | ||
); |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,94 @@ | ||||||
/* | ||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||||||
* or more contributor license agreements. Licensed under the Elastic License; | ||||||
* you may not use this file except in compliance with the Elastic License. | ||||||
*/ | ||||||
|
||||||
import { useCallback, useEffect, useMemo } from 'react'; | ||||||
import { useHistory, useLocation } from 'react-router-dom'; | ||||||
import { useUrlParams } from './use_url_params'; | ||||||
import { PAGE_SIZE_OPTIONS, Pagination, usePagination } from './use_pagination'; | ||||||
|
||||||
type SetUrlPagination = (pagination: Pagination) => void; | ||||||
interface UrlPagination { | ||||||
pagination: Pagination; | ||||||
setPagination: SetUrlPagination; | ||||||
pageSizeOptions: number[]; | ||||||
} | ||||||
|
||||||
type UrlPaginationParams = Partial<Pagination>; | ||||||
|
||||||
/** | ||||||
* Uses URL params for pagination and also persists those to the URL as they are updated | ||||||
*/ | ||||||
export const useUrlPagination = (): UrlPagination => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about changing the existing |
||||||
const location = useLocation(); | ||||||
const history = useHistory(); | ||||||
const { urlParams, toUrlParams } = useUrlParams(); | ||||||
const urlPaginationParams = useMemo(() => { | ||||||
return paginationFromUrlParams(urlParams); | ||||||
}, [urlParams]); | ||||||
const { pagination, pageSizeOptions, setPagination } = usePagination(urlPaginationParams); | ||||||
|
||||||
const setUrlPagination = useCallback<SetUrlPagination>( | ||||||
({ pageSize, currentPage }) => { | ||||||
history.push({ | ||||||
...location, | ||||||
search: toUrlParams({ | ||||||
...urlParams, | ||||||
currentPage, | ||||||
pageSize, | ||||||
}), | ||||||
}); | ||||||
}, | ||||||
[history, location, toUrlParams, urlParams] | ||||||
); | ||||||
|
||||||
useEffect(() => { | ||||||
setPagination((prevState) => { | ||||||
return { | ||||||
...prevState, | ||||||
...paginationFromUrlParams(urlParams), | ||||||
}; | ||||||
}); | ||||||
}, [setPagination, urlParams]); | ||||||
|
||||||
return { | ||||||
pagination, | ||||||
setPagination: setUrlPagination, | ||||||
pageSizeOptions, | ||||||
}; | ||||||
}; | ||||||
|
||||||
const paginationFromUrlParams = (urlParams: UrlPaginationParams): Pagination => { | ||||||
const pagination: Pagination = { | ||||||
pageSize: 20, | ||||||
currentPage: 1, | ||||||
}; | ||||||
|
||||||
// Search params can appear multiple times in the URL, in which case the value for them, | ||||||
// once parsed, would be an array. In these case, we take the last value defined | ||||||
pagination.currentPage = Number( | ||||||
(Array.isArray(urlParams.currentPage) | ||||||
? urlParams.currentPage[urlParams.currentPage.length - 1] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe .pop() will give the same result. If so, I'd prefer it as it's less statements to read.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow - why did I not think of that 🤦 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @paul-tavares no worries, It Depends ™️, right :) .pop() does alter the array. I didn't see it used again so seems it works for now, but there are trade-offs. I really wish we could After writing this I went looking and found that we can't do |
||||||
: urlParams.currentPage) ?? pagination.currentPage | ||||||
); | ||||||
pagination.pageSize = | ||||||
Number( | ||||||
(Array.isArray(urlParams.pageSize) | ||||||
? urlParams.pageSize[urlParams.pageSize.length - 1] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same question/comment re: |
||||||
: urlParams.pageSize) ?? pagination.pageSize | ||||||
) ?? pagination.pageSize; | ||||||
|
||||||
// If Current Page is not a valid positive integer, set it to 1 | ||||||
if (!Number.isFinite(pagination.currentPage) || pagination.currentPage < 1) { | ||||||
pagination.currentPage = 1; | ||||||
} | ||||||
|
||||||
// if pageSize is not one of the expected page sizes, reset it to 20 (default) | ||||||
if (!PAGE_SIZE_OPTIONS.includes(pagination.pageSize)) { | ||||||
pagination.pageSize = 20; | ||||||
} | ||||||
|
||||||
return pagination; | ||||||
}; |
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.
FYI - I would like to add to this component a
isOutdated: boolean
prop and then refactor the Agents List view to also use this component. I have a feeling that the outdated indicator will also be wanted in other scenarios.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 would also be good for our Endpoint list
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 @kevinlog , we would likely have a similar component in our code base.