mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 18:56:00 +00:00
cloud file, folder operations
This commit is contained in:
@@ -15,6 +15,7 @@ const { recryptConnection, getInternalEncryptor, encryptConnection } = require('
|
|||||||
const { getConnectionLabel, getLogger, extractErrorLogData } = require('dbgate-tools');
|
const { getConnectionLabel, getLogger, extractErrorLogData } = require('dbgate-tools');
|
||||||
const logger = getLogger('cloud');
|
const logger = getLogger('cloud');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
publicFiles_meta: true,
|
publicFiles_meta: true,
|
||||||
@@ -205,6 +206,22 @@ module.exports = {
|
|||||||
return resp;
|
return resp;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deleteContent_meta: true,
|
||||||
|
async deleteContent({ folid, cntid }) {
|
||||||
|
const resp = await callCloudApiPost(`content/delete/${folid}/${cntid}`);
|
||||||
|
socket.emitChanged('cloud-content-changed');
|
||||||
|
socket.emit('cloud-content-updated');
|
||||||
|
return resp;
|
||||||
|
},
|
||||||
|
|
||||||
|
renameContent_meta: true,
|
||||||
|
async renameContent({ folid, cntid, name }) {
|
||||||
|
const resp = await callCloudApiPost(`content/rename/${folid}/${cntid}`, { name });
|
||||||
|
socket.emitChanged('cloud-content-changed');
|
||||||
|
socket.emit('cloud-content-updated');
|
||||||
|
return resp;
|
||||||
|
},
|
||||||
|
|
||||||
saveFile_meta: true,
|
saveFile_meta: true,
|
||||||
async saveFile({ folid, cntid, fileName, data, contentFolder, format }) {
|
async saveFile({ folid, cntid, fileName, data, contentFolder, format }) {
|
||||||
const resp = await putCloudContent(folid, cntid, data, fileName, 'file', contentFolder, format);
|
const resp = await putCloudContent(folid, cntid, data, fileName, 'file', contentFolder, format);
|
||||||
@@ -212,4 +229,22 @@ module.exports = {
|
|||||||
socket.emit('cloud-content-updated');
|
socket.emit('cloud-content-updated');
|
||||||
return resp;
|
return resp;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
copyFile_meta: true,
|
||||||
|
async copyFile({ folid, cntid, name }) {
|
||||||
|
const resp = await callCloudApiPost(`content/duplicate/${folid}/${cntid}`, { name });
|
||||||
|
socket.emitChanged('cloud-content-changed');
|
||||||
|
socket.emit('cloud-content-updated');
|
||||||
|
return resp;
|
||||||
|
},
|
||||||
|
|
||||||
|
exportFile_meta: true,
|
||||||
|
async exportFile({ folid, cntid, filePath }, req) {
|
||||||
|
const { content } = await getCloudContent(folid, cntid);
|
||||||
|
if (!content) {
|
||||||
|
throw new Error('File not found');
|
||||||
|
}
|
||||||
|
await fs.writeFile(filePath, content);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -262,11 +262,15 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleDuplicate = () => {
|
const handleDuplicate = () => {
|
||||||
|
if (data._id.startsWith('cloud://')) {
|
||||||
|
apiCall('cloud/duplicate-connection', { conid: data._id });
|
||||||
|
} else {
|
||||||
apiCall('connections/save', {
|
apiCall('connections/save', {
|
||||||
...data,
|
...data,
|
||||||
_id: undefined,
|
_id: undefined,
|
||||||
displayName: `${getConnectionLabel(data)} - copy`,
|
displayName: `${getConnectionLabel(data)} - copy`,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const handleCreateDatabase = () => {
|
const handleCreateDatabase = () => {
|
||||||
showModal(InputTextModal, {
|
showModal(InputTextModal, {
|
||||||
|
|||||||
@@ -206,7 +206,14 @@
|
|||||||
showModal(ConfirmModal, {
|
showModal(ConfirmModal, {
|
||||||
message: `Really delete file ${data.file}?`,
|
message: `Really delete file ${data.file}?`,
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
|
if (data.folid && data.cntid) {
|
||||||
|
apiCall('cloud/delete-content', {
|
||||||
|
folid: data.folid,
|
||||||
|
cntid: data.cntid,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
apiCall('files/delete', data);
|
apiCall('files/delete', data);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -217,7 +224,15 @@
|
|||||||
label: 'New file name',
|
label: 'New file name',
|
||||||
header: 'Rename file',
|
header: 'Rename file',
|
||||||
onConfirm: newFile => {
|
onConfirm: newFile => {
|
||||||
|
if (data.folid && data.cntid) {
|
||||||
|
apiCall('cloud/rename-content', {
|
||||||
|
folid: data.folid,
|
||||||
|
cntid: data.cntid,
|
||||||
|
name: newFile,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
apiCall('files/rename', { ...data, newFile });
|
apiCall('files/rename', { ...data, newFile });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -226,9 +241,17 @@
|
|||||||
showModal(InputTextModal, {
|
showModal(InputTextModal, {
|
||||||
value: data.file,
|
value: data.file,
|
||||||
label: 'New file name',
|
label: 'New file name',
|
||||||
header: 'Rename file',
|
header: 'Copy file',
|
||||||
onConfirm: newFile => {
|
onConfirm: newFile => {
|
||||||
|
if (data.folid && data.cntid) {
|
||||||
|
apiCall('cloud/copy-file', {
|
||||||
|
folid: data.folid,
|
||||||
|
cntid: data.cntid,
|
||||||
|
name: newFile,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
apiCall('files/copy', { ...data, newFile });
|
apiCall('files/copy', { ...data, newFile });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -236,11 +259,19 @@
|
|||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
saveFileToDisk(
|
saveFileToDisk(
|
||||||
async filePath => {
|
async filePath => {
|
||||||
|
if (data.folid && data.cntid) {
|
||||||
|
await apiCall('cloud/export-file', {
|
||||||
|
folid: data.folid,
|
||||||
|
cntid: data.cntid,
|
||||||
|
filePath,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
await apiCall('files/export-file', {
|
await apiCall('files/export-file', {
|
||||||
folder,
|
folder,
|
||||||
file: data.file,
|
file: data.file,
|
||||||
filePath,
|
filePath,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ formatLabel: handler.label, formatExtension: handler.format, defaultFileName: data.file }
|
{ formatLabel: handler.label, formatExtension: handler.format, defaultFileName: data.file }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
import getElectron from '../utility/getElectron';
|
import getElectron from '../utility/getElectron';
|
||||||
import ChooseCloudFolderModal from './ChooseCloudFolderModal.svelte';
|
|
||||||
import ModalBase from './ModalBase.svelte';
|
import ModalBase from './ModalBase.svelte';
|
||||||
import { closeCurrentModal, showModal } from './modalTools';
|
import { closeCurrentModal, showModal } from './modalTools';
|
||||||
import FormCloudFolderSelect from '../forms/FormCloudFolderSelect.svelte';
|
import FormCloudFolderSelect from '../forms/FormCloudFolderSelect.svelte';
|
||||||
@@ -22,8 +21,10 @@
|
|||||||
export let fileExtension;
|
export let fileExtension;
|
||||||
export let filePath;
|
export let filePath;
|
||||||
export let onSave = undefined;
|
export let onSave = undefined;
|
||||||
|
export let folid;
|
||||||
|
// export let cntid;
|
||||||
|
|
||||||
const values = writable({ name, cloudFolder: '__local' });
|
const values = writable({ name, cloudFolder: folid ?? '__local' });
|
||||||
|
|
||||||
const electron = getElectron();
|
const electron = getElectron();
|
||||||
|
|
||||||
@@ -37,6 +38,8 @@
|
|||||||
savedFile: name,
|
savedFile: name,
|
||||||
savedFolder: folder,
|
savedFolder: folder,
|
||||||
savedFilePath: null,
|
savedFilePath: null,
|
||||||
|
savedCloudFolderId: null,
|
||||||
|
savedCloudContentId: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -46,6 +49,7 @@
|
|||||||
data,
|
data,
|
||||||
contentFolder: folder,
|
contentFolder: folder,
|
||||||
format,
|
format,
|
||||||
|
// cntid,
|
||||||
});
|
});
|
||||||
if (resp.cntid) {
|
if (resp.cntid) {
|
||||||
closeCurrentModal();
|
closeCurrentModal();
|
||||||
@@ -55,7 +59,7 @@
|
|||||||
savedFolder: folder,
|
savedFolder: folder,
|
||||||
savedFilePath: null,
|
savedFilePath: null,
|
||||||
savedCloudFolderId: cloudFolder,
|
savedCloudFolderId: cloudFolder,
|
||||||
savedCloudContentId: resp.cntid,
|
// savedCloudContentId: resp.cntid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +79,8 @@
|
|||||||
savedFile: null,
|
savedFile: null,
|
||||||
savedFolder: null,
|
savedFolder: null,
|
||||||
savedFilePath: filePath,
|
savedFilePath: filePath,
|
||||||
|
savedCloudFolderId: null,
|
||||||
|
savedCloudContentId: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -47,5 +47,11 @@ export function installCloudListeners() {
|
|||||||
ensureCloudConnectionsLoaded(...conids);
|
ensureCloudConnectionsLoaded(...conids);
|
||||||
});
|
});
|
||||||
|
|
||||||
apiOn('cloud-content-updated', () => cloudConnectionsStore.set({}));
|
apiOn('cloud-content-updated', () => {
|
||||||
|
const conids = Object.keys(getCloudConnectionsStore());
|
||||||
|
cloudConnectionsStore.set({});
|
||||||
|
for (const conn of conids) {
|
||||||
|
loadCloudConnection(conn);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ async function openSavedElectronFile(filePath, parsed, folder) {
|
|||||||
props: {
|
props: {
|
||||||
savedFile: null,
|
savedFile: null,
|
||||||
savedFolder: null,
|
savedFolder: null,
|
||||||
|
savedCloudFolderId: null,
|
||||||
|
savedCloudContentId: null,
|
||||||
savedFilePath: filePath,
|
savedFilePath: filePath,
|
||||||
savedFormat: handler.format,
|
savedFormat: handler.format,
|
||||||
...connProps,
|
...connProps,
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ export default async function openNewTab(newTab, initialData: any = undefined, o
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { savedFile, savedFolder, savedFilePath, conid, database } = newTab.props || {};
|
const { savedFile, savedFolder, savedFilePath, savedCloudFolderId, savedCloudContentId, conid, database } =
|
||||||
|
newTab.props || {};
|
||||||
|
|
||||||
if (conid && database) {
|
if (conid && database) {
|
||||||
const connection = await getConnectionInfo({ conid });
|
const connection = await getConnectionInfo({ conid });
|
||||||
@@ -49,7 +50,9 @@ export default async function openNewTab(newTab, initialData: any = undefined, o
|
|||||||
x.closedTime == null &&
|
x.closedTime == null &&
|
||||||
x.props.savedFile == savedFile &&
|
x.props.savedFile == savedFile &&
|
||||||
x.props.savedFolder == savedFolder &&
|
x.props.savedFolder == savedFolder &&
|
||||||
x.props.savedFilePath == savedFilePath
|
x.props.savedFilePath == savedFilePath &&
|
||||||
|
x.props.savedCloudFolderId == savedCloudFolderId &&
|
||||||
|
x.props.savedCloudContentId == savedCloudContentId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,23 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
|
|||||||
const tabs = get(openedTabs);
|
const tabs = get(openedTabs);
|
||||||
const tabid = editor.activator.tabid;
|
const tabid = editor.activator.tabid;
|
||||||
const data = editor.getData();
|
const data = editor.getData();
|
||||||
const { savedFile, savedFilePath, savedFolder } = tabs.find(x => x.tabid == tabid).props || {};
|
const { savedFile, savedFilePath, savedFolder, savedCloudFolderId, savedCloudContentId } =
|
||||||
|
tabs.find(x => x.tabid == tabid).props || {};
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
|
if (savedCloudFolderId && savedCloudContentId) {
|
||||||
|
const resp = await apiCall('cloud/save-file', {
|
||||||
|
folid: savedCloudFolderId,
|
||||||
|
fileName: savedFile,
|
||||||
|
data,
|
||||||
|
contentFolder: folder,
|
||||||
|
format,
|
||||||
|
cntid: savedCloudContentId,
|
||||||
|
});
|
||||||
|
if (resp.cntid) {
|
||||||
|
markTabSaved(tabid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (savedFile) {
|
if (savedFile) {
|
||||||
await apiCall('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
|
await apiCall('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
|
||||||
}
|
}
|
||||||
@@ -25,6 +39,7 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
|
|||||||
await apiCall('files/save-as', { filePath: savedFilePath, data, format });
|
await apiCall('files/save-as', { filePath: savedFilePath, data, format });
|
||||||
}
|
}
|
||||||
markTabSaved(tabid);
|
markTabSaved(tabid);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSave = (title, newProps) => {
|
const onSave = (title, newProps) => {
|
||||||
@@ -60,6 +75,8 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
|
|||||||
savedFile: null,
|
savedFile: null,
|
||||||
savedFolder: null,
|
savedFolder: null,
|
||||||
savedFilePath: file,
|
savedFilePath: file,
|
||||||
|
savedCloudFolderId: null,
|
||||||
|
savedCloudContentId: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if ((savedFile || savedFilePath) && saveMode == 'save') {
|
} else if ((savedFile || savedFilePath) && saveMode == 'save') {
|
||||||
@@ -73,6 +90,8 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
|
|||||||
name: savedFile || 'newFile',
|
name: savedFile || 'newFile',
|
||||||
filePath: savedFilePath,
|
filePath: savedFilePath,
|
||||||
onSave,
|
onSave,
|
||||||
|
folid: savedCloudFolderId,
|
||||||
|
// cntid: savedCloudContentId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
const serverStatus = useServerStatus();
|
const serverStatus = useServerStatus();
|
||||||
|
|
||||||
$: emptyCloudContent = ($cloudContentList || []).filter(x => !x.items?.length).map(x => x.folid);
|
$: emptyCloudContent = ($cloudContentList || []).filter(x => !x.items?.length).map(x => x.folid);
|
||||||
$: cloudContentFlat = ($cloudContentList || [])
|
$: cloudContentFlat = _.sortBy(
|
||||||
|
($cloudContentList || [])
|
||||||
.flatMap(fld => fld.items ?? [])
|
.flatMap(fld => fld.items ?? [])
|
||||||
.map(data => {
|
.map(data => {
|
||||||
if (data.type == 'connection') {
|
if (data.type == 'connection') {
|
||||||
@@ -56,7 +57,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
});
|
}),
|
||||||
|
'name'
|
||||||
|
);
|
||||||
$: contentGroupMap = _.keyBy($cloudContentList || [], x => x.folid);
|
$: contentGroupMap = _.keyBy($cloudContentList || [], x => x.folid);
|
||||||
|
|
||||||
// $: console.log('cloudContentFlat', cloudContentFlat);
|
// $: console.log('cloudContentFlat', cloudContentFlat);
|
||||||
|
|||||||
Reference in New Issue
Block a user