Repository: api-platform/admin
Pull request #98 (2018-06-06 10:57:17)

Add support for bulk delete
| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Bulk delete is a new feature introduced in React Admin. This PR adds support for it in API Platform Admin.

![capture d ecran 2018-06-06 a 12 56 28](https://user-images.githubusercontent.com/57224/41034160-124f8988-6989-11e8-9825-9d26d13a6bc1.png)



Patch:
diff --git a/src/hydra/hydraClient.js b/src/hydra/hydraClient.js
index 6b31596..ddd8f2f 100644
--- a/src/hydra/hydraClient.js
+++ b/src/hydra/hydraClient.js
@@ -1,6 +1,7 @@
 import {
   CREATE,
   DELETE,
+  DELETE_MANY,
   GET_LIST,
   GET_MANY,
   GET_MANY_REFERENCE,
@@ -300,6 +301,9 @@ export default ({entrypoint, resources = []}, httpClient = fetchHydra) => {
           )
           .then(data => ({data, total: response.json['hydra:totalItems']}));
 
+      case DELETE:
+        return Promise.resolve(() => ({data: {}}));
+
       default:
         return Promise.resolve(
           transformJsonLdDocumentToReactAdminDocument(response.json),
@@ -317,23 +321,30 @@ export default ({entrypoint, resources = []}, httpClient = fetchHydra) => {
    * @returns {Promise}
    */
   const fetchApi = (type, resource, params) => {
-    // Hydra doesn't handle WHERE IN requests, so we fallback to calling GET_ONE n times instead
-    if (GET_MANY === type) {
-      return Promise.all(
-        params.ids.map(
-          id =>
-            reactAdminDocumentsCache[id]
-              ? Promise.resolve({data: reactAdminDocumentsCache[id]})
-              : fetchApi(GET_ONE, resource, {id}),
-        ),
-      ).then(responses => ({data: responses.map(({data}) => data)}));
-    }
+    // Hydra doesn't handle MANY requests, so we fallback to calling the ONE request n times instead
+    switch (type) {
+      case GET_MANY:
+        return Promise.all(
+          params.ids.map(
+            id =>
+              reactAdminDocumentsCache[id]
+                ? Promise.resolve({data: reactAdminDocumentsCache[id]})
+                : fetchApi(GET_ONE, resource, {id}),
+          ),
+        ).then(responses => ({data: responses.map(({data}) => data)}));
+
+      case DELETE_MANY:
+        return Promise.all(
+          params.ids.map(id => fetchApi(DELETE, resource, {id})),
+        ).then(responses => ({data: {}}));
 
-    return convertReactAdminRequestToHydraRequest(type, resource, params)
-      .then(({url, options}) => httpClient(url, options))
-      .then(response =>
-        convertHydraResponseToReactAdminResponse(type, resource, response),
-      );
+      default:
+        return convertReactAdminRequestToHydraRequest(type, resource, params)
+          .then(({url, options}) => httpClient(url, options))
+          .then(response =>
+            convertHydraResponseToReactAdminResponse(type, resource, response),
+          );
+    }
   };
 
   return fetchApi;


Test patch:
diff --git a/src/hydra/hydraClient.test.js b/src/hydra/hydraClient.test.js
index 2dcae1d..0d86d44 100644
--- a/src/hydra/hydraClient.test.js
+++ b/src/hydra/hydraClient.test.js
@@ -1,4 +1,4 @@
-import {GET_LIST, GET_MANY} from 'react-admin';
+import {DELETE, DELETE_MANY, GET_LIST, GET_MANY} from 'react-admin';
 import hydraClient, {
   transformJsonLdDocumentToReactAdminDocument,
 } from './hydraClient';
@@ -99,14 +99,40 @@ describe('fetch data from an hydra api', () => {
   test('fetch a get_many resource', async () => {
     const mockHttpClient = jest.fn();
     mockHttpClient
-      .mockReturnValueOnce(Promise.resolve({json: {'@id': 'books/3'}}))
-      .mockReturnValue(Promise.resolve({json: {'@id': 'books/5'}}));
+      .mockReturnValueOnce(Promise.resolve({json: {'@id': '/books/3'}}))
+      .mockReturnValue(Promise.resolve({json: {'@id': '/books/5'}}));
 
-    await hydraClient({entrypoint: '/'}, mockHttpClient)(GET_MANY, 'books', {
+    await hydraClient({entrypoint: ''}, mockHttpClient)(GET_MANY, 'books', {
       ids: [3, 5],
     }).then(response => {
-      expect(response.data[0].id).toEqual('books/3');
-      expect(response.data[1].id).toEqual('books/5');
+      expect(response.data[0].id).toEqual('/books/3');
+      expect(response.data[1].id).toEqual('/books/5');
+    });
+  });
+
+  test('delete resource', async () => {
+    const mockHttpClient = jest.fn();
+    mockHttpClient.mockReturnValueOnce(Promise.resolve(''));
+
+    await hydraClient({entrypoint: ''}, mockHttpClient)(DELETE, 'books', {
+      id: '/books/1',
+    }).then(() => {
+      expect(mockHttpClient.mock.calls[0][0]).toBe('/books/1');
+      expect(mockHttpClient.mock.calls[0][1].method).toBe('DELETE');
+    });
+  });
+
+  test('delete many resources', async () => {
+    const mockHttpClient = jest.fn();
+    mockHttpClient.mockReturnValueOnce(Promise.resolve(''));
+
+    await hydraClient({entrypoint: ''}, mockHttpClient)(DELETE_MANY, 'books', {
+      ids: ['/books/1', '/books/2'],
+    }).then(() => {
+      expect(mockHttpClient.mock.calls[0][0]).toBe('/books/1');
+      expect(mockHttpClient.mock.calls[0][1].method).toBe('DELETE');
+      expect(mockHttpClient.mock.calls[1][0]).toBe('/books/2');
+      expect(mockHttpClient.mock.calls[1][1].method).toBe('DELETE');
     });
   });
 });