-
Notifications
You must be signed in to change notification settings - Fork 4.6k
fix(#16584): filterTableData source of truth #36849
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
Changes from 7 commits
72f3828
4d5c7e8
fbcd17f
b08abe7
39d4e5e
6869df8
6632e4a
01e008f
d89cb67
163e7b6
c10dd6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -145,6 +145,11 @@ describe( | |
| .contains("This is a test message") | ||
| .should("be.visible"); | ||
| }); | ||
| cy.getTableV2DataSelector("0", "5").then(($elemClass) => { | ||
| const discardBtnSelector = | ||
| $elemClass + " button[data-test-variant='TERTIARY']"; | ||
| cy.get(discardBtnSelector).click({ force: true }); // discard changes | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use click function from Aghelper. |
||
| }); | ||
| }); | ||
|
|
||
| it("4. Verify filter condition", () => { | ||
|
|
@@ -162,6 +167,10 @@ describe( | |
| cy.get(selector + checkboxSelector).should("be.checked"); | ||
| }); | ||
|
|
||
| cy.getTableV2DataSelector("1", "4").then((selector) => { | ||
| cy.get(selector + checkboxSelector).should("be.checked"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we please use assertHelper here ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how could we use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rahulbarwal , Could you please check the requested changes @sagar-qa007 ? |
||
| }); | ||
|
|
||
| // Filter and verify unchecked rows | ||
| cy.get(widgetsJson.tableFilterRow) | ||
| .find(publishPage.conditionDropdown) | ||
|
|
@@ -172,9 +181,6 @@ describe( | |
| cy.getTableV2DataSelector("0", "4").then((selector) => { | ||
| cy.get(selector + checkboxSelector).should("not.be.checked"); | ||
| }); | ||
| cy.getTableV2DataSelector("1", "4").then((selector) => { | ||
| cy.get(selector + checkboxSelector).should("not.be.checked"); | ||
| }); | ||
| }); | ||
|
|
||
| it("5. Verify if onCheckChange is hidden on custom columns", () => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,6 +137,12 @@ describe( | |
| cy.wait(100); | ||
| agHelper.ValidateToastMessage("This is a test message"); | ||
| }); | ||
|
|
||
| cy.getTableV2DataSelector("0", "5").then(($elemClass) => { | ||
| const discardBtnSelector = | ||
| $elemClass + " button[data-test-variant='TERTIARY']"; | ||
| cy.get(discardBtnSelector).click({ force: true }); // discard changes | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to incorporate above PR comments here. |
||
| }); | ||
| }); | ||
|
|
||
| it("4. Verify filter condition", () => { | ||
|
|
@@ -154,6 +160,10 @@ describe( | |
| cy.get(selector + switchSelector).should("be.checked"); | ||
| }); | ||
|
|
||
| cy.getTableV2DataSelector("1", "4").then((selector) => { | ||
| cy.get(selector + switchSelector).should("be.checked"); | ||
| }); | ||
|
|
||
| // Filter and verify unchecked rows | ||
| cy.get(widgetsJson.tableFilterRow) | ||
| .find(publishPage.conditionDropdown) | ||
|
|
@@ -164,9 +174,6 @@ describe( | |
| cy.getTableV2DataSelector("0", "4").then((selector) => { | ||
| cy.get(selector + switchSelector).should("not.be.checked"); | ||
| }); | ||
| cy.getTableV2DataSelector("1", "4").then((selector) => { | ||
| cy.get(selector + switchSelector).should("not.be.checked"); | ||
| }); | ||
| }); | ||
|
|
||
| it("5. Verify if onChange is hidden on custom columns", () => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -676,6 +676,9 @@ export default { | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const finalTableData = sortedTableData.filter((row) => { | ||||||||||||||||||||||||||||||||
| let isSearchKeyFound = true; | ||||||||||||||||||||||||||||||||
| const originalRow = (props.tableData ?? sortedTableData)[ | ||||||||||||||||||||||||||||||||
| row.__originalIndex__ | ||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||
| const columnWithDisplayText = Object.values(props.primaryColumns).filter( | ||||||||||||||||||||||||||||||||
| (column) => column.columnType === "url" && column.displayText, | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
|
|
@@ -780,7 +783,10 @@ export default { | |||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (searchKey) { | ||||||||||||||||||||||||||||||||
| isSearchKeyFound = Object.values(_.omit(displayedRow, hiddenColumns)) | ||||||||||||||||||||||||||||||||
| isSearchKeyFound = [ | ||||||||||||||||||||||||||||||||
| ...Object.values(_.omit(displayedRow, hiddenColumns)), | ||||||||||||||||||||||||||||||||
| ...Object.values(_.omit(originalRow, hiddenColumns)), | ||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||
|
Comment on lines
+803
to
+806
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider optimizing the search operation. While including both displayed and original values in the search is thorough, let's think about performance. When dealing with large datasets, concatenating all values and performing string operations could be expensive. Consider this optimization: -isSearchKeyFound = [
- ...Object.values(_.omit(displayedRow, hiddenColumns)),
- ...Object.values(_.omit(originalRow, hiddenColumns)),
-].join(", ").toLowerCase().includes(searchKey);
+const searchInRow = (row) => Object.values(_.omit(row, hiddenColumns))
+ .some(value => value.toString().toLowerCase().includes(searchKey));
+isSearchKeyFound = searchInRow(displayedRow) || searchInRow(originalRow);This approach stops searching as soon as a match is found, potentially improving performance with large datasets.
|
||||||||||||||||||||||||||||||||
| .join(", ") | ||||||||||||||||||||||||||||||||
| .toLowerCase() | ||||||||||||||||||||||||||||||||
| .includes(searchKey); | ||||||||||||||||||||||||||||||||
|
|
@@ -811,10 +817,15 @@ export default { | |||||||||||||||||||||||||||||||
| ConditionFunctions[props.filters[i].condition]; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (conditionFunction) { | ||||||||||||||||||||||||||||||||
| filterResult = conditionFunction( | ||||||||||||||||||||||||||||||||
| displayedRow[props.filters[i].column], | ||||||||||||||||||||||||||||||||
| props.filters[i].value, | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| filterResult = | ||||||||||||||||||||||||||||||||
| conditionFunction( | ||||||||||||||||||||||||||||||||
| originalRow[props.filters[i].column], | ||||||||||||||||||||||||||||||||
| props.filters[i].value, | ||||||||||||||||||||||||||||||||
| ) || | ||||||||||||||||||||||||||||||||
| conditionFunction( | ||||||||||||||||||||||||||||||||
| displayedRow[props.filters[i].column], | ||||||||||||||||||||||||||||||||
| props.filters[i].value, | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
|
Comment on lines
+837
to
+845
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Let's make the filter condition check more readable! Class, while the logic is correct, we can make it more maintainable by extracting the condition check into a helper function. Consider this refactor to improve readability: -filterResult =
- conditionFunction(
- originalRow[props.filters[i].column],
- props.filters[i].value,
- ) ||
- conditionFunction(
- displayedRow[props.filters[i].column],
- props.filters[i].value,
- );
+const checkCondition = (row, column, value) =>
+ conditionFunction(row[column], value);
+
+filterResult =
+ checkCondition(originalRow, props.filters[i].column, props.filters[i].value) ||
+ checkCondition(displayedRow, props.filters[i].column, props.filters[i].value);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||
| filterResult = false; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1181,6 +1181,122 @@ describe("Validates getFilteredTableData Properties", () => { | |
| expect(result).toStrictEqual(expected); | ||
| }); | ||
|
|
||
| it("should filter correctly after editing a value with an applied filter", () => { | ||
| const { getFilteredTableData } = derivedProperty; | ||
| const input = { | ||
| tableData: [ | ||
| { id: 1234, name: "Jim Doe" }, | ||
| { id: 123, name: "Hamza Khafaga" }, | ||
| { id: 234, name: "Khadija Khafaga" }, | ||
| ], | ||
| processedTableData: [ | ||
| { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, | ||
| { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, | ||
| { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, | ||
| ], | ||
| filters: [ | ||
| { | ||
| condition: "contains", | ||
| column: "name", | ||
| value: "Khafaga", | ||
| }, | ||
| ], | ||
| sortOrder: { column: "id", order: "desc" }, | ||
| columnOrder: ["name", "id"], | ||
| primaryColumns: { | ||
| id: { | ||
| index: 1, | ||
| width: 150, | ||
| id: "id", | ||
| alias: "id", | ||
| originalId: "id", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "number", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "id", | ||
| isAscOrder: false, | ||
| }, | ||
| name: { | ||
| index: 0, | ||
| width: 150, | ||
| id: "name", | ||
| alias: "name", | ||
| originalId: "name", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "text", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "awesome", | ||
| isAscOrder: undefined, | ||
| }, | ||
| }, | ||
| tableColumns: [ | ||
| { | ||
| index: 0, | ||
| width: 150, | ||
| id: "name", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "text", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "awesome", | ||
| isAscOrder: undefined, | ||
| }, | ||
| { | ||
| index: 1, | ||
| width: 150, | ||
| id: "id", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "number", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "id", | ||
| isAscOrder: false, | ||
| }, | ||
| ], | ||
| }; | ||
|
|
||
| input.orderedTableColumns = Object.values(input.primaryColumns).sort( | ||
| (a, b) => { | ||
| return input.columnOrder[a.id] < input.columnOrder[b.id]; | ||
| }, | ||
| ); | ||
|
|
||
| const expected = [ | ||
| { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, | ||
| { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, | ||
| ]; | ||
|
|
||
| let result = getFilteredTableData(input, moment, _); | ||
|
|
||
| expect(result).toStrictEqual(expected); | ||
| }); | ||
|
|
||
| it("validates generated sanitized table data with valid property keys", () => { | ||
| const { getProcessedTableData } = derivedProperty; | ||
|
|
||
|
|
@@ -1333,6 +1449,116 @@ describe("Validates getFilteredTableData Properties", () => { | |
|
|
||
| expect(result).toStrictEqual(expected); | ||
| }); | ||
|
|
||
| it("filters correctly after editing a value with an applied search key", () => { | ||
| const { getFilteredTableData } = derivedProperty; | ||
| const input = { | ||
| tableData: [ | ||
| { id: 1234, name: "Jim Doe" }, | ||
| { id: 123, name: "Hamza Khafaga" }, | ||
| { id: 234, name: "Khadija Khafaga" }, | ||
| ], | ||
| processedTableData: [ | ||
| { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, | ||
| { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, | ||
| { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, | ||
| ], | ||
| searchText: "Khafaga", | ||
| sortOrder: { column: "id", order: "desc" }, | ||
| columnOrder: ["name", "id"], | ||
| primaryColumns: { | ||
| id: { | ||
| index: 1, | ||
| width: 150, | ||
| id: "id", | ||
| alias: "id", | ||
| originalId: "id", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "number", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "id", | ||
| isAscOrder: false, | ||
| }, | ||
| name: { | ||
| index: 0, | ||
| width: 150, | ||
| id: "name", | ||
| alias: "name", | ||
| originalId: "name", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "text", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "awesome", | ||
| isAscOrder: undefined, | ||
| }, | ||
| }, | ||
| tableColumns: [ | ||
| { | ||
| index: 0, | ||
| width: 150, | ||
| id: "name", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "text", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "awesome", | ||
| isAscOrder: undefined, | ||
| }, | ||
| { | ||
| index: 1, | ||
| width: 150, | ||
| id: "id", | ||
| horizontalAlignment: "LEFT", | ||
| verticalAlignment: "CENTER", | ||
| columnType: "number", | ||
| textColor: "#231F20", | ||
| textSize: "PARAGRAPH", | ||
| fontStyle: "REGULAR", | ||
| enableFilter: true, | ||
| enableSort: true, | ||
| isVisible: true, | ||
| isDerived: false, | ||
| label: "id", | ||
| isAscOrder: false, | ||
| }, | ||
| ], | ||
| }; | ||
|
|
||
| input.orderedTableColumns = Object.values(input.primaryColumns).sort( | ||
| (a, b) => { | ||
| return input.columnOrder[a.id] < input.columnOrder[b.id]; | ||
| }, | ||
| ); | ||
|
|
||
| const expected = [ | ||
| { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, | ||
| { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, | ||
| ]; | ||
|
|
||
| let result = getFilteredTableData(input, moment, _); | ||
|
|
||
| expect(result).toStrictEqual(expected); | ||
| }); | ||
|
Comment on lines
+1540
to
+1648
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Students, let's discuss code duplication! This test case is very similar to the previous one, just using Consider using a parameterized test or combining the cases: describe("filtering after editing a value", () => {
const baseInput = {
tableData: [
{ id: 1234, name: "Jim Doe" },
{ id: 123, name: "Hamza Khafaga" },
{ id: 234, name: "Khadija Khafaga" },
],
processedTableData: [
{ id: 1234, name: "Jim Doe", __originalIndex__: 0 },
{ id: 123, name: "Hamza Anas", __originalIndex__: 1 },
{ id: 234, name: "Khadija Khafaga", __originalIndex__: 2 },
],
// ... common properties ...
};
const expected = [
{ id: 234, name: "Khadija Khafaga", __originalIndex__: 2 },
{ id: 123, name: "Hamza Anas", __originalIndex__: 1 },
];
it("should work with filters", () => {
const input = {
...baseInput,
filters: [{
condition: "contains",
column: "name",
value: "Khafaga",
}],
};
expect(getFilteredTableData(input, moment, _)).toStrictEqual(expected);
});
it("should work with search", () => {
const input = {
...baseInput,
searchText: "Khafaga",
};
expect(getFilteredTableData(input, moment, _)).toStrictEqual(expected);
});
}); |
||
| }); | ||
|
|
||
| describe("Validate getSelectedRow function", () => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kindly add this locator in locator files related to it.