diff --git a/config/routes.rb b/config/routes.rb index 483d3234488e..682d0780d732 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -551,6 +551,7 @@ end match 'host_statuses' => 'react#index', :via => :get + match 'new/hosts/auto_complete_search', :via => :get, to: 'hosts#auto_complete_search', as: "auto_complete_search_hosts_new" constraints(id: /[^\/]+/) do match 'new/hosts/:id' => 'react#index', :via => :get, :as => :host_details_page end diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/ActionKebab.js b/webpack/assets/javascripts/react_app/components/HostsIndex/ActionKebab.js similarity index 100% rename from webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/ActionKebab.js rename to webpack/assets/javascripts/react_app/components/HostsIndex/ActionKebab.js diff --git a/webpack/assets/javascripts/react_app/components/HostsIndex/index.js b/webpack/assets/javascripts/react_app/components/HostsIndex/index.js index 292bb105b5d4..c83784aa12a9 100644 --- a/webpack/assets/javascripts/react_app/components/HostsIndex/index.js +++ b/webpack/assets/javascripts/react_app/components/HostsIndex/index.js @@ -5,7 +5,7 @@ import { Td } from '@patternfly/react-table'; import { ToolbarItem } from '@patternfly/react-core'; import { translate as __ } from '../../common/I18n'; import TableIndexPage from '../PF4/TableIndexPage/TableIndexPage'; -import { ActionKebab } from '../PF4/TableIndexPage/ActionKebab'; +import { ActionKebab } from './ActionKebab'; import { HOSTS_API_PATH, API_REQUEST_KEY } from '../../routes/Hosts/constants'; import { selectKebabItems } from './Selectors'; import { useAPI } from '../../common/hooks/API/APIHooks'; @@ -44,7 +44,7 @@ const HostsIndex = () => { const { fetchBulkParams, ...selectAllOptions } = useBulkSelect({ results, - metadata: {}, + metadata: { total, page }, initialSearchQuery: apiSearchQuery || '', }); diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox.scss b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox/SelectAllCheckbox.scss similarity index 100% rename from webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox.scss rename to webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox/SelectAllCheckbox.scss diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox.js b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox/index.js similarity index 97% rename from webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox.js rename to webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox/index.js index b63f23695993..9b7221bcdd7f 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox.js +++ b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/SelectAllCheckbox/index.js @@ -6,8 +6,8 @@ import { DropdownToggleCheckbox, DropdownItem, } from '@patternfly/react-core'; -import { translate as __ } from '../../../../common/I18n'; -import { noop } from '../../../../common/helpers'; +import { translate as __ } from '../../../../../common/I18n'; +import { noop } from '../../../../../common/helpers'; import './SelectAllCheckbox.scss'; diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.js b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.js index 3a322f1953c7..42bbc7b93edd 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.js +++ b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.js @@ -93,7 +93,7 @@ export const useSelectionSet = ({ const selectPage = () => { const selectablePageIds = pageIds.filter(canSelect); selectionSet.addAll(selectablePageIds); - selectableResults.forEach (result => { + selectableResults.forEach(result => { selectedResults.current[result[idColumn]] = result; }); }; @@ -168,7 +168,7 @@ export const useBulkSelect = ({ const [searchQuery, updateSearchQuery] = useState(initialSearchQuery); const [selectAllMode, setSelectAllMode] = useState(false); const selectedCount = selectAllMode - ? Number(metadata.selectable) - exclusionSet.size + ? Number(metadata.selectable || metadata.total) - exclusionSet.size : selectOptions.selectedCount; const areAllRowsOnPageSelected = () => diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.test.js b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.test.js new file mode 100644 index 000000000000..7271946e4689 --- /dev/null +++ b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/Table/TableHooks.test.js @@ -0,0 +1,99 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import { useBulkSelect } from './TableHooks'; + +const isSelectable = () => true; +const idColumn = 'errata_id'; +const metadata = { + error: null, selectable: 2, subtotal: 2, total: 2, +}; +const results = [ + { + errata_id: 'RHSA-2022:2031', + id: 311, + severity: 'Low', + type: 'security', + }, + { + errata_id: 'RHSA-2022:2110', + id: 17, + severity: 'Low', + type: 'security', + }, +]; + +it('returns a scoped search string based on inclusionSet', () => { + const { result } = renderHook(() => useBulkSelect({ + results, + metadata, + idColumn, + isSelectable, + })); + + act(() => { + result.current.selectOne(true, 'RHSA-2022:2031'); + }); + + expect(result.current.fetchBulkParams()).toBe('errata_id ^ (RHSA-2022:2031)'); +}); + +it('returns a scoped search string based on exclusionSet', () => { + const { result } = renderHook(() => useBulkSelect({ + results, + metadata, + idColumn, + isSelectable, + })); + + act(() => { + result.current.selectAll(true); + }); + + act(() => { + result.current.selectOne(false, 'RHSA-2022:2031'); + }); + + expect(result.current.fetchBulkParams()).toBe('errata_id !^ (RHSA-2022:2031)'); +}); + +it('adds search query to scoped search string based on exclusionSet', () => { + const { result } = renderHook(() => useBulkSelect({ + results, + metadata, + idColumn, + isSelectable, + })); + + act(() => { + result.current.updateSearchQuery('type=security'); + }); + + act(() => { + result.current.selectAll(true); + }); + + act(() => { + result.current.selectOne(false, 'RHSA-2022:2031'); + }); + + expect(result.current.fetchBulkParams()).toBe('type=security and errata_id !^ (RHSA-2022:2031)'); +}); + +it('adds filter dropdown query to scoped search string', () => { + const { result } = renderHook(() => useBulkSelect({ + results, + metadata, + idColumn, + isSelectable, + filtersQuery: 'severity=Low', + })); + + act(() => { + result.current.selectAll(true); + }); + + act(() => { + result.current.selectOne(false, 'RHSA-2022:2031'); + }); + + expect(result.current.fetchBulkParams()).toBe('severity=Low and errata_id !^ (RHSA-2022:2031)'); +}); diff --git a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/TableIndexPage.test.js b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/TableIndexPage.test.js index ce306c97b3c2..e31e5d644788 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/TableIndexPage.test.js +++ b/webpack/assets/javascripts/react_app/components/PF4/TableIndexPage/TableIndexPage.test.js @@ -37,6 +37,17 @@ const props = { exportable: true, creatable: true, hasHelpPage: true, + response: { + response: { + search: "", + can_create: true, + results: [{item: 1}], + total: 1, + per_page: 20, + page: 1, + subtotal: 1, + }, + }, children: