mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-21 12:56:00 +00:00
D & D CSV files
This commit is contained in:
86
packages/web/src/utility/dragDropFileTarget.ts
Normal file
86
packages/web/src/utility/dragDropFileTarget.ts
Normal 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);
|
||||
},
|
||||
};
|
||||
}
|
||||
47
packages/web/src/utility/openElectronFile.ts
Normal file
47
packages/web/src/utility/openElectronFile.ts
Normal 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,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
78
packages/web/src/utility/uploadFiles.ts
Normal file
78
packages/web/src/utility/uploadFiles.ts
Normal 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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user