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

[Discover] Added context aware logic for logs view in discover to show Load More… #211176

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4bc9040
Added context aware logic for logs view in discover to show Load More…
achyutjhunjhunwala Feb 14, 2025
3c030cf
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Feb 14, 2025
1262b1c
Fix checktype issues with tests
achyutjhunjhunwala Feb 17, 2025
30a5312
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 17, 2025
44926fa
Created a new React Safe throttle function to take care of function t…
achyutjhunjhunwala Feb 17, 2025
772a1bf
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Feb 17, 2025
ae58357
Add Jest tests for the new hooks
achyutjhunjhunwala Feb 17, 2025
9355069
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 17, 2025
15d8f74
Add unit tests for footer
achyutjhunjhunwala Feb 17, 2025
2d40f38
Add a mock test to check profile based awareness
achyutjhunjhunwala Feb 17, 2025
f03f365
Change logic for handling Load More computation
achyutjhunjhunwala Feb 18, 2025
b1ed427
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 18, 2025
6d21afc
Fix broken tests
achyutjhunjhunwala Feb 18, 2025
4ca7760
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 19, 2025
cb3d7c0
Fix Saved search creation logic for test
achyutjhunjhunwala Feb 19, 2025
7898c63
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 20, 2025
841fc6e
Add serverless test for common discover extension point
achyutjhunjhunwala Feb 20, 2025
06028d4
Update missed throttle call over debounce
achyutjhunjhunwala Feb 20, 2025
3ad351c
Add serverless test for Obs profile
achyutjhunjhunwala Feb 20, 2025
8b886e8
Stateful extension tests
achyutjhunjhunwala Feb 20, 2025
18b6cc8
Fix pagination mode names
achyutjhunjhunwala Feb 20, 2025
18b1c53
Add Unit test case for Profile resolution
achyutjhunjhunwala Feb 21, 2025
6a8925e
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Feb 21, 2025
8b045c1
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Feb 21, 2025
d55c701
Fix typo
achyutjhunjhunwala Feb 21, 2025
0abf153
Fix infinite scroll logic
achyutjhunjhunwala Feb 21, 2025
0f3277f
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Mar 3, 2025
3855658
Fix virtualization options for pagination mode
achyutjhunjhunwala Mar 3, 2025
213dd07
Merge branch 'main' into add-logic-to-load-more-in-logs-view-in-discover
achyutjhunjhunwala Mar 3, 2025
cfb8d1a
Fix checktype issues
achyutjhunjhunwala Mar 3, 2025
d7f8482
Fix checktype issues with unit tests
achyutjhunjhunwala Mar 3, 2025
7e91e22
Fix missed Unit Tests
achyutjhunjhunwala Mar 3, 2025
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
2 changes: 2 additions & 0 deletions src/platform/packages/shared/kbn-react-hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

export { useBoolean } from './src/use_boolean';
export { useErrorTextStyle } from './src/use_error_text_style';
export { useDebounceFn } from './src/use_debounce_fn';
export { useThrottleFn } from './src/use_throttle_fn';
export { useAbortController } from './src/use_abort_controller';
export { useAbortableAsync } from './src/use_abortable_async';
export type { UseAbortableAsync, AbortableAsyncState } from './src/use_abortable_async';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export * from './use_debounce_fn';
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { renderHook, act } from '@testing-library/react';
import { useDebounceFn } from '../..';

describe('useDebounceFn hook', () => {
jest.useFakeTimers();

it('should debounce the function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useDebounceFn(fn, { wait: 200 }));

act(() => {
result.current.run();
result.current.run();
});

expect(fn).not.toBeCalled();

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).toBeCalledTimes(1);
});

it('should cancel the debounced function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useDebounceFn(fn, { wait: 200 }));

act(() => {
result.current.run();
result.current.cancel();
});

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).not.toBeCalled();
});

it('should flush the debounced function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useDebounceFn(fn, { wait: 200 }));

act(() => {
result.current.run();
result.current.flush();
});

expect(fn).toBeCalledTimes(1);
});

it('should handle leading option correctly', () => {
const fn = jest.fn();
const { result } = renderHook(() => useDebounceFn(fn, { wait: 200, leading: true }));

act(() => {
result.current.run();
});

expect(fn).toBeCalledTimes(1);

act(() => {
jest.advanceTimersByTime(200);
});

act(() => {
result.current.run();
});

expect(fn).toBeCalledTimes(2);
});

it('should handle trailing option correctly', () => {
const fn = jest.fn();
const { result } = renderHook(() => useDebounceFn(fn, { wait: 200, trailing: true }));

act(() => {
result.current.run();
result.current.run();
});

expect(fn).not.toBeCalled();

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).toBeCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { debounce, isFunction } from 'lodash';
import { useMemo } from 'react';
import useLatest from 'react-use/lib/useLatest';
import useUnmount from 'react-use/lib/useUnmount';

type Noop = (...args: any[]) => any;

export interface DebounceOptions {
wait?: number;
leading?: boolean;
trailing?: boolean;
maxWait?: number;
}

export function useDebounceFn<T extends Noop>(fn: T, options?: DebounceOptions) {
if (!isFunction(fn)) {
throw Error(`useDebounceFn expected parameter is a function, got ${typeof fn}`);
}

const fnRef = useLatest(fn);

const wait = options?.wait ?? 1000;

const debounced = useMemo(
() =>
debounce(
(...args: Parameters<T>): ReturnType<T> => {
return fnRef.current(...args);
},
wait,
options
),
[fnRef, options, wait]
);

useUnmount(() => {
debounced.cancel();
});

return {
run: debounced,
cancel: debounced.cancel,
flush: debounced.flush,
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export * from './use_throttle_fn';
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { renderHook, act } from '@testing-library/react';
import { useThrottleFn } from '../..';

describe('useThrottleFn hook', () => {
jest.useFakeTimers();

it('should throttle the function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useThrottleFn(fn, { wait: 200, leading: false }));

act(() => {
result.current.run();
result.current.run();
result.current.run();
});

// Because leading is false, the fn won't be called immediately.
expect(fn).toBeCalledTimes(0);

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).toBeCalledTimes(1);

act(() => {
result.current.run();
jest.advanceTimersByTime(200);
});

expect(fn).toBeCalledTimes(2);
});

it('should cancel the throttled function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useThrottleFn(fn, { wait: 200, leading: false }));

act(() => {
result.current.run();
result.current.cancel();
});

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).not.toBeCalled();
});

it('should flush the throttled function call', () => {
const fn = jest.fn();
const { result } = renderHook(() => useThrottleFn(fn, { wait: 200 }));

act(() => {
result.current.run();
result.current.flush();
});

expect(fn).toBeCalledTimes(1);
});

it('should handle leading option correctly', () => {
const fn = jest.fn();
const { result } = renderHook(() => useThrottleFn(fn, { wait: 200, leading: true }));

act(() => {
result.current.run();
});

expect(fn).toBeCalledTimes(1);

act(() => {
jest.advanceTimersByTime(200);
});

act(() => {
result.current.run();
});

expect(fn).toBeCalledTimes(2);
});

it('should handle trailing option correctly', () => {
const fn = jest.fn();
const { result } = renderHook(() => useThrottleFn(fn, { wait: 200, trailing: true }));

act(() => {
result.current.run();
result.current.run();
});

expect(fn).toBeCalledTimes(1);

act(() => {
jest.advanceTimersByTime(200);
});

expect(fn).toBeCalledTimes(2);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { throttle, isFunction } from 'lodash';
import { useMemo } from 'react';
import useLatest from 'react-use/lib/useLatest';
import useUnmount from 'react-use/lib/useUnmount';

type Noop = (...args: any[]) => any;

export interface ThrottleOptions {
wait?: number;
leading?: boolean;
trailing?: boolean;
}

export function useThrottleFn<T extends Noop>(fn: T, options?: ThrottleOptions) {
if (!isFunction(fn)) {
throw Error(`useThrottleFn expected parameter is a function, got ${typeof fn}`);
}

const fnRef = useLatest(fn);

const wait = options?.wait ?? 1000;

const throttled = useMemo(
() =>
throttle(
(...args: Parameters<T>): ReturnType<T> => {
return fnRef.current(...args);
},
wait,
options
),
[fnRef, options, wait]
);

useUnmount(() => {
throttled.cancel();
});

return {
run: throttled,
cancel: throttled.cancel,
flush: throttled.flush,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export {
} from './src/components/row_height_settings';
export { getDisplayedColumns, SOURCE_COLUMN } from './src/utils/columns';
export { getTextBasedColumnsMeta } from './src/utils/get_columns_meta';
export { ROWS_HEIGHT_OPTIONS, DataGridDensity } from './src/constants';
export { ROWS_HEIGHT_OPTIONS, DataGridDensity, DEFAULT_PAGINATION_MODE } from './src/constants';

export { JSONCodeEditorCommonMemoized } from './src/components/json_code_editor/json_code_editor_common';
export { SourceDocument } from './src/components/source_document';
Expand Down
Loading