@veritone-ce/design-system 1.2.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ import { ComponentStory, Story, ComponentMeta } from '@storybook/react';
2
+ import FileUploader from '.';
3
+ declare const _default: ComponentMeta<({ uploadUrl, files, accept, multiple, onSuccess, onError, extensions, ...props }: {
4
+ 'data-testid'?: string | undefined;
5
+ accept?: import("react-dropzone").Accept | undefined;
6
+ multiple?: boolean | undefined;
7
+ chunking?: boolean | undefined;
8
+ uploadUrl?: string | undefined;
9
+ extensions?: string[] | undefined;
10
+ files?: ((v: File[]) => void) | undefined;
11
+ onError?: ((v: Error) => void) | undefined;
12
+ onSuccess?: ((v: boolean) => void) | undefined;
13
+ }) => JSX.Element>;
14
+ export default _default;
15
+ export declare const Default: ComponentStory<typeof FileUploader> | Story;
@@ -0,0 +1,26 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import FileUploader from '.';
14
+ export default {
15
+ title: 'Components/FileUploader',
16
+ component: FileUploader,
17
+ argTypes: {
18
+ extensions: {
19
+ defaultValue: ['.pdf', '.format']
20
+ }
21
+ }
22
+ };
23
+ export const Default = (_a) => {
24
+ var args = __rest(_a, []);
25
+ return _jsx(FileUploader, Object.assign({}, args));
26
+ };
@@ -0,0 +1,253 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { render } from '../../../utils/tests/helpers';
12
+ import { fireEvent, screen, act, waitFor } from '@testing-library/react';
13
+ import * as axios from 'axios';
14
+ // import * as uploadFile from '../useUploadFile'
15
+ import FileUploader from '..';
16
+ jest.mock('axios');
17
+ const mockedAxios = axios;
18
+ describe('<FileUploader />', () => {
19
+ it('should render the FileUploader component', () => {
20
+ render(_jsx(FileUploader, {}));
21
+ expect(screen.getByTestId('file-uploader')).toBeInTheDocument();
22
+ });
23
+ it('should simulate a drop a file without upload link', () => __awaiter(void 0, void 0, void 0, function* () {
24
+ render(_jsx(FileUploader, {}));
25
+ const dropzone = screen.getByTestId('dropzone');
26
+ const exampleFile = new File(['file'], 'image.png', {
27
+ type: 'image/png'
28
+ });
29
+ Object.defineProperty(dropzone, 'files', {
30
+ value: [exampleFile]
31
+ });
32
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
33
+ fireEvent.drop(dropzone);
34
+ }));
35
+ }));
36
+ it('should simulate a drop a file with upload link and upload error', () => __awaiter(void 0, void 0, void 0, function* () {
37
+ const onError = jest.fn();
38
+ render(_jsx(FileUploader, { uploadUrl: "testing", onError: onError }));
39
+ const dropzone = screen.getByTestId('dropzone');
40
+ const exampleFile = new File(['file'], 'image.png', {
41
+ type: 'image/png'
42
+ });
43
+ Object.defineProperty(dropzone, 'files', {
44
+ value: [exampleFile]
45
+ });
46
+ mockedAxios.default.mockImplementation(() => Promise.reject({}));
47
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
48
+ fireEvent.drop(dropzone);
49
+ }));
50
+ yield waitFor(() => expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument());
51
+ expect(onError).toBeCalled();
52
+ }));
53
+ it('should simulate a drop a file without upload link and upload error', () => __awaiter(void 0, void 0, void 0, function* () {
54
+ const onError = jest.fn();
55
+ render(_jsx(FileUploader, { onError: onError }));
56
+ const dropzone = screen.getByTestId('dropzone');
57
+ const exampleFile = new File(['file'], 'image.png', {
58
+ type: 'image/png'
59
+ });
60
+ Object.defineProperty(dropzone, 'files', {
61
+ value: [exampleFile]
62
+ });
63
+ mockedAxios.default.mockImplementation(() => Promise.reject({}));
64
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
65
+ fireEvent.drop(dropzone);
66
+ }));
67
+ expect(onError).toBeCalled();
68
+ }));
69
+ it('should call onUploadProgress', () => __awaiter(void 0, void 0, void 0, function* () {
70
+ const onSuccess = jest.fn();
71
+ render(_jsx(FileUploader, { uploadUrl: "testing", onSuccess: onSuccess }));
72
+ const dropzone = screen.getByTestId('dropzone');
73
+ const exampleFile = new File(['file'], 'image.png', {
74
+ type: 'image/png'
75
+ });
76
+ Object.defineProperty(dropzone, 'files', {
77
+ value: [exampleFile]
78
+ });
79
+ mockedAxios.default.mockImplementation(({
80
+ //@ts-ignore
81
+ onUploadProgress }) => {
82
+ onUploadProgress({ loaded: 0, total: 100 });
83
+ return Promise.resolve({});
84
+ });
85
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
86
+ fireEvent.drop(dropzone);
87
+ }));
88
+ yield waitFor(() => {
89
+ expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument();
90
+ expect(screen.getAllByTestId('file-progress-bar')[0]).toBeInTheDocument();
91
+ const progressStyles = getComputedStyle(screen.getAllByTestId('file-progress-bar')[0]);
92
+ expect(progressStyles.width).toBe('0%');
93
+ });
94
+ expect(onSuccess).toBeCalled();
95
+ }));
96
+ /* it('should simulate a drop a file with upload link and upload success', async () => {
97
+ const onSuccess = jest.fn()
98
+ render(<FileUploader uploadUrl="testing" onSuccess={onSuccess} />)
99
+
100
+ const dropzone = screen.getByTestId('dropzone')
101
+
102
+ const exampleFile = new File(['file'], 'image.png', {
103
+ type: 'image/png'
104
+ })
105
+
106
+ Object.defineProperty(dropzone, 'files', {
107
+ value: [exampleFile]
108
+ })
109
+
110
+ jest.spyOn(uploadFile, 'uploadFile').mockImplementation(
111
+ jest.fn((_a, _b, setProgress) => {
112
+ setProgress(43)
113
+ return new Promise((resolve) => resolve({} as axios.AxiosResponse))
114
+ })
115
+ )
116
+
117
+ await act(async () => {
118
+ fireEvent.drop(dropzone)
119
+ })
120
+
121
+ await waitFor(() => {
122
+ expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument()
123
+
124
+ expect(screen.getAllByTestId('file-progress-bar')[0]).toBeInTheDocument()
125
+ })
126
+
127
+ await waitFor(() => {
128
+ const progressStyles = getComputedStyle(
129
+ screen.getAllByTestId('file-progress-bar')[0]
130
+ )
131
+ expect(progressStyles.width).toBe('43%')
132
+ })
133
+
134
+ expect(onSuccess).toBeCalled()
135
+ })
136
+
137
+ it('should call files function after drop files', async () => {
138
+ const files = jest.fn()
139
+ render(<FileUploader uploadUrl="testing" files={files} />)
140
+
141
+ const dropzone = screen.getByTestId('dropzone')
142
+
143
+ const exampleFile = new File(['file'], 'image.png', {
144
+ type: 'image/png'
145
+ })
146
+
147
+ Object.defineProperty(dropzone, 'files', {
148
+ value: [exampleFile]
149
+ })
150
+
151
+ jest.spyOn(uploadFile, 'uploadFile').mockImplementation(
152
+ jest.fn((_a, _b, setProgress) => {
153
+ setProgress(43)
154
+ return new Promise((resolve) => resolve({} as axios.AxiosResponse))
155
+ })
156
+ )
157
+
158
+ await act(async () => {
159
+ fireEvent.drop(dropzone)
160
+ })
161
+
162
+ await waitFor(() => {
163
+ expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument()
164
+
165
+ expect(screen.getAllByTestId('file-progress-bar')[0]).toBeInTheDocument()
166
+ })
167
+
168
+ await waitFor(() => {
169
+ const progressStyles = getComputedStyle(
170
+ screen.getAllByTestId('file-progress-bar')[0]
171
+ )
172
+ expect(progressStyles.width).toBe('43%')
173
+ })
174
+
175
+ expect(files).toBeCalled()
176
+ })
177
+
178
+ it('should list a uploaded file', async () => {
179
+ const files = jest.fn()
180
+ render(<FileUploader uploadUrl="testing" files={files} />)
181
+
182
+ const dropzone = screen.getByTestId('dropzone')
183
+
184
+ const exampleFile = new File(['file'], 'image.png', {
185
+ type: 'image/png'
186
+ })
187
+
188
+ Object.defineProperty(dropzone, 'files', {
189
+ value: [exampleFile]
190
+ })
191
+
192
+ jest.spyOn(uploadFile, 'uploadFile').mockImplementation(
193
+ jest.fn((_a, _b, setProgress) => {
194
+ setProgress(100)
195
+ return new Promise((resolve) => resolve({} as axios.AxiosResponse))
196
+ })
197
+ )
198
+
199
+ await act(async () => {
200
+ fireEvent.drop(dropzone)
201
+ })
202
+
203
+ await waitFor(() => {
204
+ expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument()
205
+
206
+ expect(screen.getAllByTestId('file-item-size')[0]).toBeInTheDocument()
207
+ })
208
+
209
+ expect(files).toBeCalled()
210
+ })
211
+
212
+ it('should delete a file on list', async () => {
213
+ const files = jest.fn()
214
+ render(<FileUploader uploadUrl="testing" files={files} />)
215
+
216
+ const dropzone = screen.getByTestId('dropzone')
217
+
218
+ const exampleFile = new File(['file'], 'image.png', {
219
+ type: 'image/png'
220
+ })
221
+
222
+ Object.defineProperty(dropzone, 'files', {
223
+ value: [exampleFile]
224
+ })
225
+
226
+ jest.spyOn(uploadFile, 'uploadFile').mockImplementation(
227
+ jest.fn((_a, _b, setProgress) => {
228
+ setProgress(100)
229
+ return new Promise((resolve) => resolve({} as axios.AxiosResponse))
230
+ })
231
+ )
232
+
233
+ await act(async () => {
234
+ fireEvent.drop(dropzone)
235
+ })
236
+
237
+ await waitFor(() => {
238
+ expect(screen.getAllByTestId('file-item')[0]).toBeInTheDocument()
239
+
240
+ expect(screen.getAllByTestId('file-item-size')[0]).toBeInTheDocument()
241
+ })
242
+
243
+ expect(files).toBeCalled()
244
+
245
+ await act(async () => {
246
+ fireEvent.click(screen.getAllByTestId('file-item-delete-button')[0])
247
+ })
248
+
249
+ await waitFor(() => {
250
+ expect(screen.queryAllByTestId('file-item')).toHaveLength(0)
251
+ })
252
+ }) */
253
+ });
@@ -0,0 +1,20 @@
1
+ import { Accept } from 'react-dropzone';
2
+ export interface FileData {
3
+ file: File;
4
+ uploadProgress: number;
5
+ isUploaded: boolean;
6
+ withError: boolean;
7
+ }
8
+ declare type FileUploaderProps = {
9
+ 'data-testid'?: string;
10
+ accept?: Accept;
11
+ multiple?: boolean;
12
+ chunking?: boolean;
13
+ uploadUrl?: string;
14
+ extensions?: string[];
15
+ files?: (v: File[]) => void;
16
+ onError?: (v: Error) => void;
17
+ onSuccess?: (v: boolean) => void;
18
+ };
19
+ declare const FileUploader: ({ uploadUrl, files, accept, multiple, onSuccess, onError, extensions, ...props }: FileUploaderProps) => JSX.Element;
20
+ export default FileUploader;
@@ -0,0 +1,151 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
14
+ import { useCallback, useEffect, useState } from 'react';
15
+ import { Box } from '@mui/system';
16
+ import { IconButton, Typography } from '@mui/material';
17
+ import { useTheme } from '@mui/material/styles';
18
+ import CloudUploadOutlinedIcon from '@mui/icons-material/CloudUploadOutlined';
19
+ import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
20
+ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
21
+ import { useDropzone } from 'react-dropzone';
22
+ import { useUploadFile } from './useUploadFile';
23
+ const FileUploader = (_a) => {
24
+ var { uploadUrl, files, accept, multiple, onSuccess, onError, extensions = ['[format]', '[format]', '[format]'] } = _a, props = __rest(_a, ["uploadUrl", "files", "accept", "multiple", "onSuccess", "onError", "extensions"]);
25
+ const { palette } = useTheme();
26
+ const [fileList, setfileList] = useState([]);
27
+ const { onDrop } = useUploadFile(setfileList, uploadUrl, onSuccess, onError);
28
+ const { getRootProps, getInputProps, acceptedFiles } = useDropzone({
29
+ multiple,
30
+ accept,
31
+ onDrop
32
+ });
33
+ const handleDeleteFile = useCallback((fileIndex) => {
34
+ const nFileList = [...fileList];
35
+ nFileList.splice(fileIndex, 1);
36
+ setfileList(nFileList);
37
+ }, [fileList]);
38
+ useEffect(() => {
39
+ const fileArray = fileList.map(({ file }) => file);
40
+ files && files(fileArray);
41
+ }, [acceptedFiles, fileList, files]);
42
+ return (_jsxs(Box, Object.assign({ "data-testid": "file-uploader" }, props, { children: [_jsxs(Box, Object.assign({ "data-testid": "dropzone", sx: {
43
+ maxWidth: '500px',
44
+ height: '109px',
45
+ display: 'flex',
46
+ alignItems: 'center',
47
+ gap: '20px',
48
+ paddingTop: '20px',
49
+ paddingRight: '38px',
50
+ paddingBottom: '19px',
51
+ paddingLeft: '20px',
52
+ width: '100%',
53
+ boxSizing: 'border-box',
54
+ borderRadius: '4px',
55
+ cursor: 'pointer',
56
+ outline: `1px solid ${palette.neutral.main}`
57
+ } }, getRootProps(), { children: [_jsx("input", Object.assign({}, getInputProps())), _jsx(Box, Object.assign({ sx: {
58
+ display: 'flex',
59
+ alignItems: 'center',
60
+ justifyContent: 'center',
61
+ width: '70px',
62
+ height: '70px',
63
+ boxSizing: 'border-box',
64
+ border: `6px solid ${palette.misc.altBackground}`,
65
+ borderRadius: '50%'
66
+ } }, { children: _jsx(CloudUploadOutlinedIcon, { sx: {
67
+ fill: palette.text.tertiary,
68
+ width: '30px',
69
+ height: '30px'
70
+ } }) })), _jsxs(Box, { children: [_jsxs(Typography, Object.assign({ sx: {
71
+ fontSize: '14px',
72
+ width: '352px',
73
+ fontWeight: 600,
74
+ lineHeight: '22px',
75
+ color: palette.text.primary
76
+ } }, { children: [_jsx(Box, Object.assign({ component: "span", sx: {
77
+ marginRight: '4px',
78
+ textDecoration: 'underline',
79
+ color: palette.button.main
80
+ } }, { children: "Browse files" })), "from your computer or drag and drop here"] })), _jsxs(Typography, Object.assign({ sx: {
81
+ fontWeight: 600,
82
+ fontSize: '10px',
83
+ lineHeight: '16px',
84
+ color: palette.neutral.main
85
+ } }, { children: ["Supported File Formats: ", extensions === null || extensions === void 0 ? void 0 : extensions.join(', ')] }))] })] })), fileList.map((file, index) => {
86
+ return (_jsxs(Box, Object.assign({ "data-testid": "file-item", sx: {
87
+ height: '70px',
88
+ maxWidth: '500px',
89
+ display: 'flex',
90
+ alignItems: 'center',
91
+ gap: '20px',
92
+ padding: '15px',
93
+ boxSizing: 'border-box',
94
+ borderBottom: `1px solid rgba(42, 50, 60, 0.5)`
95
+ } }, { children: [_jsx(Box, Object.assign({ sx: {
96
+ display: 'flex',
97
+ alignItems: 'center',
98
+ justifyContent: 'center',
99
+ width: '40px',
100
+ height: '40px',
101
+ boxSizing: 'border-box',
102
+ border: `3px solid ${palette.misc.altBackground}`,
103
+ borderRadius: '50%'
104
+ } }, { children: _jsx(InsertDriveFileIcon, { sx: {
105
+ width: '18px',
106
+ height: '18px',
107
+ fill: palette.text.tertiary
108
+ } }) })), _jsxs(Box, Object.assign({ sx: { flex: 1 } }, { children: [_jsx(Typography, Object.assign({ sx: {
109
+ fontWeight: 600,
110
+ fontSize: '14px',
111
+ lineHeight: '19px',
112
+ color: palette.text.primary
113
+ } }, { children: file.file.name })), file.isUploaded ? (_jsx(_Fragment, { children: _jsx(Typography, Object.assign({ "data-testid": "file-item-size", sx: {
114
+ marginTop: '1px',
115
+ fontWeight: 400,
116
+ fontSize: '12px',
117
+ lineHeight: '16px',
118
+ color: palette.neutral.main
119
+ } }, { children: (file.file.size / (1024 * 1024)).toFixed(1) + ' MB' })) })) : file.withError ? (_jsxs(_Fragment, { children: [_jsx(Box, Object.assign({ sx: {
120
+ width: '100%',
121
+ height: '4px',
122
+ marginTop: '5px',
123
+ marginBottom: '4px',
124
+ borderRadius: '20px',
125
+ background: palette.misc.altBackground
126
+ } }, { children: _jsx(Box, { sx: {
127
+ width: '100%',
128
+ height: '100%',
129
+ borderRadius: '20px',
130
+ background: palette.error.main
131
+ } }) })), _jsx(Typography, Object.assign({ sx: {
132
+ fontWeight: 600,
133
+ fontSize: '10px',
134
+ lineHeight: '14px',
135
+ color: palette.text.primary
136
+ } }, { children: "File upload error. Please try again." }))] })) : (_jsx(Box, Object.assign({ sx: {
137
+ width: '100%',
138
+ height: '4px',
139
+ marginTop: '5px',
140
+ marginBottom: '4px',
141
+ borderRadius: '20px',
142
+ background: palette.misc.altBackground
143
+ } }, { children: _jsx(Box, { "data-testid": "file-progress-bar", sx: {
144
+ width: `${file.uploadProgress}%`,
145
+ height: '100%',
146
+ borderRadius: '20px',
147
+ background: palette.success.main
148
+ } }) })))] })), _jsx(IconButton, Object.assign({ "data-testid": "file-item-delete-button", "aria-label": "delete", sx: { padding: 0 }, onClick: () => handleDeleteFile(index) }, { children: _jsx(DeleteOutlineIcon, { sx: { width: '18px', height: '18px' } }) }))] }), index));
149
+ })] })));
150
+ };
151
+ export default FileUploader;
@@ -0,0 +1,5 @@
1
+ import { FileData } from '.';
2
+ export declare const useUploadFile: (setfileList: (v: FileData[]) => void, uploadUrl?: string, onSuccess?: ((v: boolean) => void) | undefined, onError?: ((v: Error) => void) | undefined) => {
3
+ onDrop: <T extends File>(acceptedFiles: T[]) => Promise<void>;
4
+ };
5
+ export declare const uploadFile: (uploadUrl: string, file: File, setProgress: (v: number) => void, method?: string) => Promise<import("axios").AxiosResponse<any, any>>;
@@ -0,0 +1,76 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
11
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
12
+ var m = o[Symbol.asyncIterator], i;
13
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
14
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
15
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
16
+ };
17
+ import axios from 'axios';
18
+ import { useCallback } from 'react';
19
+ export const useUploadFile = (setfileList, uploadUrl, onSuccess, onError) => {
20
+ const onDrop = useCallback((acceptedFiles) => __awaiter(void 0, void 0, void 0, function* () {
21
+ var e_1, _a;
22
+ if (!uploadUrl) {
23
+ onError && onError(new Error('upload url is required'));
24
+ return;
25
+ }
26
+ let newList = acceptedFiles.map((file) => ({
27
+ file,
28
+ isUploaded: false,
29
+ uploadProgress: 0,
30
+ withError: false
31
+ }));
32
+ setfileList(newList);
33
+ try {
34
+ for (var _b = __asyncValues(newList.entries()), _c; _c = yield _b.next(), !_c.done;) {
35
+ const [index, file] = _c.value;
36
+ try {
37
+ yield uploadFile(uploadUrl, file.file, (progress) => {
38
+ const nList = [...newList];
39
+ nList.splice(index, 1, Object.assign(Object.assign({}, file), { isUploaded: progress === 100, uploadProgress: progress }));
40
+ newList = nList;
41
+ setfileList(nList);
42
+ });
43
+ onSuccess && onSuccess(true);
44
+ }
45
+ catch (error) {
46
+ const nList = [...newList];
47
+ nList.splice(index, 1, Object.assign(Object.assign({}, file), { isUploaded: false, uploadProgress: 0, withError: true }));
48
+ newList = nList;
49
+ setfileList(nList);
50
+ onError && onError(error);
51
+ }
52
+ }
53
+ }
54
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
55
+ finally {
56
+ try {
57
+ if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);
58
+ }
59
+ finally { if (e_1) throw e_1.error; }
60
+ }
61
+ }), [onError, onSuccess, setfileList, uploadUrl]);
62
+ return { onDrop };
63
+ };
64
+ export const uploadFile = (uploadUrl, file, setProgress, method = 'POST') => {
65
+ const data = new FormData();
66
+ data.append('file', file);
67
+ return axios({
68
+ data,
69
+ method,
70
+ baseURL: uploadUrl,
71
+ onUploadProgress(progressEvent) {
72
+ const { loaded, total } = progressEvent;
73
+ total && setProgress(Math.round((loaded * 100) / total));
74
+ }
75
+ });
76
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veritone-ce/design-system",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "start": "yarn storybook",
@@ -44,10 +44,12 @@
44
44
  "@testing-library/user-event": "^13.2.1",
45
45
  "@types/jest": "^27.0.1",
46
46
  "@types/node": "^16.7.13",
47
+ "axios": "^1.2.1",
47
48
  "cz-conventional-changelog": "^3.3.0",
48
49
  "husky": "^8.0.2",
49
50
  "react": "^18.2.0",
50
51
  "react-dom": "^18.2.0",
52
+ "react-dropzone": "^14.2.3",
51
53
  "react-scripts": "5.0.1",
52
54
  "typescript": "^4.4.2",
53
55
  "web-vitals": "^2.1.0"