Skip to content

Commit

Permalink
feat: multiple file upload (#475)
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelSuwinski committed Sep 27, 2022
1 parent 3762ad0 commit 414d297
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/hydra/dataProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,15 @@ describe('Transform a React Admin request to an Hydra request', () => {
await dataProvider.introspect();

const file = new File(['foo'], 'foo.txt');
const icons = [...Array(3).keys()].map((i) => ({
rawFile: new File([`icon_${i}`], `icon_${i}.png`),
}));
await dataProvider.create('resource', {
data: {
image: {
rawFile: file,
},
icons,
bar: 'baz',
qux: null,
array: ['foo', 'dummy'],
Expand All @@ -238,6 +242,7 @@ describe('Transform a React Admin request to an Hydra request', () => {
expect(options.body).toBeInstanceOf(FormData);
expect(Array.from((options.body as FormData).entries())).toEqual([
['image', file],
...icons.map((icon) => ['icons[]', icon.rawFile]),
['bar', 'baz'],
['qux', 'null'],
['array', '["foo","dummy"]'],
Expand Down
28 changes: 19 additions & 9 deletions src/hydra/dataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,14 @@ function dataProvider(
data as Record<string, unknown>,
).then((hydraData) => {
const values = Object.values(hydraData);
const containFile = (element: unknown) =>
isPlainObject(element) &&
Object.values(element as Record<string, unknown>).some(
(value) => value instanceof File,
);
const containFile = (element: unknown): boolean =>
Array.isArray(element)
? element.every((value) => containFile(value))
: isPlainObject(element) &&
Object.values(element as Record<string, unknown>).some(
(value) => value instanceof File,
);

type ToJSONObject = { toJSON(): string };
const hasToJSON = (
element: string | ToJSONObject,
Expand All @@ -281,10 +284,17 @@ function dataProvider(
).forEach(([key, value]) => {
// React-Admin FileInput format is an object containing a file.
if (containFile(value)) {
body.append(
key,
Object.values(value).find((val) => val instanceof File),
);
const findFile = (element: string | ToJSONObject): Blob =>
Object.values(element).find((val) => val instanceof File);
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
Array.isArray(value)
? value
.map((val) => findFile(val))
.forEach((file) => {
body.append(key.endsWith('[]') ? key : `${key}[]`, file);
})
: body.append(key, findFile(value));

return;
}
if (hasToJSON(value)) {
Expand Down

0 comments on commit 414d297

Please sign in to comment.