diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a66e1a8d..bc40045c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ ## Not released -- isRemoteCalculationSupported: revert remote calculation for dynamic spatial index sources [#905](https://github.com/CartoDB/carto-react/pull/905) - Fix HistogramWidget with one non-zero bucket [#901](https://github.com/CartoDB/carto-react/pull/901) - Spatial Index Sources use remote widgets calculation [#898](https://github.com/CartoDB/carto-react/pull/898) - Support for `hiddenColumnFields` parameter and `onRowClick` handler for Table Widget [#900](https://github.com/CartoDB/carto-react/pull/900) -- Support for `searchText` and `searchColumn` for Table Widget [#902](https://github.com/CartoDB/carto-react/pull/902) +- Support for `searchText` and `searchColumn` for remote calculations for Table Widget [#902](https://github.com/CartoDB/carto-react/pull/902) +- Support `searchText` and `searchColumn` for local calculations (Tilesets) for Table Widget [#903](https://github.com/CartoDB/carto-react/pull/903) - Support for columns `formatter` function for Table Widget [#904](https://github.com/CartoDB/carto-react/pull/904) +- isRemoteCalculationSupported: revert remote calculation for dynamic spatial index sources [#905](https://github.com/CartoDB/carto-react/pull/905) ## 3.0.0 diff --git a/packages/react-widgets/src/models/TableModel.js b/packages/react-widgets/src/models/TableModel.js index 331eedf12..5491e28df 100644 --- a/packages/react-widgets/src/models/TableModel.js +++ b/packages/react-widgets/src/models/TableModel.js @@ -8,11 +8,22 @@ export function getTable(props) { function fromLocal(props) { // Injecting sortByColumnType externally from metadata gives better results. It allows to avoid deriving type from row value itself (with potential null values) - const { source, sortBy, sortDirection, sortByColumnType, page, rowsPerPage } = props; + const { + source, + sortBy, + sortDirection, + sortByColumnType, + page, + rowsPerPage, + searchFilterText, + searchFilterColumn + } = props; return executeTask(source.id, Methods.FEATURES_RAW, { filters: source.filters, filtersLogicalOperator: source.filtersLogicalOperator, + searchFilterText, + searchFilterColumn, sortBy, sortByDirection: sortDirection, sortByColumnType, @@ -29,14 +40,26 @@ function formatResult(res) { // From remote function fromRemote(props) { - const { source, spatialFilter, searchFilter, abortController, ...params } = props; + const { + source, + spatialFilter, + searchFilterText, + searchFilterColumn, + abortController, + ...params + } = props; const { columns, sortBy, sortDirection, page, rowsPerPage } = params; + const searchFilter = + searchFilterText && searchFilterColumn + ? { [searchFilterColumn]: { stringSearch: { values: [searchFilterText] } } } + : null; + return _executeModel({ model: 'table', source, spatialFilter, - searchFilter, + ...(searchFilter && { searchFilter }), params: { column: columns, sortBy, diff --git a/packages/react-widgets/src/widgets/TableWidget.js b/packages/react-widgets/src/widgets/TableWidget.js index fa985d45d..7776217a1 100644 --- a/packages/react-widgets/src/widgets/TableWidget.js +++ b/packages/react-widgets/src/widgets/TableWidget.js @@ -70,9 +70,8 @@ function TableWidget({ dataSource, params: { columns: [...columns.map((c) => c.field), ...hiddenColumnFields], - searchFilter: containsStringSearchFilter && { - [searchColumn]: { stringSearch: { values: [searchText] } } - }, + searchFilterText: searchText, + searchFilterColumn: searchColumn, sortBy, sortDirection, sortByColumnType, diff --git a/packages/react-workers/__tests__/methods.test.js b/packages/react-workers/__tests__/methods.test.js index 7dc5f07e5..baf7bf7fb 100644 --- a/packages/react-workers/__tests__/methods.test.js +++ b/packages/react-workers/__tests__/methods.test.js @@ -98,5 +98,46 @@ describe('Worker Methods', () => { .sort((a, b) => b.size_m2 - a.size_m2) }); }); + + it('should not filter when searchFilterColumn is provided, but searchFilterText is not', () => { + expect( + getRawFeatures({ + searchFilterColumn: Object.keys(sampleGeoJson.features[0].properties)[0], + searchFilterText: null + }) + ).toEqual({ + totalCount: 6, + hasData: true, + rows: sampleGeoJson.features.map((f) => f.properties) + }); + }); + + it('should not filter when searchFilterText is provided, but searchFilterColumn is not', () => { + expect( + getRawFeatures({ + searchFilterColumn: null, + searchFilterText: 'any-text' + }) + ).toEqual({ + totalCount: 6, + hasData: true, + rows: sampleGeoJson.features.map((f) => f.properties) + }); + }); + + it('should filter when searchFilterColumn and searchFilterText are provided', () => { + const searchFilterColumn = Object.keys(sampleGeoJson.features[0].properties)[0]; + + const result = getRawFeatures({ + searchFilterColumn, + searchFilterText: sampleGeoJson.features[0].properties[searchFilterColumn] + }); + + expect(result).toEqual({ + totalCount: 1, + hasData: true, + rows: [sampleGeoJson.features.map((f) => f.properties)[0]] + }); + }); }); }); diff --git a/packages/react-workers/src/workers/methods.js b/packages/react-workers/src/workers/methods.js index 1ee6b13fb..b205ff679 100644 --- a/packages/react-workers/src/workers/methods.js +++ b/packages/react-workers/src/workers/methods.js @@ -11,6 +11,7 @@ import { } from '@carto/react-core'; import { InvalidColumnError } from '@carto/react-core/'; import { applySorting } from '../utils/sorting'; +import { current } from '@reduxjs/toolkit'; let currentFeatures; let currentGeoJSON; @@ -224,6 +225,8 @@ export function getRange({ filters, filtersLogicalOperator, column }) { export function getRawFeatures({ filters, filtersLogicalOperator, + searchFilterColumn, + searchFilterText, sortBy, sortByDirection = 'asc', sortByColumnType, @@ -236,7 +239,19 @@ export function getRawFeatures({ let hasData = false; if (currentFeatures) { - rows = applySorting(getFilteredFeatures(filters, filtersLogicalOperator), { + let filteredFeatures = getFilteredFeatures(filters, filtersLogicalOperator); + + if (searchFilterColumn && searchFilterText) { + filteredFeatures = filteredFeatures.filter( + (row) => + row[searchFilterColumn] && + String(row[searchFilterColumn]) + .toLowerCase() + .includes(String(searchFilterText).toLowerCase()) + ); + } + + rows = applySorting(filteredFeatures, { sortBy, sortByDirection, sortByColumnType