From fdb8d7f08ef804249e8f75a6083a52fdfde12349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Rodr=C3=ADguez?= Date: Fri, 24 Oct 2025 12:52:54 -0600 Subject: [PATCH 1/9] Adding filters to COLUMN_ARRAY_NESTED_FUNCTIONS --- src/lib/utils/propCategories.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/utils/propCategories.js b/src/lib/utils/propCategories.js index 2eb167b..267d0bf 100644 --- a/src/lib/utils/propCategories.js +++ b/src/lib/utils/propCategories.js @@ -301,6 +301,7 @@ export const COLUMN_NESTED_OR_OBJ_OF_FUNCTIONS = { export const COLUMN_ARRAY_NESTED_FUNCTIONS = { children: 1, filterOptions: 1, + filters: 1 }; /** From ea6ddae22a6c88d0152a9abd0e91cf2688269ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Rodr=C3=ADguez?= Date: Fri, 24 Oct 2025 13:09:19 -0600 Subject: [PATCH 2/9] Adding the production build --- package-lock.json | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index b784e43..3f02b9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10060,7 +10060,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -10102,7 +10101,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -10862,7 +10860,6 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -12847,7 +12844,8 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true + "dev": true, + "requires": {} }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -13845,7 +13843,8 @@ "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "requires": {} }, "@emotion/utils": { "version": "1.2.1", @@ -14347,7 +14346,8 @@ "@mui/types": { "version": "7.2.13", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", - "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==" + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", + "requires": {} }, "@mui/utils": { "version": "5.15.7", @@ -14701,19 +14701,22 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/info": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/serve": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true + "dev": true, + "requires": {} }, "@xtuc/ieee754": { "version": "1.2.0", @@ -14737,7 +14740,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "ag-charts-community": { "version": "11.3.2", @@ -15951,7 +15955,8 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.9", @@ -16795,7 +16800,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ignore": { "version": "5.3.1", @@ -19129,7 +19135,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.4", @@ -19240,7 +19247,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "requires": { "loose-envify": "^1.1.0" } @@ -19275,7 +19281,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -19798,7 +19803,6 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, "requires": { "loose-envify": "^1.1.0" } @@ -20174,7 +20178,8 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "dev": true + "dev": true, + "requires": {} }, "style-to-object": { "version": "0.4.4", @@ -20689,7 +20694,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true + "dev": true, + "requires": {} } } }, From 320bfafd38cf7eb45b5df96a75d60d93ca5018db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Rodr=C3=ADguez?= Date: Fri, 24 Oct 2025 15:37:29 -0600 Subject: [PATCH 3/9] package-lock.json revert changes --- package-lock.json | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f02b9c..b784e43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10060,6 +10060,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -10101,6 +10102,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dev": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -10860,6 +10862,7 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dev": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -12844,8 +12847,7 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "requires": {} + "dev": true }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -13843,8 +13845,7 @@ "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "requires": {} + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" }, "@emotion/utils": { "version": "1.2.1", @@ -14346,8 +14347,7 @@ "@mui/types": { "version": "7.2.13", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", - "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", - "requires": {} + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==" }, "@mui/utils": { "version": "5.15.7", @@ -14701,22 +14701,19 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/info": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/serve": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "requires": {} + "dev": true }, "@xtuc/ieee754": { "version": "1.2.0", @@ -14740,8 +14737,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ag-charts-community": { "version": "11.3.2", @@ -15955,8 +15951,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.9", @@ -16800,8 +16795,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} + "dev": true }, "ignore": { "version": "5.3.1", @@ -19135,8 +19129,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.4", @@ -19247,6 +19240,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, "requires": { "loose-envify": "^1.1.0" } @@ -19281,6 +19275,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -19803,6 +19798,7 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dev": true, "requires": { "loose-envify": "^1.1.0" } @@ -20178,8 +20174,7 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "dev": true, - "requires": {} + "dev": true }, "style-to-object": { "version": "0.4.4", @@ -20694,8 +20689,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "requires": {} + "dev": true } } }, From deecbd5404b883641c63a792ab855d1b093aac47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Rodr=C3=ADguez?= Date: Fri, 24 Oct 2025 15:56:33 -0600 Subject: [PATCH 4/9] Adding a comma (,) --- src/lib/utils/propCategories.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/utils/propCategories.js b/src/lib/utils/propCategories.js index 267d0bf..60f819a 100644 --- a/src/lib/utils/propCategories.js +++ b/src/lib/utils/propCategories.js @@ -301,7 +301,7 @@ export const COLUMN_NESTED_OR_OBJ_OF_FUNCTIONS = { export const COLUMN_ARRAY_NESTED_FUNCTIONS = { children: 1, filterOptions: 1, - filters: 1 + filters: 1, }; /** From a050cced1dfcf0e1d25396cabde2e5143332b3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Rodr=C3=ADguez?= Date: Fri, 5 Dec 2025 11:32:40 -0700 Subject: [PATCH 5/9] Fix duplicate entry in CHANGELOG.md Removed duplicate entry for issue #412 in the changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 381029c..f39928b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Links "DE#nnn" prior to version 2.0 point to the Dash Enterprise closed-source D - [#408](https://github.com/plotly/dash-ag-grid/pull/408) fixed issue where the `columnState` would conflict with `columnDefs` updates - fixes [#416] (https://github.com/plotly/dash-ag-grid/issues/416) - fixes [#407](https://github.com/plotly/dash-ag-grid/issues/407) +- [#412](https://github.com/plotly/dash-ag-grid/issues/412) fix "Multi-Column Filter not properly recognized in filterParams" ## [33.3.2rc2] - 2025-09-17 From baf26c0023ffdafb1c18f22e67e5ecec73459aa0 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 5 Dec 2025 15:04:36 -0700 Subject: [PATCH 6/9] Add: test for comparator filter --- tests/assets/dashAgGridFunctions.js | 38 +++++++++++- tests/test_custom_filter.py | 96 +++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/tests/assets/dashAgGridFunctions.js b/tests/assets/dashAgGridFunctions.js index eacb3e6..76d399e 100644 --- a/tests/assets/dashAgGridFunctions.js +++ b/tests/assets/dashAgGridFunctions.js @@ -396,6 +396,41 @@ dagfuncs.startWith = ([filterValues], cellValue) => { const name = cellValue ? cellValue.split(" ")[1] : "" return name && name.toLowerCase().indexOf(filterValues.toLowerCase()) === 0 } + +dagfuncs.dateFilterComparator = (filterLocalDateAtMidnight, cellValue) => { + const dateAsString = cellValue; + + if (dateAsString == null) { + // Return -1 to show nulls "before" any date + return -1; + } + + // The data from this CSV is in dd/mm/yyyy format + const dateParts = dateAsString.split("/"); + if (dateParts.length !== 3) { + // Handle invalid format + return 0; + } + + const day = Number(dateParts[0]); + const month = Number(dateParts[1]) - 1; // JS months are 0-indexed + const year = Number(dateParts[2]); + const cellDate = new Date(year, month, day); + + // Check for invalid date (e.g., from "NaN") + if (isNaN(cellDate.getTime())) { + return 0; + } + + // Now that both parameters are Date objects, we can compare + if (cellDate < filterLocalDateAtMidnight) { + return -1; + } else if (cellDate > filterLocalDateAtMidnight) { + return 1; + } + return 0; +}; + // END test_custom_filter.py // FOR test_quick_filter.py @@ -502,4 +537,5 @@ dagfuncs.TestEvent = (params, setEventData) => { dagfuncs.testToyota = (params) => { return params.data.make == 'Toyota' ? {'color': 'blue'} : {} -} \ No newline at end of file +} + diff --git a/tests/test_custom_filter.py b/tests/test_custom_filter.py index b0e6c54..6d15950 100644 --- a/tests/test_custom_filter.py +++ b/tests/test_custom_filter.py @@ -236,3 +236,99 @@ def test_fi005_custom_filter(dash_duo): # Test numberParser and numberFormatter grid.set_filter(0, "$100,5") grid.wait_for_cell_text(0, 0, "$200,00") + +def test_fi006_custom_filter(dash_duo): + app = Dash(__name__) + + df = pd.read_csv( + "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv" + ) + + columnDefs = [ + {"field": "athlete", + "filter": "agMultiColumnFilter", + "filterParams": { + "filters": [ + {"filter": "agTextColumnFilter"}, + {"filter": "agSetColumnFilter"} # Example with Set Filter + ] + }}, + {"field": "country"}, + { + "field": "date", + "filter": "agMultiColumnFilter", + "filterParams": { + "filters": [ + { + "filter": "agSetColumnFilter", + 'filterParams': {'excelMode': 'windows', 'buttons': ['apply', 'reset'], + } + }, + { + "filter": "agDateColumnFilter", + 'filterParams': { + 'excelMode': 'windows', + 'buttons': ['apply', 'reset'], + 'comparator': {'function': 'dateFilterComparator'}, + } + }, + ], + + }, + }, + ] + + + app.layout = html.Div( + [ + dag.AgGrid( + id="date-filter-example", + enableEnterpriseModules=True, + columnDefs=columnDefs, + rowData=df.to_dict("records"), + defaultColDef={"flex": 1, "minWidth": 150, "floatingFilter": True}, + dashGridOptions={"animateRows": False} + ), + ], + ) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "date-filter-example") + + # Wait for grid to load + grid.wait_for_cell_text(0, 0, "Michael Phelps") + + # Test Set Filter - select a date from the checkbox list + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + + # Uncheck "Select All" + dash_duo.find_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input').click() + + # Select "24/08/2008" + set_filter_items = dash_duo.find_elements('.ag-set-filter-list .ag-virtual-list-item') + for item in set_filter_items: + if "24/08/2008" in item.text: + item.find_element_by_css_selector('.ag-checkbox-input').click() + break + + # Apply and verify + dash_duo.find_element('button[ref="applyFilterButton"]').click() + grid.wait_for_cell_text(0, 2, "24/08/2008") + + # Reset + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('button[ref="resetFilterButton"]').click() + + # Test Date Filter - type a date in the input field + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + + # Switch to Date Filter tab + dash_duo.find_elements('.ag-tabs-header .ag-tab')[1].click() + + # Type date and apply + dash_duo.find_element('.ag-date-filter input[class*="ag-input-field-input"]').send_keys("24/08/2008") + dash_duo.find_element('button[ref="applyFilterButton"]').click() + + # Verify + grid.wait_for_cell_text(0, 2, "24/08/2008") \ No newline at end of file From 2d5cc90763f345b2683bb2cf4e2daf4b0031e51a Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Wed, 10 Dec 2025 10:52:46 -0700 Subject: [PATCH 7/9] fix test adding a wait --- tests/test_custom_filter.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/tests/test_custom_filter.py b/tests/test_custom_filter.py index 6d15950..8ec14a6 100644 --- a/tests/test_custom_filter.py +++ b/tests/test_custom_filter.py @@ -300,10 +300,13 @@ def test_fi006_custom_filter(dash_duo): grid.wait_for_cell_text(0, 0, "Michael Phelps") # Test Set Filter - select a date from the checkbox list - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') + filter_button.click() - # Uncheck "Select All" - dash_duo.find_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input').click() + # Wait for filter menu to open and uncheck "Select All" + dash_duo.wait_for_element('.ag-set-filter-list') + select_all = dash_duo.wait_for_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input') + select_all.click() # Select "24/08/2008" set_filter_items = dash_duo.find_elements('.ag-set-filter-list .ag-virtual-list-item') @@ -313,22 +316,30 @@ def test_fi006_custom_filter(dash_duo): break # Apply and verify - dash_duo.find_element('button[ref="applyFilterButton"]').click() + apply_button = dash_duo.wait_for_element('button[ref="applyFilterButton"]') + apply_button.click() grid.wait_for_cell_text(0, 2, "24/08/2008") # Reset - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() - dash_duo.find_element('button[ref="resetFilterButton"]').click() + filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') + filter_button.click() + reset_button = dash_duo.wait_for_element('button[ref="resetFilterButton"]') + reset_button.click() # Test Date Filter - type a date in the input field - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') + filter_button.click() - # Switch to Date Filter tab - dash_duo.find_elements('.ag-tabs-header .ag-tab')[1].click() + # Wait for tabs and switch to Date Filter tab + dash_duo.wait_for_element('.ag-tabs-header') + date_tab = dash_duo.find_elements('.ag-tabs-header .ag-tab')[1] + date_tab.click() - # Type date and apply - dash_duo.find_element('.ag-date-filter input[class*="ag-input-field-input"]').send_keys("24/08/2008") - dash_duo.find_element('button[ref="applyFilterButton"]').click() + # Wait for date input and type date + date_input = dash_duo.wait_for_element('.ag-date-filter input[class*="ag-input-field-input"]') + date_input.send_keys("24/08/2008") - # Verify + # Apply and verify + apply_button = dash_duo.wait_for_element('button[ref="applyFilterButton"]') + apply_button.click() grid.wait_for_cell_text(0, 2, "24/08/2008") \ No newline at end of file From 6793de631bf6bda2e8c90ec4cb5bd4d3605e439a Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Wed, 10 Dec 2025 11:16:22 -0700 Subject: [PATCH 8/9] fix test remove waiting --- tests/test_custom_filter.py | 52 ++++++++++++++----------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/tests/test_custom_filter.py b/tests/test_custom_filter.py index 8ec14a6..b1ee065 100644 --- a/tests/test_custom_filter.py +++ b/tests/test_custom_filter.py @@ -296,17 +296,13 @@ def test_fi006_custom_filter(dash_duo): grid = utils.Grid(dash_duo, "date-filter-example") - # Wait for grid to load grid.wait_for_cell_text(0, 0, "Michael Phelps") - # Test Set Filter - select a date from the checkbox list - filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') - filter_button.click() + # Test Set Filter - click filter button on date column + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() - # Wait for filter menu to open and uncheck "Select All" - dash_duo.wait_for_element('.ag-set-filter-list') - select_all = dash_duo.wait_for_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input') - select_all.click() + # Uncheck "Select All" + dash_duo.find_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input').click() # Select "24/08/2008" set_filter_items = dash_duo.find_elements('.ag-set-filter-list .ag-virtual-list-item') @@ -315,31 +311,23 @@ def test_fi006_custom_filter(dash_duo): item.find_element_by_css_selector('.ag-checkbox-input').click() break - # Apply and verify - apply_button = dash_duo.wait_for_element('button[ref="applyFilterButton"]') - apply_button.click() + # Apply + dash_duo.find_element('button[ref="applyFilterButton"]').click() grid.wait_for_cell_text(0, 2, "24/08/2008") # Reset - filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') - filter_button.click() - reset_button = dash_duo.wait_for_element('button[ref="resetFilterButton"]') - reset_button.click() - - # Test Date Filter - type a date in the input field - filter_button = dash_duo.wait_for_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]') - filter_button.click() - - # Wait for tabs and switch to Date Filter tab - dash_duo.wait_for_element('.ag-tabs-header') - date_tab = dash_duo.find_elements('.ag-tabs-header .ag-tab')[1] - date_tab.click() - - # Wait for date input and type date - date_input = dash_duo.wait_for_element('.ag-date-filter input[class*="ag-input-field-input"]') - date_input.send_keys("24/08/2008") - - # Apply and verify - apply_button = dash_duo.wait_for_element('button[ref="applyFilterButton"]') - apply_button.click() + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('button[ref="resetFilterButton"]').click() + + # Test Date Filter - click filter button again + dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + + # Switch to Date Filter tab (second tab) + dash_duo.find_elements('.ag-tabs-header .ag-tab')[1].click() + + # Type date + dash_duo.find_element('.ag-date-filter input[class*="ag-input-field-input"]').send_keys("24/08/2008") + + # Apply + dash_duo.find_element('button[ref="applyFilterButton"]').click() grid.wait_for_cell_text(0, 2, "24/08/2008") \ No newline at end of file From de563a9de66012a12fa8e5a9ec670edeb1e7078e Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Wed, 10 Dec 2025 13:42:57 -0700 Subject: [PATCH 9/9] fix test selector issue --- tests/test_custom_filter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_custom_filter.py b/tests/test_custom_filter.py index b1ee065..5cdaa9c 100644 --- a/tests/test_custom_filter.py +++ b/tests/test_custom_filter.py @@ -114,7 +114,7 @@ def test_fi003_custom_filter(dash_duo): grid.wait_for_cell_text(0, 0, "23") - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('.ag-floating-filter[aria-colindex="3"] button').click() dash_duo.find_element('.ag-filter label:nth-child(2)').click() @@ -299,7 +299,7 @@ def test_fi006_custom_filter(dash_duo): grid.wait_for_cell_text(0, 0, "Michael Phelps") # Test Set Filter - click filter button on date column - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('.ag-floating-filter[aria-colindex="3"] button').click() # Uncheck "Select All" dash_duo.find_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input').click() @@ -316,11 +316,11 @@ def test_fi006_custom_filter(dash_duo): grid.wait_for_cell_text(0, 2, "24/08/2008") # Reset - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('.ag-floating-filter[aria-colindex="3"] button').click() dash_duo.find_element('button[ref="resetFilterButton"]').click() # Test Date Filter - click filter button again - dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click() + dash_duo.find_element('.ag-floating-filter[aria-colindex="3"] button').click() # Switch to Date Filter tab (second tab) dash_duo.find_elements('.ag-tabs-header .ag-tab')[1].click()