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

[EuiInMemoryTable] Persist table rows per page and sort #198297

Merged
merged 49 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8d99ca8
Persist rows per page in TableListView
sebelga Oct 29, 2024
78ac564
Add jest test
sebelga Oct 30, 2024
12a62e0
Add persistence to AlertFieldsTable
sebelga Oct 30, 2024
981895f
Add persistence to ESQLEditor > QueryHistory
sebelga Oct 30, 2024
597f23b
Add persistence to ESQLEditor > QueryHistory (2)
sebelga Oct 30, 2024
19dc9a9
Add persistence to SearchSessionsMgmtTable
sebelga Oct 30, 2024
c17cc42
Add persistence to Data view mgmt RelationshipsTable
sebelga Oct 30, 2024
c10e4ee
Infer sorting type based on initialSort value
sebelga Oct 30, 2024
40e109b
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Oct 31, 2024
8bbbe4d
Fix TS issue
sebelga Oct 31, 2024
72cd587
Create HOC for class components
sebelga Oct 31, 2024
c0abb67
Allow common persist props to be provided
sebelga Oct 31, 2024
e8c5553
Add persistence to Inspector view > DataTableFormat
sebelga Oct 31, 2024
a56474e
Fix linting issue
sebelga Nov 2, 2024
c8e4584
Export function component instead of PureComponent
sebelga Nov 4, 2024
4fa6d33
Refactor props naming
sebelga Nov 4, 2024
c00b8a6
Add persistence to Scripted fields Table
sebelga Nov 4, 2024
099f884
Fix alert fields table pagination
sebelga Nov 4, 2024
2d54992
Change tableId
sebelga Nov 4, 2024
40c0230
Add persistence to Indexed fields Table
sebelga Nov 4, 2024
b80693f
Add persistence to data views source filters Table
sebelga Nov 4, 2024
499fa39
Add persistence to data views index patterns Table
sebelga Nov 4, 2024
7dfa3f0
Add props getter to for the persist options
sebelga Nov 4, 2024
1ce41a2
Add persistence to SavedObjectFinder
sebelga Nov 4, 2024
0d990f0
Fix TS issue
sebelga Nov 5, 2024
f458f59
Add ids to SavedObjectFinder instances
sebelga Nov 5, 2024
ab69b87
Update type
sebelga Nov 5, 2024
ef62c69
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Nov 5, 2024
76b02f7
Fix jest tests
sebelga Nov 5, 2024
210668b
Fix TS issue
sebelga Nov 5, 2024
61f565d
Fix tableId missing
sebelga Nov 5, 2024
00c4901
Fix TS issue
sebelga Nov 6, 2024
b9b8762
Fix inspector table pagination
sebelga Nov 7, 2024
f5873cf
Set pageSize instead of initialPageSize in pagination prop
sebelga Nov 7, 2024
f4df7bb
Update helper to open rows per page button
sebelga Nov 8, 2024
d2c58c3
Reset table size to 20 before testing
sebelga Nov 8, 2024
3a61532
Fix jest tests
sebelga Nov 8, 2024
cda6141
Fix jest tests
sebelga Nov 8, 2024
605d896
Revert change to column field
sebelga Nov 8, 2024
55b4cb6
Update snapshot
sebelga Nov 9, 2024
8c8f64b
Add persistence to SO mgmt > UnmatchedReferences table
sebelga Nov 11, 2024
d4bb868
Add persistence to SO mgmt > Relationships table
sebelga Nov 11, 2024
ce2b976
Cleanup
sebelga Nov 11, 2024
8373986
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Nov 11, 2024
8106cd5
Add jest test for the HOC + comments
sebelga Nov 11, 2024
26f2069
Merge branch 'persist-table-rows-per-page' of github.com:sebelga/kiba…
sebelga Nov 11, 2024
af37d6d
Merge branch 'main' into persist-table-rows-per-page
sebelga Nov 12, 2024
cd15415
Merge branch 'main' into persist-table-rows-per-page
sebelga Nov 13, 2024
aa685d5
Merge branch 'main' into persist-table-rows-per-page
sebelga Nov 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const FinderApp = (props: {
<ContentClientProvider contentClient={props.contentClient}>
<I18nProvider>
<SavedObjectFinder
id="cmFinderApp"
showFilter={true}
services={{
savedObjectsTagging: props.savedObjectsTagging.getTaggingApi(),
Expand Down
20 changes: 20 additions & 0 deletions packages/content-management/table_list_view_table/src/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import React from 'react';
import { from } from 'rxjs';
import type { IStorage } from '@kbn/kibana-utils-plugin/public';

import type { Services, TagListProps } from './services';

Expand Down Expand Up @@ -149,3 +150,22 @@ export const getStoryArgTypes = () => ({
defaultValue: false,
},
});

export const localStorageMock = (): IStorage => {
let store: Record<string, unknown> = {};

return {
getItem: (key: string) => {
return store[key] || null;
},
setItem: (key: string, value: unknown) => {
store[key] = value;
},
clear() {
store = {};
},
removeItem(key: string) {
delete store[key];
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { LocationDescriptor, History } from 'history';
import type { UserContentCommonSchema } from '@kbn/content-management-table-list-view-common';

import { WithServices } from './__jest__';
import { getTagList } from './mocks';
import { getTagList, localStorageMock } from './mocks';
import { TableListViewTable, type TableListViewTableProps } from './table_list_view_table';
import { getActions } from './table_list_view.test.helpers';
import type { Services } from './services';
Expand Down Expand Up @@ -335,6 +335,12 @@ describe('TableListView', () => {
const totalItems = 30;
const updatedAt = new Date().toISOString();

beforeEach(() => {
Object.defineProperty(window, 'localStorage', {
value: localStorageMock(),
});
});

const hits: UserContentCommonSchema[] = [...Array(totalItems)].map((_, i) => ({
id: `item${i}`,
type: 'dashboard',
Expand Down Expand Up @@ -429,6 +435,54 @@ describe('TableListView', () => {
expect(firstRowTitle).toBe('Item 20');
expect(lastRowTitle).toBe('Item 29');
});

test('should persist the number of rows in the table', async () => {
let testBed: TestBed;

const tableId = 'myTable';

await act(async () => {
testBed = await setup({
initialPageSize,
findItems: jest.fn().mockResolvedValue({ total: hits.length, hits: [...hits] }),
id: tableId,
});
});

{
const { component, table, find } = testBed!;
component.update();

const { tableCellsValues } = table.getMetaData('itemsInMemTable');
expect(tableCellsValues.length).toBe(20); // 20 by default

let storageValue = localStorage.getItem(`tablePersist:${tableId}`);
expect(storageValue).toBe(null);

find('tablePaginationPopoverButton').simulate('click');
find('tablePagination-10-rows').simulate('click');

storageValue = localStorage.getItem(`tablePersist:${tableId}`);
expect(storageValue).not.toBe(null);
expect(JSON.parse(storageValue!).pageSize).toBe(10);
}

// Mount a second table and verify that is shows only 10 rows
{
await act(async () => {
testBed = await setup({
initialPageSize,
findItems: jest.fn().mockResolvedValue({ total: hits.length, hits: [...hits] }),
id: tableId,
});
});

const { component, table } = testBed!;
component.update();
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
expect(tableCellsValues.length).toBe(10); // 10 items this time
}
});
});

describe('column sorting', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
ContentInsightsProvider,
useContentInsightsServices,
} from '@kbn/content-management-content-insights-public';
import { useEuiTablePersist } from '@kbn/shared-ux-table-persist';

import {
Table,
Expand Down Expand Up @@ -443,7 +444,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
hasUpdatedAtMetadata,
hasCreatedByMetadata,
hasRecentlyAccessedMetadata,
pagination,
pagination: _pagination,
tableSort,
tableFilter,
} = state;
Expand Down Expand Up @@ -903,7 +904,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
[updateTableSortFilterAndPagination]
);

const onTableChange = useCallback(
const customOnTableChange = useCallback(
(criteria: CriteriaWithPagination<T>) => {
const data: {
sort?: State<T>['tableSort'];
Expand Down Expand Up @@ -1038,6 +1039,20 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
);
}, [entityName, fetchError]);

const { pageSize, onTableChange } = useEuiTablePersist({
tableId: listingId,
initialPageSize,
customOnTableChange,
pageSizeOptions: uniq([10, 20, 50, initialPageSize]).sort(),
});

const pagination = useMemo<Pagination>(() => {
return {
..._pagination,
pageSize,
};
}, [_pagination, pageSize]);

// ------------
// Effects
// ------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
"@kbn/content-management-user-profiles",
"@kbn/recently-accessed",
"@kbn/content-management-content-insights-public",
"@kbn/content-management-favorites-public"
"@kbn/content-management-favorites-public",
"@kbn/kibana-utils-plugin",
"@kbn/shared-ux-table-persist"
],
"exclude": [
"target/**/*"
Expand Down
39 changes: 13 additions & 26 deletions packages/kbn-alerts-ui-shared/src/alert_fields_table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import {
EuiTabbedContent,
EuiTabbedContentProps,
useEuiOverflowScroll,
EuiBasicTableColumn,
} from '@elastic/eui';
import { css } from '@emotion/react';
import React, { memo, useCallback, useMemo, useState } from 'react';
import React, { memo, useMemo } from 'react';
import { Alert } from '@kbn/alerting-types';
import { euiThemeVars } from '@kbn/ui-theme';
import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/basic_table';
import { useEuiTablePersist } from '@kbn/shared-ux-table-persist';

export const search = {
box: {
Expand Down Expand Up @@ -66,28 +67,6 @@ export const ScrollableFlyoutTabbedContent = (props: EuiTabbedContentProps) => (

const COUNT_PER_PAGE_OPTIONS = [25, 50, 100];

const useFieldBrowserPagination = () => {
const [pagination, setPagination] = useState<{ pageIndex: number }>({
pageIndex: 0,
});

const onTableChange = useCallback(({ page: { index } }: { page: { index: number } }) => {
setPagination({ pageIndex: index });
}, []);
const paginationTableProp = useMemo(
() => ({
...pagination,
pageSizeOptions: COUNT_PER_PAGE_OPTIONS,
}),
[pagination]
);

return {
onTableChange,
paginationTableProp,
};
};

type AlertField = Exclude<
{
[K in keyof Alert]: { key: K; value: Alert[K] };
Expand All @@ -111,7 +90,11 @@ export interface AlertFieldsTableProps {
* A paginated, filterable table to show alert object fields
*/
export const AlertFieldsTable = memo(({ alert, fields }: AlertFieldsTableProps) => {
const { onTableChange, paginationTableProp } = useFieldBrowserPagination();
const { pageSize, sorting, onTableChange } = useEuiTablePersist<AlertField>({
tableId: 'obltAlertFields',
initialPageSize: 25,
});

const items = useMemo(() => {
let _items = Object.entries(alert).map(
([key, value]) =>
Expand All @@ -131,7 +114,11 @@ export const AlertFieldsTable = memo(({ alert, fields }: AlertFieldsTableProps)
itemId="key"
columns={columns}
onTableChange={onTableChange}
pagination={paginationTableProp}
pagination={{
pageSize,
pageSizeOptions: COUNT_PER_PAGE_OPTIONS,
}}
sorting={sorting}
search={search}
css={css`
& .euiTableRow {
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-alerts-ui-shared/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@kbn/core-ui-settings-browser",
"@kbn/core-http-browser-mocks",
"@kbn/core-notifications-browser-mocks",
"@kbn/kibana-react-plugin"
"@kbn/kibana-react-plugin",
"@kbn/shared-ux-table-persist"
]
}
27 changes: 11 additions & 16 deletions packages/kbn-esql-editor/src/editor_footer/query_history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import {
EuiInMemoryTable,
EuiBasicTableColumn,
EuiButtonEmpty,
Criteria,
EuiButtonIcon,
CustomItemAction,
EuiCopy,
EuiToolTip,
euiScrollBarStyles,
} from '@elastic/eui';
import { css, Interpolation, Theme } from '@emotion/react';
import { useEuiTablePersist } from '@kbn/shared-ux-table-persist';
import { type QueryHistoryItem, getHistoryItems } from '../history_local_storage';
import { getReducedSpaceStyling, swapArrayElements } from './query_history_helpers';

Expand Down Expand Up @@ -212,8 +212,16 @@ export function QueryHistory({
}) {
const theme = useEuiTheme();
const scrollBarStyles = euiScrollBarStyles(theme);
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');
const historyItems: QueryHistoryItem[] = getHistoryItems(sortDirection);

const { sorting, onTableChange } = useEuiTablePersist<QueryHistoryItem>({
tableId: 'esqlQueryHistory',
initialSort: {
field: 'timeRan',
direction: 'desc',
},
});

const historyItems: QueryHistoryItem[] = getHistoryItems(sorting.sort.direction);

const actions: Array<CustomItemAction<QueryHistoryItem>> = useMemo(() => {
return [
Expand Down Expand Up @@ -276,19 +284,6 @@ export function QueryHistory({
return getTableColumns(containerWidth, isOnReducedSpaceLayout, actions);
}, [actions, containerWidth, isOnReducedSpaceLayout]);

const onTableChange = ({ page, sort }: Criteria<QueryHistoryItem>) => {
if (sort) {
const { direction } = sort;
setSortDirection(direction);
}
};

const sorting = {
sort: {
field: 'timeRan',
direction: sortDirection,
},
};
const { euiTheme } = theme;
const extraStyling = isOnReducedSpaceLayout ? getReducedSpaceStyling() : '';

Expand Down
1 change: 1 addition & 0 deletions packages/kbn-esql-editor/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@kbn/fields-metadata-plugin",
"@kbn/esql-validation-autocomplete",
"@kbn/esql-utils",
"@kbn/shared-ux-table-persist",
],
"exclude": [
"target/**/*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const EventAnnotationGroupSavedObjectFinder = ({
) : (
<SavedObjectFinder
key="searchSavedObjectFinder"
id="eventAnnotationGroup"
fixedPageSize={fixedPageSize}
onChoose={(id, type, fullName, savedObject) => {
onChoose({ id, type, fullName, savedObject });
Expand Down
3 changes: 2 additions & 1 deletion packages/shared-ux/table_persist/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export { useEuiTablePersist, DEFAULT_PAGE_SIZE_OPTIONS } from './src';
export { useEuiTablePersist, DEFAULT_PAGE_SIZE_OPTIONS, withEuiTablePersist } from './src';
export type { EuiTablePersistInjectedProps, EuiTablePersistPropsGetter, HOCProps } from './src';
6 changes: 6 additions & 0 deletions packages/shared-ux/table_persist/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@

export { useEuiTablePersist } from './use_table_persist';
export { DEFAULT_PAGE_SIZE_OPTIONS } from './constants';
export { withEuiTablePersist } from './table_persist_hoc';
export type {
EuiTablePersistInjectedProps,
EuiTablePersistPropsGetter,
HOCProps,
} from './table_persist_hoc';
Loading