UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

112 lines (111 loc) 4.98 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useReducer, useRef } from 'react'; import join from '../../components/utils/join'; import contains from '../../components/utils/contains'; import SimpleButton from '../SimpleButton'; import { Icon } from '../icons'; import HelpBlock from '../HelpBlock'; import reducer, { ActionTypes } from './reducer'; import { Box, Flex } from '../Flex'; const initialState = { dragOver: false, message: null, }; const preventEventPropagation = (e) => { e.preventDefault(); e.stopPropagation(); }; export const readJSONFile = async (file, toJSON) => { const reader = new FileReader(); return new Promise((resolve, reject) => { reader.onload = function (e) { try { const fn = toJSON || JSON.parse; const json = fn(e.target.result); Promise.resolve(json).then(resolve); } catch (ex) { reject('Invalid JSON'); } }; reader.onerror = function (e) { reject(e); }; reader.readAsText(file); }); }; const FileDroppable = (props = {}) => { const { onDropSuccess, message, fileAccept = '.json', helpText = 'AdapTable No Code Version', defaultText = 'Click here to select a JSON file to load or drag it here', dragOverText = 'Drop file here to start Adaptable Wizard', icon = _jsx(Icon, { name: "paperclip", size: 40 }), value, ...domProps } = props; const [state, dispatch] = useReducer(reducer, initialState); const onDragEnter = (e) => { dispatch({ type: ActionTypes.DRAG_OVER, }); }; const onDragLeave = (event) => { preventEventPropagation(event); if (domRef.current != event.target && contains(domRef.current, event.target)) { return; } dispatch({ type: ActionTypes.DRAG_OUT, }); }; const onDrop = async (e) => { let files; preventEventPropagation(e); let nativeEvent = e.nativeEvent; if (nativeEvent && nativeEvent.dataTransfer) { files = nativeEvent.dataTransfer.files; } else { files = e.target.files; } onDragLeave(e); const file = files[0]; if (file) { let json; try { json = await (props.readFile || readJSONFile)(file, props.toJSON); dispatch({ type: ActionTypes.DROP_SUCCES, payload: { message: (_jsx(Box, { children: props.loadingText === undefined ? 'Initializing adaptable...' : props.loadingText })), }, }); requestAnimationFrame(() => { requestAnimationFrame(() => { if (onDropSuccess) { onDropSuccess(json, file); } }); }); } catch (err) { dispatch({ type: ActionTypes.SET_INVALID_FILE, payload: { message: _jsx(Box, { children: 'The file is not a valid JSON file! Please try again!' }), }, }); } } }; const domRef = useRef(null); let form = (_jsx("form", { onSubmit: preventEventPropagation, children: _jsxs(SimpleButton, { style: { cursor: 'pointer' }, variant: "outlined", children: [_jsx("div", { children: state.dragOver ? dragOverText : defaultText }), _jsx("input", { type: "file", onChange: onDrop, accept: fileAccept, value: props?.file?.name, style: { opacity: 0, position: 'absolute', cursor: 'pointer', fontSize: 0, lineHeight: 0, top: 0, left: 0, width: '100%', height: '100%', zIndex: 1, } })] }) })); const msg = message || state.message; return (_jsxs(Flex, { ...domProps, flexDirection: "column", className: join(props.className, 'ab-FileDroppable', state.dragOver ? 'ab-FileDroppable--drag-over' : ''), alignItems: "center", justifyContent: "center", onDragEnter: onDragEnter, onDragLeave: onDragLeave, onDrop: onDrop, onDragOver: preventEventPropagation, ref: domRef, children: [props.children, helpText || icon ? (_jsxs(Flex, { flexDirection: "column", children: [helpText ? (_jsx(Flex, { flexDirection: "column", alignItems: "center", className: "twa:m-2", children: _jsx(HelpBlock, { children: _jsx("b", { children: helpText }) }) })) : null, icon ? (_jsx(Flex, { flexDirection: "column", alignItems: "center", className: "twa:m-2", children: icon })) : null] })) : null, msg, form] })); }; export default FileDroppable;