Repository: api-platform/admin (ts)

Issue:
Range filter changes [] style to dot notation
If use standard filters to achieve range filter functionality, i.e.:
```
<Filter {...props}>
    <SelectInput
        source='year[gte]'
        label="Year from"
        choices={getYears()}
        alwaysOn
    />
</Filter>
```
as a result you will get api request: year.gte=2002 instead of required year[gte]=2002

Pull request:
Use array notation for exists, range and date filters
| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tickets       | fixes #260
| License       | MIT
| Doc PR        | N/A

React Final Form doesn't make the distinction between array notation and dot notation (see https://final-form.org/docs/final-form/field-names).

Since some filters in API Platform use array notation (exists, range and date filters), the data provider needs to check if some specific keywords for these filters are used.

Hence using a hardcoded list of keywords like this.

The drawbacks of this method is the need to maintain this list and the risk of conflict with property names.

A second solution would be to use a special syntax like curly brackets (like `date{after}`) but I don't think it's an user-friendly solution since it needs to be documented.

A third solution would be to use something like `HydraFilter` which would replace array notation to curly notation (and it would use the second solution too).

Maybe we can introduce the last solutions for special cases like if the exists filter parameter name is modified. WDYT?

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b512b8..e0e4a85 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
 ## 2.0.1
 
 * Use readable and writable fields instead of fields
+* Use array notation for exists, range and date filters
 
 ## 2.0.0
 
diff --git a/src/hydra/dataProvider.js b/src/hydra/dataProvider.js
index 55c4482..1c35599 100644
--- a/src/hydra/dataProvider.js
+++ b/src/hydra/dataProvider.js
@@ -235,6 +235,26 @@ export default (
             }
 
             Object.keys(filterValue).forEach(subKey => {
+              if (
+                rootKey === 'exists' ||
+                [
+                  'after',
+                  'before',
+                  'strictly_after',
+                  'strictly_before',
+                  'lt',
+                  'gt',
+                  'lte',
+                  'gte',
+                  'between',
+                ].includes(subKey)
+              ) {
+                return buildFilterParams(
+                  subKey,
+                  filterValue,
+                  `${rootKey}[${subKey}]`,
+                );
+              }
               buildFilterParams(subKey, filterValue, `${rootKey}.${subKey}`);
             });
           };


Test patch:
diff --git a/src/hydra/dataProvider.test.js b/src/hydra/dataProvider.test.js
index 5541f7f..ac76a70 100644
--- a/src/hydra/dataProvider.test.js
+++ b/src/hydra/dataProvider.test.js
@@ -90,6 +90,9 @@ describe('Transform a React Admin request to an Hydra request', () => {
           sub_nested: { sub: { param: true } },
           array: ['/iri/1', '/iri/2'],
           nested_array: { nested: ['/nested_iri/1', '/nested_iri/2'] },
+          exists: { foo: true },
+          nested_date: { date: { before: '2000' } },
+          nested_range: { range: { between: '12.99..15.99' } },
         },
       })
       .then(() => {
@@ -109,6 +112,12 @@ describe('Transform a React Admin request to an Hydra request', () => {
           'nested_array.nested[1]',
           '/nested_iri/2',
         ]);
+        expect(searchParams[7]).toEqual(['exists[foo]', 'true']);
+        expect(searchParams[8]).toEqual(['nested_date.date[before]', '2000']);
+        expect(searchParams[9]).toEqual([
+          'nested_range.range[between]',
+          '12.99..15.99',
+        ]);
       });
   });
 });