Skip to content

Commit

Permalink
fix(RHINENG-10460): column sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
AsToNlele committed Jan 8, 2025
1 parent 8379db5 commit 10b6832
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 36 deletions.
18 changes: 18 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,21 @@ Cypress.Commands.add(
);
}
);

Cypress.Commands.add('checkAPISorting', (endpoint, sortKey, direction) => {
cy.wait(endpoint)
.its('request.url')
.should(
'include',
`sort_by=${encodeURIComponent(`${sortKey}:${direction}`)}`
);
});

Cypress.Commands.add('checkAPIFiltering', (endpoint, filterKey, value) => {
cy.wait(endpoint)
.its('request.url')
.should(
'include',
`filter=${encodeURIComponent(`${filterKey} ~ ${value}`)}`
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ const useAsyncTableTools = (items, columns, options = {}) => {

const { toolbarProps: conditionalFilterProps } = useFilterConfig(options);

const { tableProps: sortableTableProps } = useTableSort(
managedColumns,
options
);
const {
tableProps: expandableTableProps,
tableView: expandableTableViewOptions,
Expand All @@ -93,6 +89,11 @@ const useAsyncTableTools = (items, columns, options = {}) => {
bulkSelect: bulkSelectTableViewOptions,
});

const { tableProps: sortableTableProps } = useTableSort(managedColumns, {
...options,
onSelect: bulkSelectTableProps?.onSelect || tablePropsOption?.onSelect,
});

const exportConfig = withExport({
columns: managedColumns,
...options,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export const columnOffset = (options = {}) => {
const init =
(typeof options.onSelect === 'function') +
(typeof options.detailsComponent !== 'undefined');
return typeof options.tableTree !== 'undefined' ? init - 1 : init;
return options.tableView === 'tree' ? init - 1 : init;
};
19 changes: 14 additions & 5 deletions src/Frameworks/AsyncTableTools/hooks/useTableSort/useTableSort.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useMemo } from 'react';
import { addSortableTransform, columnOffset } from './helpers';
import useTableState from '../useTableState';
import useTableState, { useRawTableState } from '../useTableState';
import { TABLE_STATE_NAMESPACE } from './constants';

/**
Expand Down Expand Up @@ -40,6 +40,10 @@ const useTableSort = (columns, options = {}) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(columns), JSON.stringify(options.serialisers)]
);

const { tableView } = useRawTableState() || {};
const offset = columnOffset({ ...options, tableView });

const stateOptions = useMemo(
() => ({
...(serialisers?.sort
Expand All @@ -53,7 +57,7 @@ const useTableSort = (columns, options = {}) => {
const [sortBy, setSortBy] = useTableState(
TABLE_STATE_NAMESPACE,
initialSortBy || {
index: columnOffset(options),
index: 0,
direction: 'asc',
},
stateOptions
Expand All @@ -62,18 +66,23 @@ const useTableSort = (columns, options = {}) => {
const onSort = useCallback(
(_, index, direction) => {
setSortBy({
index,
index: index - offset,
direction,
});
onSortOption?.(index, direction);
},
[onSortOption, setSortBy]
[onSortOption, setSortBy, offset]
);

const sortByOffset = sortBy && {
...sortBy,
index: sortBy?.index + offset,
};

return {
tableProps: {
onSort,
sortBy: sortBy,
sortBy: sortByOffset,
cells: addSortableTransform(columns),
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { Spinner, Bullseye } from '@patternfly/react-core';

import propTypes from 'prop-types';
import AsyncTableToolsTable from '@/Frameworks/AsyncTableTools/components/AsyncTableToolsTable';
import { TableToolsTable } from 'Utilities/hooks/useTableTools';
Expand Down
115 changes: 90 additions & 25 deletions src/SmartComponents/CompliancePolicies/CompliancePolicies.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import CompliancePolicies from './CompliancePolicies';
import { init } from 'Store';
import { featureFlagsInterceptors } from '../../../cypress/utils/interceptors';
import { buildPolicies, buildPoliciesV2 } from '../../__factories__/policies';
import Columns from 'PresentationalComponents/PoliciesTable/Columns';
// import * as Filters from 'PresentationalComponents/PoliciesTable/Filters';

const mountComponent = () => {
cy.mountWithContext(CompliancePolicies, { store: init().getStore() });
Expand All @@ -11,9 +13,15 @@ const fixtures = buildPolicies(13);
const fixturesV2 = buildPoliciesV2(13);

const policies = Object.assign([], fixtures['profiles']['edges']);
const policies_v2 = Object.assign([], fixturesV2);

describe('Policies table tests', () => {
const policies_v2 = {
data: fixturesV2,
meta: {
total: fixturesV2.length,
},
};

describe.skip('Policies table tests', () => {
beforeEach(() => {
cy.intercept('*', {
statusCode: 201,
Expand Down Expand Up @@ -408,39 +416,96 @@ describe('Policies table tests', () => {
describe('Policies table tests API V2', () => {
beforeEach(() => {
featureFlagsInterceptors.apiV2Enabled();
cy.intercept('**/graphql', {

// Ignore total endpoint
cy.intercept(/\/api\/compliance\/v2\/policies(?!.*limit=1&).*$/, {
statusCode: 200,
body: {
data: fixtures,
},
});
cy.intercept('**/policies*', {
body: policies_v2,
}).as('getPolicies');

// Total endpoint
cy.intercept('/api/compliance/v2/policies?limit=1', {
statusCode: 200,
body: {
data: fixturesV2,
},
});
body: policies_v2,
}).as('getPoliciesTotal');

mountComponent();
});
describe('defaults', () => {
it.skip('The table renders with data', () => {
it('The table renders with data', () => {
cy.get('table').should('have.length', 1);

let policyNames = [];
policies_v2.forEach((item) => {
policyNames.push(item['title']);
});
const policyNames = policies_v2.data.map((item) => item.title);

// Check Name sorting
const ascendingSorted = [...policyNames].sort((a, b) => {
return a.localeCompare(b, undefined, { sensitivity: 'base' });
});
cy.get('th[data-label="Name"]')
.invoke('attr', 'aria-sort')
.should('eq', 'ascending');
cy.get('td[data-label="Name"] > div > div > a').each((item, index) => {
expect(Cypress.$(item).text()).to.eq(ascendingSorted[index]);
expect(Cypress.$(item).text()).to.eq(policyNames[index]);
});
});
it('Shows correct item count', () => {
cy.ouiaType('PF5/Pagination', 'div')
.first()
.get('.pf-v5-c-menu-toggle__text')
.find('b')
.eq(1)
.should('have.text', policies_v2.data.length);
});
});

it('Sorts each column', () => {
const filteredColumns = Columns.filter(
(el) => !Object.hasOwn(el, 'isShown') || el?.isShown === true
);
cy.wrap(filteredColumns).each((col, index) => {
// Name column
if (index === 0) {
// Wait for initial request with default sorting "title:asc"
cy.checkAPISorting('@getPolicies', col?.sortable, 'asc');
cy.get('.pf-v5-c-skeleton').should('have.length', 0);

// Check Desc
cy.get('th').eq(index).find('button').click();
cy.checkAPISorting('@getPolicies', col?.sortable, 'desc');

// Check Asc
cy.get('th').eq(index).find('button').click();
cy.checkAPISorting('@getPolicies', col?.sortable, 'asc');
} else {
cy.get('.pf-v5-c-skeleton').should('have.length', 0);

// Check Asc
cy.get('th').eq(index).find('button').click();
cy.checkAPISorting('@getPolicies', col?.sortable, 'asc');

// Check Desc
cy.get('th').eq(index).find('button').click();
cy.checkAPISorting('@getPolicies', col?.sortable, 'desc');
}
});
});

// Debouncing needs to be fixed first
describe.skip('Filters', () => {
it('Name filter', () => {
cy.wait('@getPolicies');
cy.get('.pf-v5-c-skeleton').should('have.length', 0);

// cy.get('div[data-input').type('Hello, World')

// cy.ouiaId('Policy name', 'button').click();
cy.ouiaId('ConditionalFilter', 'input').type('foobar');
// cy.checkAPIFiltering('@getPolicies', 'title', 'Foo bar');

const repeatCount = 10;
for (let i = 0; i < repeatCount; i++) {
cy.wait('@getPolicies', {
requestTimeout: 5000,
}).then((interception) => {
const isTargetIntercept = interception.request.url.includes('foobar');
if (isTargetIntercept) found = true;
});
}
let found = false;
expect(found, 'Specific intercept not found').to.be.true;
});
});
});

0 comments on commit 10b6832

Please sign in to comment.