Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a9ee6ab
add cancel button on ui
ruchidh Oct 7, 2025
bf0bbda
abort query
ruchidh Oct 8, 2025
093d05f
s3 implemenetaion
ruchidh Oct 9, 2025
09fdab6
tets cases done
ruchidh Oct 10, 2025
00e196a
change cancel icon
ruchidh Oct 10, 2025
69d78a0
add timeput delay for cancel button and fix canel icon border
ruchidh Oct 11, 2025
f75a813
query cancel for s3 tested
ruchidh Oct 15, 2025
0585282
Update opensearch_dashboards.yml
ruchidh Oct 15, 2025
9235963
Delete scripts/cance_query.md
ruchidh Oct 15, 2025
8f549d9
Update sql_async_search_strategy.ts
ruchidh Oct 15, 2025
9796031
Remove unnecessary whitespace in sql_async_search_strategy
ruchidh Oct 15, 2025
13a5104
Delete src/plugins/query_enhancements/server/search/ppl_async_search_…
ruchidh Oct 15, 2025
23f08f3
Delete src/plugins/query_enhancements/server/search/sql_async_search_…
ruchidh Oct 15, 2025
a993e67
Remove unnecessary comment on query cancellation
ruchidh Oct 15, 2025
0ea035d
Add inProgressQueryId check in SQL async search
ruchidh Oct 15, 2025
5326882
Clean up comments in abortAllActiveQueries function
ruchidh Oct 15, 2025
1496f15
Fix comment formatting in opensearch_dashboards.yml
ruchidh Oct 15, 2025
42d4f19
Changeset file for PR #10727 created/updated
opensearch-changeset-bot[bot] Oct 15, 2025
fdff680
Update query_editor_top_row.test.tsx
ruchidh Oct 15, 2025
837d3e7
Remove abort signal handling tests
ruchidh Oct 15, 2025
83467e7
Merge branch 'main' into ruchi/cancel-query
ruchidh Oct 15, 2025
f996e7b
Add setBreakdownField reducer to query editor slice
ruchidh Oct 15, 2025
8c83511
Remove contextProvider configuration comment
ruchidh Oct 15, 2025
520fc20
update QueryEditorTopRow tests
ruchidh Oct 15, 2025
1415f71
Update opensearch_dashboards.yml
ruchidh Oct 15, 2025
d6c28e9
Add comments for new OpenSearch Dashboards features
ruchidh Oct 15, 2025
0b787e1
Adjust cancel button display delay
ruchidh Oct 15, 2025
2c7815e
Update overall_status_middleware.ts
ruchidh Oct 16, 2025
1b5c29f
Refactor overall status middleware for clarity
ruchidh Oct 16, 2025
ca6d5c0
fix logic for opensearch cancel
ruchidh Oct 16, 2025
85b8439
query execution
ruchidh Oct 16, 2025
aea55a0
Refactor import statements for overall status middleware
ruchidh Oct 16, 2025
3bb7f04
Add shouldShowCancelButton to dependencies
ruchidh Oct 16, 2025
546225c
Update overall_status_middleware.ts
ruchidh Oct 16, 2025
02ff6e2
Refactor condition for resetting user query flag
ruchidh Oct 16, 2025
94503ac
Format export statements for query editor selectors
ruchidh Oct 16, 2025
c20d497
Merge branch 'main' into ruchi/cancel-query
ruchidh Oct 21, 2025
36a3298
Update query_execution_button.test.tsx
ruchidh Oct 21, 2025
e12b541
update eui class for hardcocded text
ruchidh Oct 21, 2025
feaf536
Update _query_editor.scss
ruchidh Oct 21, 2025
5c44212
Update _query_editor.scss
ruchidh Oct 21, 2025
6f85122
refactor timing logic fo cancel logic
ruchidh Oct 21, 2025
eb7972f
Update index.ts
ruchidh Oct 21, 2025
eb27e1e
Fix missing newline at end of use_cancel_button_timing.ts
ruchidh Oct 21, 2025
a2a8aa5
Update query_editor_top_row.tsx
ruchidh Oct 21, 2025
5e8323c
Fix type assertion for useCancelButtonTiming mock
ruchidh Oct 21, 2025
26d1292
initial load opensearch
ruchidh Oct 21, 2025
1fdda8a
intiial load
ruchidh Oct 22, 2025
8aa08e7
pass overallstatus param
ruchidh Oct 22, 2025
b20850e
Merge branch 'main' into ruchi/cancel-query
ruchidh Oct 22, 2025
5c5036a
add test cases
ruchidh Oct 22, 2025
58ffd27
Update use_cancel_button_timing.test.ts
ruchidh Oct 22, 2025
883f2bf
fix test cases
ruchidh Oct 22, 2025
6ee4ffb
fix editor run test case
ruchidh Oct 22, 2025
a9b4687
Update use_search.test.tsx
ruchidh Oct 22, 2025
3e2001a
Update search_bar.test.tsx
ruchidh Oct 22, 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 changelogs/fragments/10727.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- Add cancel query feature to discover ([#10727](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10727))
2 changes: 1 addition & 1 deletion config/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,4 @@

# @experimental Set the value to true to enable context provider
# contextProvider:
# enabled: true
# enabled: true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this included by mistake?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why it's showing up, though i didn't make any changes, tried to reset but still shows up

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do:

git restore --staged config/opensearch_dashboatrds.yml

before commiting.

And better yet, something we learned from @ashwin-pc , if you have temporaryopensearch_dashboards.yml changes you need to make, create a opensearch_dashboards.dev.yml within this folder and have your personal changes in there. Then you never have to interact with the opensearch_dashboards.yml file. This is what mine looks like:

Screenshot 2025-10-21 at 11 47 17 AM

Copy link
Collaborator

@angle943 angle943 Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and i believe its showing up because you prob made changes to this file for your local configs, and your IDE is auto-formatting it.

TBH its more proper to add the extra whitespace like your change does, but ideally in the future its best to leave this file out of the diff to make it easier for reviewers.

You can use vim to undo this change if you really wanted and commit it, but not a blocker

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks justin that would help

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ export {
IUiStart as DataPublicPluginStartUi,
useQueryStringManager,
getEffectiveLanguageForAutoComplete,
useCancelButtonTiming,
} from './ui';

/**
Expand Down
12 changes: 12 additions & 0 deletions src/plugins/data/public/ui/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

export { useCancelButtonTiming } from './use_cancel_button_timing';
111 changes: 111 additions & 0 deletions src/plugins/data/public/ui/hooks/use_cancel_button_timing.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

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

describe('useCancelButtonTiming', () => {
beforeEach(() => {
jest.useFakeTimers();
});

afterEach(() => {
jest.runOnlyPendingTimers();
jest.useRealTimers();
});

it('should show cancel button initially when showInitially is true', () => {
const { result } = renderHook(() => useCancelButtonTiming(false, true));
expect(result.current).toBe(true);
});

it('should not show cancel button initially when showInitially is false', () => {
const { result } = renderHook(() => useCancelButtonTiming(false, false));
expect(result.current).toBe(false);
});

it('should show cancel button after 50ms delay when shouldShow becomes true', () => {
const { result, rerender } = renderHook(
({ shouldShow }) => useCancelButtonTiming(shouldShow, false),
{ initialProps: { shouldShow: false } }
);

expect(result.current).toBe(false);

rerender({ shouldShow: true });
expect(result.current).toBe(false); // Still false immediately

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

expect(result.current).toBe(true);
});

it('should keep cancel button visible for minimum 200ms when hiding', () => {
const { result, rerender } = renderHook(
({ shouldShow }) => useCancelButtonTiming(shouldShow, true),
{ initialProps: { shouldShow: false } }
);

expect(result.current).toBe(true);

// Start hiding process
rerender({ shouldShow: false });
expect(result.current).toBe(true); // Still visible

// Wait 100ms (less than 200ms minimum)
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current).toBe(true);

// Complete 200ms minimum display time
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current).toBe(false);
});

it('should transition from initial mode to delayed mode after first query', () => {
const { result, rerender } = renderHook(
({ shouldShow }) => useCancelButtonTiming(shouldShow, true),
{ initialProps: { shouldShow: true } }
);

expect(result.current).toBe(true);

// Complete initial query
rerender({ shouldShow: false });
act(() => {
jest.advanceTimersByTime(200);
});
expect(result.current).toBe(false);

// Start new query - should now use 50ms delay
rerender({ shouldShow: true });
expect(result.current).toBe(false); // No longer shows immediately

act(() => {
jest.advanceTimersByTime(50);
});
expect(result.current).toBe(true);
});

it('should clean up timers on unmount', () => {
const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
const { unmount } = renderHook(() => useCancelButtonTiming(true, true));

unmount();
expect(clearTimeoutSpy).toHaveBeenCalled();
clearTimeoutSpy.mockRestore();
});
});
73 changes: 73 additions & 0 deletions src/plugins/data/public/ui/hooks/use_cancel_button_timing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import { useState, useEffect, useRef } from 'react';

/**
* Custom hook for managing cancel button visibility with proper timing
* - Shows cancel button initially on page load if showInitially=true (for initial queries)
* - Hides button when initial query completes
* - Shows cancel button after 50ms delay when shouldShow becomes true (prevents flickering for quick queries)
* - Keeps button visible for minimum 200ms (smooth UX)
*/
export const useCancelButtonTiming = (shouldShow: boolean, showInitially: boolean = true) => {
const [shouldShowCancelButton, setShouldShowCancelButton] = useState(showInitially);
const cancelButtonTimerRef = useRef<NodeJS.Timeout | null>(null);
const minimumDisplayTimerRef = useRef<NodeJS.Timeout | null>(null);
const hasCompletedInitialQueryRef = useRef(false); // Track if initial query has completed

useEffect(() => {
if (shouldShow) {
// Clear any existing minimum display timer
if (minimumDisplayTimerRef.current) {
clearTimeout(minimumDisplayTimerRef.current);
minimumDisplayTimerRef.current = null;
}

// Start timer to show cancel button after 50ms (existing logic)
cancelButtonTimerRef.current = setTimeout(() => {
setShouldShowCancelButton(true);
}, 50);
} else {
// Clear the show timer
if (cancelButtonTimerRef.current) {
clearTimeout(cancelButtonTimerRef.current);
cancelButtonTimerRef.current = null;
}

// Mark that initial query has completed (if we were showing initially)
if (showInitially && !hasCompletedInitialQueryRef.current) {
hasCompletedInitialQueryRef.current = true;
}

// If button is currently visible, keep it visible for minimum 200ms
if (shouldShowCancelButton) {
minimumDisplayTimerRef.current = setTimeout(() => {
setShouldShowCancelButton(false);
}, 200);
} else {
setShouldShowCancelButton(false);
}
}

// Cleanup timers on unmount
return () => {
if (cancelButtonTimerRef.current) {
clearTimeout(cancelButtonTimerRef.current);
}
if (minimumDisplayTimerRef.current) {
clearTimeout(minimumDisplayTimerRef.current);
}
};
}, [shouldShow, shouldShowCancelButton, showInitially]);

return shouldShowCancelButton;
};
1 change: 1 addition & 0 deletions src/plugins/data/public/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ export { SuggestionsComponent } from './typeahead';
export { DatasetSelector, DatasetSelectorAppearance } from './dataset_selector';
export { AdvancedSelector } from './dataset_selector/advanced_selector';
export { ConfiguratorV2 } from './dataset_selector/configurator/configurator_v2';
export { useCancelButtonTiming } from './hooks';
7 changes: 7 additions & 0 deletions src/plugins/data/public/ui/query_editor/_query_editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@
max-width: 32px;
}

// Global cancel button styling - applies everywhere
.osdQueryEditor__cancelButton {
border: 1px solid $euiColorDanger !important;
border-radius: $euiSizeXS !important;
background-color: transparent !important;
}

.osdQueryEditor--updateButtonWrapper {
:first-child {
min-width: 0 !important;
Expand Down
Loading
Loading