mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.10`: - [[Cloud Security] Fix page size bug (#164428)](https://github.com/elastic/kibana/pull/164428) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Jordan","email":"51442161+JordanSh@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-08-28T15:33:03Z","message":"[Cloud Security] Fix page size bug (#164428)","sha":"191bedaa5dea78ccd928f2177b17919793f01da5","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Cloud Security","v8.10.0","v8.11.0"],"number":164428,"url":"https://github.com/elastic/kibana/pull/164428","mergeCommit":{"message":"[Cloud Security] Fix page size bug (#164428)","sha":"191bedaa5dea78ccd928f2177b17919793f01da5"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164428","number":164428,"mergeCommit":{"message":"[Cloud Security] Fix page size bug (#164428)","sha":"191bedaa5dea78ccd928f2177b17919793f01da5"}}]}] BACKPORT--> Co-authored-by: Jordan <51442161+JordanSh@users.noreply.github.com>
This commit is contained in:
parent
eb217d5997
commit
65b543b62a
4 changed files with 229 additions and 99 deletions
|
@ -4,12 +4,39 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { useCallback } from 'react';
|
||||
import { Dispatch, SetStateAction, useCallback } from 'react';
|
||||
import { type DataView } from '@kbn/data-views-plugin/common';
|
||||
import { BoolQuery } from '@kbn/es-query';
|
||||
import { CriteriaWithPagination } from '@elastic/eui';
|
||||
import { useUrlQuery } from '../use_url_query';
|
||||
import { usePageSize } from '../use_page_size';
|
||||
import { getDefaultQuery, useBaseEsQuery, usePersistedQuery } from './utils';
|
||||
|
||||
interface QuerySort {
|
||||
direction: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface CloudPostureTableResult {
|
||||
setUrlQuery: (query: any) => void;
|
||||
// TODO: remove any, this sorting is used for both EuiGrid and EuiTable which uses different types of sorts
|
||||
sort: any;
|
||||
filters: any[];
|
||||
query?: { bool: BoolQuery };
|
||||
queryError?: Error;
|
||||
pageIndex: number;
|
||||
// TODO: remove any, urlQuery is an object with query fields but we also add custom fields to it, need to assert usages
|
||||
urlQuery: any;
|
||||
setTableOptions: (options: CriteriaWithPagination<object>) => void;
|
||||
handleUpdateQuery: (query: any) => void;
|
||||
pageSize: number;
|
||||
setPageSize: Dispatch<SetStateAction<number | undefined>>;
|
||||
onChangeItemsPerPage: (newPageSize: number) => void;
|
||||
onChangePage: (newPageIndex: number) => void;
|
||||
onSort: (sort: QuerySort[]) => void;
|
||||
onResetFilters: () => void;
|
||||
}
|
||||
|
||||
/*
|
||||
Hook for managing common table state and methods for Cloud Posture
|
||||
*/
|
||||
|
@ -21,7 +48,7 @@ export const useCloudPostureTable = ({
|
|||
defaultQuery?: (params: any) => any;
|
||||
dataView: DataView;
|
||||
paginationLocalStorageKey: string;
|
||||
}) => {
|
||||
}): CloudPostureTableResult => {
|
||||
const getPersistedDefaultQuery = usePersistedQuery(defaultQuery);
|
||||
const { urlQuery, setUrlQuery } = useUrlQuery(getPersistedDefaultQuery);
|
||||
const { pageSize, setPageSize } = usePageSize(paginationLocalStorageKey);
|
||||
|
@ -31,9 +58,10 @@ export const useCloudPostureTable = ({
|
|||
setPageSize(newPageSize);
|
||||
setUrlQuery({
|
||||
pageIndex: 0,
|
||||
pageSize: newPageSize,
|
||||
});
|
||||
},
|
||||
[setUrlQuery, setPageSize]
|
||||
[setPageSize, setUrlQuery]
|
||||
);
|
||||
|
||||
const onResetFilters = useCallback(() => {
|
||||
|
|
|
@ -20,7 +20,10 @@ import React, { useCallback, useMemo, useState, useEffect } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { Routes, Route } from '@kbn/shared-ux-router';
|
||||
import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY } from '../../common/constants';
|
||||
import { useCloudPostureTable } from '../../common/hooks/use_cloud_posture_table';
|
||||
import {
|
||||
CloudPostureTableResult,
|
||||
useCloudPostureTable,
|
||||
} from '../../common/hooks/use_cloud_posture_table';
|
||||
import { useLatestVulnerabilities } from './hooks/use_latest_vulnerabilities';
|
||||
import type { VulnerabilitiesQueryData } from './types';
|
||||
import { LATEST_VULNERABILITIES_INDEX_PATTERN } from '../../../common/constants';
|
||||
|
@ -63,67 +66,35 @@ const getDefaultQuery = ({ query, filters }: any): any => ({
|
|||
pageIndex: 0,
|
||||
});
|
||||
|
||||
export const Vulnerabilities = () => {
|
||||
const { data, isLoading, error } = useFilteredDataView(LATEST_VULNERABILITIES_INDEX_PATTERN);
|
||||
const getSetupStatus = useCspSetupStatusApi();
|
||||
|
||||
if (getSetupStatus?.data?.vuln_mgmt?.status !== 'indexed') return <NoVulnerabilitiesStates />;
|
||||
|
||||
if (error) {
|
||||
return <ErrorCallout error={error as Error} />;
|
||||
}
|
||||
if (isLoading) {
|
||||
return defaultLoadingRenderer();
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return defaultNoDataRenderer();
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
path={findingsNavigation.resource_vulnerabilities.path}
|
||||
render={() => <ResourceVulnerabilities dataView={data} />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={findingsNavigation.vulnerabilities_by_resource.path}
|
||||
render={() => <VulnerabilitiesByResource dataView={data} />}
|
||||
/>
|
||||
<Route
|
||||
path={findingsNavigation.vulnerabilities.path}
|
||||
render={() => <VulnerabilitiesContent dataView={data} />}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
const VulnerabilitiesDataGrid = ({
|
||||
dataView,
|
||||
data,
|
||||
isFetching,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
onResetFilters,
|
||||
pageSize,
|
||||
setUrlQuery,
|
||||
pageIndex,
|
||||
sort,
|
||||
}: {
|
||||
dataView: DataView;
|
||||
data: VulnerabilitiesQueryData | undefined;
|
||||
isFetching: boolean;
|
||||
}) => {
|
||||
const {
|
||||
pageIndex,
|
||||
sort,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
});
|
||||
} & Pick<
|
||||
CloudPostureTableResult,
|
||||
| 'pageIndex'
|
||||
| 'sort'
|
||||
| 'pageSize'
|
||||
| 'onChangeItemsPerPage'
|
||||
| 'onChangePage'
|
||||
| 'onSort'
|
||||
| 'urlQuery'
|
||||
| 'setUrlQuery'
|
||||
| 'onResetFilters'
|
||||
>) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const styles = useStyles();
|
||||
const [showHighlight, setHighlight] = useState(false);
|
||||
|
@ -131,7 +102,9 @@ const VulnerabilitiesDataGrid = ({
|
|||
const invalidIndex = -1;
|
||||
|
||||
const selectedVulnerability = useMemo(() => {
|
||||
return data?.page[urlQuery.vulnerabilityIndex];
|
||||
if (urlQuery.vulnerabilityIndex !== undefined) {
|
||||
return data?.page[urlQuery.vulnerabilityIndex];
|
||||
}
|
||||
}, [data?.page, urlQuery.vulnerabilityIndex]);
|
||||
|
||||
const onCloseFlyout = () => {
|
||||
|
@ -194,7 +167,9 @@ const VulnerabilitiesDataGrid = ({
|
|||
|
||||
const flyoutVulnerabilityIndex = urlQuery?.vulnerabilityIndex;
|
||||
|
||||
const selectedVulnerabilityIndex = flyoutVulnerabilityIndex + pageIndex * pageSize;
|
||||
const selectedVulnerabilityIndex = flyoutVulnerabilityIndex
|
||||
? flyoutVulnerabilityIndex + pageIndex * pageSize
|
||||
: undefined;
|
||||
|
||||
const renderCellValue = useMemo(() => {
|
||||
const Cell: React.FC<EuiDataGridCellValueElementProps> = ({
|
||||
|
@ -306,7 +281,9 @@ const VulnerabilitiesDataGrid = ({
|
|||
[pageSize, setUrlQuery]
|
||||
);
|
||||
|
||||
const showVulnerabilityFlyout = flyoutVulnerabilityIndex > invalidIndex;
|
||||
const showVulnerabilityFlyout = flyoutVulnerabilityIndex
|
||||
? flyoutVulnerabilityIndex > invalidIndex
|
||||
: undefined;
|
||||
|
||||
if (data?.page.length === 0) {
|
||||
return <EmptyState onResetFilters={onResetFilters} />;
|
||||
|
@ -392,8 +369,21 @@ const VulnerabilitiesDataGrid = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const VulnerabilitiesContent = ({ dataView }: { dataView: DataView }) => {
|
||||
const { pageIndex, query, sort, queryError, pageSize, setUrlQuery } = useCloudPostureTable({
|
||||
const {
|
||||
sort,
|
||||
query,
|
||||
queryError,
|
||||
pageSize,
|
||||
pageIndex,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
|
@ -445,8 +435,58 @@ const VulnerabilitiesContent = ({ dataView }: { dataView: DataView }) => {
|
|||
<EuiSpacer size="m" />
|
||||
{error && <ErrorCallout error={error as Error} />}
|
||||
{!error && (
|
||||
<VulnerabilitiesDataGrid dataView={dataView} data={data} isFetching={isFetching} />
|
||||
<VulnerabilitiesDataGrid
|
||||
dataView={dataView}
|
||||
data={data}
|
||||
isFetching={isFetching}
|
||||
pageIndex={pageIndex}
|
||||
sort={sort}
|
||||
pageSize={pageSize}
|
||||
onChangeItemsPerPage={onChangeItemsPerPage}
|
||||
onChangePage={onChangePage}
|
||||
onSort={onSort}
|
||||
urlQuery={urlQuery}
|
||||
onResetFilters={onResetFilters}
|
||||
setUrlQuery={setUrlQuery}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Vulnerabilities = () => {
|
||||
const { data, isLoading, error } = useFilteredDataView(LATEST_VULNERABILITIES_INDEX_PATTERN);
|
||||
const getSetupStatus = useCspSetupStatusApi();
|
||||
|
||||
if (getSetupStatus?.data?.vuln_mgmt?.status !== 'indexed') return <NoVulnerabilitiesStates />;
|
||||
|
||||
if (error) {
|
||||
return <ErrorCallout error={error as Error} />;
|
||||
}
|
||||
if (isLoading) {
|
||||
return defaultLoadingRenderer();
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return defaultNoDataRenderer();
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
path={findingsNavigation.resource_vulnerabilities.path}
|
||||
render={() => <ResourceVulnerabilities dataView={data} />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={findingsNavigation.vulnerabilities_by_resource.path}
|
||||
render={() => <VulnerabilitiesByResource dataView={data} />}
|
||||
/>
|
||||
<Route
|
||||
path={findingsNavigation.vulnerabilities.path}
|
||||
render={() => <VulnerabilitiesContent dataView={data} />}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -21,7 +21,10 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { Link, useParams, generatePath } from 'react-router-dom';
|
||||
import type { BoolQuery } from '@kbn/es-query';
|
||||
import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY } from '../../../../common/constants';
|
||||
import { useCloudPostureTable } from '../../../../common/hooks/use_cloud_posture_table';
|
||||
import {
|
||||
CloudPostureTableResult,
|
||||
useCloudPostureTable,
|
||||
} from '../../../../common/hooks/use_cloud_posture_table';
|
||||
import { useLatestVulnerabilities } from '../../hooks/use_latest_vulnerabilities';
|
||||
import type { VulnerabilitiesQueryData } from '../../types';
|
||||
import { ErrorCallout } from '../../../configurations/layout/error_callout';
|
||||
|
@ -68,26 +71,31 @@ const ResourceVulnerabilitiesDataGrid = ({
|
|||
dataView,
|
||||
data,
|
||||
isFetching,
|
||||
pageIndex,
|
||||
sort,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
}: {
|
||||
dataView: DataView;
|
||||
data: VulnerabilitiesQueryData;
|
||||
isFetching: boolean;
|
||||
}) => {
|
||||
const {
|
||||
pageIndex,
|
||||
sort,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
});
|
||||
} & Pick<
|
||||
CloudPostureTableResult,
|
||||
| 'pageIndex'
|
||||
| 'sort'
|
||||
| 'pageSize'
|
||||
| 'onChangeItemsPerPage'
|
||||
| 'onChangePage'
|
||||
| 'onSort'
|
||||
| 'urlQuery'
|
||||
| 'setUrlQuery'
|
||||
| 'onResetFilters'
|
||||
>) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const styles = useStyles();
|
||||
|
||||
|
@ -357,7 +365,19 @@ export const ResourceVulnerabilities = ({ dataView }: { dataView: DataView }) =>
|
|||
const params = useParams<{ resourceId: string }>();
|
||||
const resourceId = decodeURIComponent(params.resourceId);
|
||||
|
||||
const { pageIndex, query, sort, queryError, pageSize, setUrlQuery } = useCloudPostureTable({
|
||||
const {
|
||||
pageIndex,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
query,
|
||||
sort,
|
||||
onSort,
|
||||
queryError,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
|
@ -459,7 +479,20 @@ export const ResourceVulnerabilities = ({ dataView }: { dataView: DataView }) =>
|
|||
<EuiSpacer size="m" />
|
||||
{error && <ErrorCallout error={error as Error} />}
|
||||
{!error && (
|
||||
<ResourceVulnerabilitiesDataGrid dataView={dataView} data={data} isFetching={isFetching} />
|
||||
<ResourceVulnerabilitiesDataGrid
|
||||
dataView={dataView}
|
||||
data={data}
|
||||
isFetching={isFetching}
|
||||
pageIndex={pageIndex}
|
||||
pageSize={pageSize}
|
||||
urlQuery={urlQuery}
|
||||
setUrlQuery={setUrlQuery}
|
||||
onChangeItemsPerPage={onChangeItemsPerPage}
|
||||
onChangePage={onChangePage}
|
||||
onResetFilters={onResetFilters}
|
||||
onSort={onSort}
|
||||
sort={sort}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,10 @@ import { i18n } from '@kbn/i18n';
|
|||
import { Link, generatePath } from 'react-router-dom';
|
||||
import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY } from '../../../common/constants';
|
||||
import { findingsNavigation } from '../../../common/navigation/constants';
|
||||
import { useCloudPostureTable } from '../../../common/hooks/use_cloud_posture_table';
|
||||
import {
|
||||
CloudPostureTableResult,
|
||||
useCloudPostureTable,
|
||||
} from '../../../common/hooks/use_cloud_posture_table';
|
||||
import { ErrorCallout } from '../../configurations/layout/error_callout';
|
||||
import { FindingsSearchBar } from '../../configurations/layout/findings_search_bar';
|
||||
import { useLimitProperties } from '../../../common/utils/get_limit_properties';
|
||||
|
@ -54,26 +57,31 @@ const VulnerabilitiesByResourceDataGrid = ({
|
|||
dataView,
|
||||
data,
|
||||
isFetching,
|
||||
pageIndex,
|
||||
sort,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
}: {
|
||||
dataView: DataView;
|
||||
data: VulnerabilitiesByResourceQueryData | undefined;
|
||||
isFetching: boolean;
|
||||
}) => {
|
||||
const {
|
||||
pageIndex,
|
||||
sort,
|
||||
pageSize,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
onSort,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
});
|
||||
} & Pick<
|
||||
CloudPostureTableResult,
|
||||
| 'pageIndex'
|
||||
| 'sort'
|
||||
| 'pageSize'
|
||||
| 'onChangeItemsPerPage'
|
||||
| 'onChangePage'
|
||||
| 'onSort'
|
||||
| 'urlQuery'
|
||||
| 'setUrlQuery'
|
||||
| 'onResetFilters'
|
||||
>) => {
|
||||
const styles = useStyles();
|
||||
|
||||
const { isLastLimitedPage, limitedTotalItemCount } = useLimitProperties({
|
||||
|
@ -232,7 +240,19 @@ const VulnerabilitiesByResourceDataGrid = ({
|
|||
};
|
||||
|
||||
export const VulnerabilitiesByResource = ({ dataView }: { dataView: DataView }) => {
|
||||
const { pageIndex, query, sort, queryError, pageSize, setUrlQuery } = useCloudPostureTable({
|
||||
const {
|
||||
pageIndex,
|
||||
onChangeItemsPerPage,
|
||||
onChangePage,
|
||||
pageSize,
|
||||
query,
|
||||
sort,
|
||||
onSort,
|
||||
queryError,
|
||||
urlQuery,
|
||||
setUrlQuery,
|
||||
onResetFilters,
|
||||
} = useCloudPostureTable({
|
||||
dataView,
|
||||
defaultQuery: getDefaultQuery,
|
||||
paginationLocalStorageKey: LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY,
|
||||
|
@ -273,6 +293,15 @@ export const VulnerabilitiesByResource = ({ dataView }: { dataView: DataView })
|
|||
dataView={dataView}
|
||||
data={data}
|
||||
isFetching={isFetching}
|
||||
pageIndex={pageIndex}
|
||||
sort={sort}
|
||||
pageSize={pageSize}
|
||||
onChangeItemsPerPage={onChangeItemsPerPage}
|
||||
onChangePage={onChangePage}
|
||||
onSort={onSort}
|
||||
urlQuery={urlQuery}
|
||||
setUrlQuery={setUrlQuery}
|
||||
onResetFilters={onResetFilters}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue