Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import CSV #3809

Closed
Odonno opened this issue Oct 12, 2019 · 6 comments
Closed

Import CSV #3809

Odonno opened this issue Oct 12, 2019 · 6 comments

Comments

@Odonno
Copy link

Odonno commented Oct 12, 2019

Is your feature request related to a problem? Please describe.

We already have an Export button in CSV format but we don't have an Import button to save/update entities from another source (like importing data from a different environment).

Describe the solution you'd like

An Import button which can be added side-by-side with the Export button.

Additional context

I have already written a solution/component by myself. I can make a PR for that feature.

@kopax
Copy link
Contributor

kopax commented Oct 12, 2019

Hello @Odonno and thanks for offering the feature. Is it possible to see the solution/component you've been working on?

@Odonno
Copy link
Author

Odonno commented Oct 14, 2019

Of course. Here is my solution, and some thoughts:

  • it is written in TypeScript
  • I handle only one file at a time
  • I don't handle exception (like no file selected)
  • The code will rewrite (update) the entire collection (it can surely be improved)
  • I used inline style
  • No internationalization
import React from 'react';
import Button from '@material-ui/core/Button';
import GetAppIcon from '@material-ui/icons/GetApp';
import { connect } from 'react-redux';
import { parse as convertFromCSV } from 'papaparse';
import { crudUpdateMany } from 'ra-core';

const ImportButton = (props: any) => {
    const { resource, dispatch, basePath } = props;

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files && e.target.files[0];

        if (file) {
            convertFromCSV(file, {
                delimiter: ',',
                complete: (result) => {
                    const { data } = result;
                    
                    const keys: string[] = data[0];
                    const primaryKey = keys[0];

                    const values = data.slice(1).map(row => {
                        const value: any = {};

                        keys.forEach((key, index) => {
                            value[key] = row[index];
                        });

                        return value;
                    });

                    const ids = values.map(v => v[primaryKey]);
                    dispatch(
                        crudUpdateMany(resource, ids, values, basePath)
                    );
                }
            });
        }
    };

    return (
        <>
            <input
                type="file"
                id="text-button-file"
                style={{ display: 'none' }}
                accept='.csv'
                onChange={handleChange}
            />
            <label htmlFor="text-button-file" style={{ display: 'inline-flex', alignItems: 'center' }}>
                <Button
                    color="primary"
                    component="span"
                >
                    <GetAppIcon style={{ transform: 'rotate(180deg)', fontSize: 20 }} />
                    <span style={{ paddingLeft: '0.5em' }}>Import</span>
                </Button>
            </label>
        </>
    );
};

export default connect()(ImportButton);

@djhi
Copy link
Collaborator

djhi commented Oct 14, 2019

Would you mind creating an addon package for it ?

@benwinding
Copy link
Contributor

Hey Guys,

Still hard to do, so I implemented the solution from @Odonno into an npm package (react-admin-import-csv) Give it a go and let me know if there's any issues.

https://github.com/benwinding/react-admin-import-csv

Cheeers,
Ben

@Odonno
Copy link
Author

Odonno commented Mar 29, 2020

Well, since we are now lockdown, I would have like to take a look next week to integrate the Import button. But it seems you were faster than me.

I also intensified the test of this feature in the previous weeks and I found some issues. I can do some code reviews/PRs in your repository if you like.

@fzaninotto
Copy link
Member

@benwinding Would you mind opening a PR on the docs to add a link to your package in the Ecosystem section?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants