D & D CSV files

This commit is contained in:
Jan Prochazka
2021-03-13 20:28:06 +01:00
parent 834eeabd3f
commit 500c1c76ba
9 changed files with 322 additions and 8 deletions

View File

@@ -0,0 +1,86 @@
import _ from 'lodash';
import { isFileDragActive } from '../stores';
import { fromEvent } from 'file-selector';
import uploadFiles from './uploadFiles';
function isEvtWithFiles(event) {
if (!event.dataTransfer) {
return !!event.target && !!event.target.files;
}
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file
return Array.prototype.some.call(
event.dataTransfer.types,
type => type === 'Files' || type === 'application/x-moz-file'
);
}
export default function dragDropFileTarget(node, items) {
let dragTargetsRef = [];
function handleDragEnter(event) {
event.preventDefault();
event.stopPropagation();
dragTargetsRef = [...dragTargetsRef, event.target];
if (isEvtWithFiles(event)) {
isFileDragActive.set(true);
}
return false;
}
function handleDragOver(event) {
event.preventDefault();
event.stopPropagation();
if (event.dataTransfer) {
try {
event.dataTransfer.dropEffect = 'copy';
} catch {}
}
}
function handleDragLeave(event) {
event.preventDefault();
event.stopPropagation();
// Only deactivate once the dropzone and all children have been left
const targets = dragTargetsRef.filter(target => node && node.contains(target));
// Make sure to remove a target present multiple times only once
// (Firefox may fire dragenter/dragleave multiple times on the same element)
const targetIdx = targets.indexOf(event.target);
if (targetIdx !== -1) {
targets.splice(targetIdx, 1);
}
dragTargetsRef = targets;
if (targets.length > 0) {
return;
}
isFileDragActive.set(false);
}
async function handleDrop(event) {
event.preventDefault();
event.stopPropagation();
isFileDragActive.set(false);
if (isEvtWithFiles(event)) {
const files = await fromEvent(event);
uploadFiles(files);
}
}
node.addEventListener('dragenter', handleDragEnter);
node.addEventListener('dragover', handleDragOver);
node.addEventListener('dragleave', handleDragLeave);
node.addEventListener('drop', handleDrop);
return {
destroy() {
node.removeEventListener('dragenter', handleDragEnter);
node.removeEventListener('dragover', handleDragOver);
node.removeEventListener('dragleave', handleDragLeave);
node.removeEventListener('drop', handleDrop);
},
};
}

View File

@@ -0,0 +1,47 @@
import { showModal } from '../modals/modalTools';
import newQuery from '../query/newQuery';
import ImportExportModal from '../modals/ImportExportModal.svelte';
export function canOpenByElectron(file, extensions) {
if (!file) return false;
const nameLower = file.toLowerCase();
if (nameLower.endsWith('.sql')) return true;
for (const format of extensions.fileFormats) {
if (nameLower.endsWith(`.${format.extension}`)) return true;
}
return false;
}
export function openElectronFileCore(filePath, extensions) {
const nameLower = filePath.toLowerCase();
const path = window.require('path');
const fs = window.require('fs');
const parsed = path.parse(filePath);
if (nameLower.endsWith('.sql')) {
const data = fs.readFileSync(filePath, { encoding: 'utf-8' });
newQuery({
title: parsed.name,
initialData: data,
// @ts-ignore
savedFilePath: filePath,
savedFormat: 'text',
});
}
for (const format of extensions.fileFormats) {
if (nameLower.endsWith(`.${format.extension}`)) {
showModal(ImportExportModal, {
openedFile: {
filePath,
storageType: format.storageType,
shortName: parsed.name,
},
importToArchive: true,
initialValues: {
sourceStorageType: format.storageType,
},
});
}
}
}

View File

@@ -0,0 +1,78 @@
import { extensions } from '../stores';
import { get } from 'svelte/store';
import { canOpenByElectron, openElectronFileCore } from './openElectronFile';
import getElectron from './getElectron';
import resolveApi from './resolveApi';
import { findFileFormat } from '../plugins/fileformats';
import { showModal } from '../modals/modalTools';
import ImportExportModal from '../modals/ImportExportModal.svelte';
let uploadListener;
export function setUploadListener(value) {
uploadListener = value;
}
export default function uploadFiles(files) {
const ext = get(extensions);
const electron = getElectron();
files.forEach(async file => {
if (parseInt(file.size, 10) >= 4 * 1024 * 1024) {
// to big file
return;
}
console.log('FILE', file);
if (electron && canOpenByElectron(file.path, ext)) {
openElectronFileCore(file.path, ext);
return;
}
const formData = new FormData();
formData.append('data', file);
const fetchOptions = {
method: 'POST',
body: formData,
};
const apiBase = resolveApi();
const resp = await fetch(`${apiBase}/uploads/upload`, fetchOptions);
const fileData = await resp.json();
fileData.shortName = file.name;
for (const format of ext.fileFormats) {
if (file.name.endsWith('.' + format.extension)) {
fileData.shortName = file.name.slice(0, -format.extension.length - 1);
fileData.storageType = format.storageType;
}
}
if (uploadListener) {
uploadListener(fileData);
} else {
if (findFileFormat(ext, fileData.storageType)) {
showModal(ImportExportModal, {
uploadedFile: fileData,
importToArchive: true,
initialValues: {
sourceStorageType: fileData.storageType,
},
});
}
}
// const reader = new FileReader();
// reader.onabort = () => console.log('file reading was aborted');
// reader.onerror = () => console.log('file reading has failed');
// reader.onload = () => {
// // Do whatever you want with the file contents
// const binaryStr = reader.result;
// console.log(binaryStr);
// };
// reader.readAsArrayBuffer(file);
});
}