@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
JavaScript
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;