index.tsx 6.05 KB
Newer Older
1
2
3
import * as React from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
4
import {withStyles} from 'material-ui/styles';
Matija Obreza's avatar
Matija Obreza committed
5
import {FormLabel} from 'material-ui/Form';
6
7
8
9
10
11
12
13
14
15
16
import Button from 'material-ui/Button';
import Grid from 'material-ui/Grid';
import Divider from 'material-ui/Divider';
import List, {
    ListItem,
    ListItemSecondaryAction,
} from 'material-ui/List';
import IconButton from 'material-ui/IconButton';
import DeleteIcon from 'material-ui-icons/Delete';
import Snackbar from 'material-ui/Snackbar';

Matija Obreza's avatar
Matija Obreza committed
17
import {regexp} from 'data/acceptFileTypes';
Matija Obreza's avatar
Matija Obreza committed
18
19
20

import {uploadRepositoryFileRequest, deleteRepositoryFileRequest} from 'actions/dataset';
import {Dataset} from 'model/dataset.model';
21
import {RepositoryFile} from 'model/repositoryFile.model';
22
23
24

interface IUploadSectionProps extends React.ClassAttributes<any> {
    classes: any;
Matija Obreza's avatar
Matija Obreza committed
25
    fields: any;
Matija Obreza's avatar
Matija Obreza committed
26

27
    uuid: any;
Matija Obreza's avatar
Matija Obreza committed
28
29
30
31
    dataset: Dataset;

    uploadRepositoryFileRequest: (dataset: Dataset, file: File) => any;
    deleteRepositoryFileRequest: (dataset: Dataset, fileRepositoryUUID: string) => any;
32
33
}

34
const styleSheet: any = (theme) => ({
35
36
37
38
39
40
41
42
    /* tslint:disable */
    root: {
        '& input[type="file"]': {
            display: 'none',
        },
        width: '100%',
        display: 'flex',
        flexWrap: 'wrap',
Maxim Babichev's avatar
Maxim Babichev committed
43
        margin: '20px 0 0 0',
44
45
46
47
48
49
50
    },
    fileLabel: {
        width: '100%',
        display: 'flex',
        flexWrap: 'wrap',
        position: 'relative',
    },
Maxim Babichev's avatar
Maxim Babichev committed
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    field: {
        flexBasis: '90%',
        maxWidth: '90%',
        [theme.breakpoints.down('lg')]: {
            maxWidth: '80%',
        },
        [theme.breakpoints.down('md')]: {
            maxWidth: '80%',
        },
    },
    button: {
        flexBasis: '10%',
        maxWidth: '10%',
        textAlign: 'center',
        [theme.breakpoints.down('lg')]: {
            flexBasis: '20%',
            maxWidth: '20%',
        },
    },
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    /* tslint:enable */
    placeholder: {
        color: 'rgba(0, 0, 0, 0.87)',
        fontWeight: 'normal',
        padding: '8px 0 8px 0',
        margin: '16px 0 0 0',
        // width: '100%',
    },
    divider: {
        backgroundColor: 'rgba(0, 0, 0, 0.42)',
    },
    uploadLabel: {
        position: 'absolute',
        top: 0,
        left: 0,
        transform: 'translate(-6px, 0px) scale(0.75)',
    },
Maxim Babichev's avatar
Maxim Babichev committed
87
88
    uploadField: {
        padding: '0 !important',
89
    },
90
});
91
92
93
94
95
96
97
98
99
100
101
102

class UploadSection extends React.Component<IUploadSectionProps, any> {

    public constructor(props: any) {
        super(props);

        this.state = {
            open: false,
        };
    }

    protected onChange = (e) => {
Matija Obreza's avatar
Matija Obreza committed
103
        const {dataset, uploadRepositoryFileRequest} = this.props;
104
105
106
        const file = e.target.files[0];

        if (regexp.test(file.name)) {
Matija Obreza's avatar
Matija Obreza committed
107
            uploadRepositoryFileRequest(dataset, file);
108
109
110
111
112
113
        } else {
            this.setState({ open: true });
        }
    }

    protected deleteFile = (fileUUID) => {
Matija Obreza's avatar
Matija Obreza committed
114
115
        const {dataset, deleteRepositoryFileRequest} = this.props;
        deleteRepositoryFileRequest(dataset, fileUUID);
116
117
118
119
120
121
122
123
    }

    protected handleRequestClose = () => {
        this.setState({ open: false });
    }

    public render() {

Matija Obreza's avatar
Matija Obreza committed
124
        const {classes, fields, dataset} = this.props;
Matija Obreza's avatar
Matija Obreza committed
125
126
127
128

        if (!dataset) {
          return null;
        }
129
130
131

        return (
            <Grid container className={ classes.root }>
Maxim Babichev's avatar
Maxim Babichev committed
132
                <Grid item xs={ 12 } className={ classes.uploadField }>
133
134
                    <input id="file" type="file" onChange={ this.onChange }/>
                    <label htmlFor="file" className={ classes.fileLabel }>
Maxim Babichev's avatar
Maxim Babichev committed
135
                        <Grid item xs={ 12 } md={ 11 } className={ classes.field }>
136
137
138
139
                            <FormLabel className={ classes.uploadLabel } >Upload*</FormLabel>
                            <FormLabel className={ classes.placeholder } >From file ...</FormLabel>
                            <Divider className={ classes.divider } />
                        </Grid>
Maxim Babichev's avatar
Maxim Babichev committed
140
141
                        <Grid item xs={ 12 } md={ 1 } className={ classes.button }>
                            <Button raised component="span" className={ classes.uploadButton }>
142
143
144
145
146
147
148
149
                                Upload
                            </Button>
                        </Grid>
                    </label>
                </Grid>
                <Grid item xs={ 12 }>
                    <div className={ classes.demo }>
                        <List>
Matija Obreza's avatar
Matija Obreza committed
150
                            { fields.map((member, index, fields) => (
151
152
153
154
                                    <ListItem divider button key={ index } >
                                        <div>
                                            { index + 1 }
                                        </div>
155
                                        <div>{ (fields.get(index) as RepositoryFile).originalFilename }</div>
156
157
                                        <ListItemSecondaryAction>
                                            <IconButton aria-label="Delete">
158
                                                <DeleteIcon onClick={ this.deleteFile.bind(this, fields.get(index).uuid) }/>
159
160
161
162
163
164
165
166
167
168
169
170
                                            </IconButton>
                                        </ListItemSecondaryAction>
                                    </ListItem>
                                ))
                            }
                        </List>
                    </div>
                </Grid>

                <Snackbar
                    anchorOrigin={ { vertical: 'bottom', horizontal: 'center' } }
                    open={ this.state.open }
171
                    onClose={ this.handleRequestClose }
172
173
174
175
176
177
178
                    SnackbarContentProps={ {
                        'aria-describedby': 'message-id',
                    } }
                    message={ <span id="message-id">Accepted file types: csv,xls,xlsx</span> }
                />
            </Grid>
        );
Matija Obreza's avatar
Matija Obreza committed
179
    }
180
181
182
183
184
185
186
}

const mapDispatchToProps = (dispatch) => bindActionCreators({
    uploadRepositoryFileRequest,
    deleteRepositoryFileRequest,
}, dispatch);

Matija Obreza's avatar
Matija Obreza committed
187
export default connect(() => ({}), mapDispatchToProps)(withStyles(styleSheet)(UploadSection));