cloud file, folder operations

This commit is contained in:
SPRINX0\prochazka
2025-05-28 10:46:35 +02:00
parent 741b942dea
commit 7b50a19b2c
9 changed files with 150 additions and 41 deletions

View File

@@ -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;
},
}; };

View File

@@ -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, {

View File

@@ -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 }
); );

View 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,
}); });
} }
}; };

View File

@@ -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);
}
});
} }

View File

@@ -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,

View File

@@ -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
); );
} }

View File

@@ -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,
}); });
} }
} }

View File

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