From 7d690d5b46350299809d5d0861b4686734412baa Mon Sep 17 00:00:00 2001 From: Rahul Barwal Date: Wed, 14 May 2025 11:59:43 +0530 Subject: [PATCH] fix: Enhance table search functionality by omitting system columns from search results (#40647) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit    ## Description Problem Table search results included irrelevant search results. Root cause System columns were not excluded in the search logic, causing them to be considered during filtering. Solution This PR handles the exclusion of system columns from the table search logic, ensuring only relevant user-visible columns are considered during filtering. This improves the accuracy and clarity of search results. Fixes #39469 _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Table" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 0ca8bca0d058575be52458ae53c095818cab36c8 > Cypress dashboard. > Tags: `@tag.Table` > Spec: >
Wed, 14 May 2025 03:41:27 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **Bug Fixes** - Improved search functionality in tables by excluding system columns from search results, ensuring more accurate filtering. - **Tests** - Added and reorganized tests to validate search behavior, focusing on exclusion of system and hidden columns from search results. --- .../derived.test/getFilteredTableData.test.js | 269 ++++++++++++++++-- .../widgets/TableWidgetV2/widget/derived.js | 9 +- 2 files changed, 255 insertions(+), 23 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js index bbf3dc8414..abf5148aad 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js @@ -1324,27 +1324,6 @@ describe("Validates getFilteredTableData Properties", () => { expect(result).toStrictEqual(expected); }); - it("validate search on table data for URL columntype with display text", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - ...inputWithDisplayText, - searchText: "Y", - enableClientSideSearch: true, - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [{ url: "B.COM", __originalIndex__: 1 }]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - it("filters correctly after editing a value with an applied search key", () => { const { getFilteredTableData } = derivedProperty; const input = { @@ -1454,4 +1433,252 @@ describe("Validates getFilteredTableData Properties", () => { expect(result).toStrictEqual(expected); }); + + describe("Search in table data", () => { + it("validate search on table data for URL columntype with display text", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + ...inputWithDisplayText, + searchText: "Y", + enableClientSideSearch: true, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [{ url: "B.COM", __originalIndex__: 1 }]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("should exclude system columns from search results", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, + { id: 123, name: "John Doe", __originalIndex__: 1 }, + { id: 234, name: "Jane Doe", __originalIndex__: 2 }, + ], + searchText: "0", + enableClientSideSearch: true, + 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, + }, + }, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("should exclude hidden columns from search results", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe", hidden: "secret", __originalIndex__: 0 }, + { id: 123, name: "John Doe", hidden: "public", __originalIndex__: 1 }, + { + id: 234, + name: "Jane Doe", + hidden: "private", + __originalIndex__: 2, + }, + ], + searchText: "secret", + enableClientSideSearch: true, + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id", "hidden"], + 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, + }, + hidden: { + index: 2, + width: 150, + id: "hidden", + alias: "hidden", + originalId: "hidden", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: false, + isDerived: false, + label: "hidden", + isAscOrder: undefined, + }, + }, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("should search correctly in visible columns while ignoring system columns", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, + { id: 123, name: "John Doe", __originalIndex__: 1 }, + { id: 234, name: "Jane Doe", __originalIndex__: 2 }, + ], + searchText: "Jim", + enableClientSideSearch: true, + 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, + }, + }, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [{ id: 1234, name: "Jim Doe", __originalIndex__: 0 }]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + }); }); diff --git a/app/client/src/widgets/TableWidgetV2/widget/derived.js b/app/client/src/widgets/TableWidgetV2/widget/derived.js index 098a5d4ea7..dbc30922a5 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/derived.js +++ b/app/client/src/widgets/TableWidgetV2/widget/derived.js @@ -764,6 +764,7 @@ export default { const hiddenColumns = Object.values(props.primaryColumns) .filter((column) => !column.isVisible) .map((column) => column.alias); + const systemColumns = ["__originalIndex__"]; const finalTableData = sortedTableData.filter((row) => { let isSearchKeyFound = true; @@ -896,9 +897,13 @@ export default { if (searchKey) { const combinedRowContent = [ - ...Object.values(_.omit(displayedRow, hiddenColumns)), + ...Object.values(_.omit(displayedRow, hiddenColumns, systemColumns)), ...Object.values( - _.omit(originalRow, [...hiddenColumns, ...htmlColumnAliases]), + _.omit(originalRow, [ + ...hiddenColumns, + ...htmlColumnAliases, + ...systemColumns, + ]), ), ] .join(", ")