diff --git a/graylog2-web-interface/src/components/bootstrap/Button.tsx b/graylog2-web-interface/src/components/bootstrap/Button.tsx index 75360035cfe1..b82f09273133 100644 --- a/graylog2-web-interface/src/components/bootstrap/Button.tsx +++ b/graylog2-web-interface/src/components/bootstrap/Button.tsx @@ -202,6 +202,7 @@ const StyledButton = styled(MantineButton)<{ type Props = React.PropsWithChildren<{ active?: boolean; + allowClickWhenDisabled?: boolean; 'aria-label'?: string; bsStyle?: StyleProps; bsSize?: BsSize; @@ -226,6 +227,7 @@ type Props = React.PropsWithChildren<{ const Button = ( { 'aria-label': ariaLabel, + allowClickWhenDisabled = false, bsStyle = 'default', bsSize = undefined, className = undefined, @@ -263,7 +265,8 @@ const Button = ( variant: active ? 'outline' : 'filled', color, 'data-testid': dataTestId, - disabled, + disabled: allowClickWhenDisabled ? false : disabled, + 'data-disabled': (allowClickWhenDisabled && disabled) || undefined, role, size: sizeForMantine(bsSize), tabIndex, diff --git a/graylog2-web-interface/src/views/components/DashboardSearchBar.test.tsx b/graylog2-web-interface/src/views/components/DashboardSearchBar.test.tsx index 4c5ab33e54f6..f2301b8678db 100644 --- a/graylog2-web-interface/src/views/components/DashboardSearchBar.test.tsx +++ b/graylog2-web-interface/src/views/components/DashboardSearchBar.test.tsx @@ -98,7 +98,7 @@ describe('DashboardSearchBar', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).not.toContain('disabled')); + await waitFor(() => expect(searchButton).not.toHaveAttribute('data-disabled')); await userEvent.click(searchButton); @@ -124,7 +124,7 @@ describe('DashboardSearchBar', () => { name: /perform search \(changes were made after last search execution\)/i, }); - await waitFor(() => expect(searchButton.classList).not.toContain('disabled')); + await waitFor(() => expect(searchButton).not.toHaveAttribute('data-disabled')); await userEvent.click(searchButton); diff --git a/graylog2-web-interface/src/views/components/SearchBar.test.tsx b/graylog2-web-interface/src/views/components/SearchBar.test.tsx index d2d99ab3ae1e..9e509242eb75 100644 --- a/graylog2-web-interface/src/views/components/SearchBar.test.tsx +++ b/graylog2-web-interface/src/views/components/SearchBar.test.tsx @@ -101,7 +101,7 @@ describe('SearchBar', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).not.toContain('disabled')); + await waitFor(() => expect(searchButton).not.toHaveAttribute('data-disabled')); asMock(dispatch).mockClear(); @@ -121,7 +121,7 @@ describe('SearchBar', () => { const timeRangePickerButton = await screen.findByLabelText('Open Time Range Selector'); const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).toContain('disabled')); + await waitFor(() => expect(searchButton).toHaveAttribute('data-disabled')); within(timeRangePickerButton).getByText('warning'); }); @@ -191,7 +191,7 @@ describe('SearchBar', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).toContain('disabled')); + await waitFor(() => expect(searchButton).toHaveAttribute('data-disabled')); }); it('does not show warning icon on timerange button when search result timerange check returns false', async () => { @@ -211,6 +211,6 @@ describe('SearchBar', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).not.toContain('disabled')); + await waitFor(() => expect(searchButton).not.toHaveAttribute('data-disabled')); }); }); diff --git a/graylog2-web-interface/src/views/components/WidgetQueryControls.test.tsx b/graylog2-web-interface/src/views/components/WidgetQueryControls.test.tsx index b2e6234bd4ba..9d8fbe845143 100644 --- a/graylog2-web-interface/src/views/components/WidgetQueryControls.test.tsx +++ b/graylog2-web-interface/src/views/components/WidgetQueryControls.test.tsx @@ -210,7 +210,7 @@ describe('WidgetQueryControls', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).toContain('disabled')); + await waitFor(() => expect(searchButton).toHaveAttribute('data-disabled')); }); it('does not show warning icon on timerange button when search result timerange check returns false', async () => { @@ -230,6 +230,6 @@ describe('WidgetQueryControls', () => { const searchButton = await screen.findByRole('button', { name: /perform search/i }); - await waitFor(() => expect(searchButton.classList).not.toContain('disabled')); + await waitFor(() => expect(searchButton).not.toHaveAttribute('data-disabled')); }); }); diff --git a/graylog2-web-interface/src/views/components/searchbar/SearchButton.tsx b/graylog2-web-interface/src/views/components/searchbar/SearchButton.tsx index 0414f74ef59d..b4221ede7bd1 100644 --- a/graylog2-web-interface/src/views/components/searchbar/SearchButton.tsx +++ b/graylog2-web-interface/src/views/components/searchbar/SearchButton.tsx @@ -31,10 +31,6 @@ const StyledButton = styled(Button)<{ $dirty: boolean }>( position: relative; min-width: ${SEARCH_BUTTON_WIDTH}px; - &&&.disabled { - color: ${theme.utils.contrastingColor(theme.colors.variant.success)}; - } - ${$dirty ? css` &::after { @@ -84,7 +80,6 @@ const SearchButton = ({ onClick = undefined, }: Props) => { const sendTelemetry = useSendTelemetry(); - const className = disabled ? 'disabled' : ''; const title = dirty ? 'Perform search (changes were made after last search execution)' : 'Perform Search'; const triggerTelemetry = () => { @@ -101,7 +96,8 @@ const SearchButton = ({ onButtonClick(e, disabled, triggerTelemetry, onClick)} title={title} - className={className} + disabled={disabled} + allowClickWhenDisabled type="submit" bsStyle="primary" showOverflow