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 logger = getLogger('cloud');
const _ = require('lodash');
const fs = require('fs-extra');
module.exports = {
publicFiles_meta: true,
@@ -205,6 +206,22 @@ module.exports = {
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,
async saveFile({ folid, cntid, fileName, data, contentFolder, format }) {
const resp = await putCloudContent(folid, cntid, data, fileName, 'file', contentFolder, format);
@@ -212,4 +229,22 @@ module.exports = {
socket.emit('cloud-content-updated');
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 = () => {
apiCall('connections/save', {
...data,
_id: undefined,
displayName: `${getConnectionLabel(data)} - copy`,
});
if (data._id.startsWith('cloud://')) {
apiCall('cloud/duplicate-connection', { conid: data._id });
} else {
apiCall('connections/save', {
...data,
_id: undefined,
displayName: `${getConnectionLabel(data)} - copy`,
});
}
};
const handleCreateDatabase = () => {
showModal(InputTextModal, {

View File

@@ -206,7 +206,14 @@
showModal(ConfirmModal, {
message: `Really delete file ${data.file}?`,
onConfirm: () => {
apiCall('files/delete', data);
if (data.folid && data.cntid) {
apiCall('cloud/delete-content', {
folid: data.folid,
cntid: data.cntid,
});
} else {
apiCall('files/delete', data);
}
},
});
};
@@ -217,7 +224,15 @@
label: 'New file name',
header: 'Rename file',
onConfirm: newFile => {
apiCall('files/rename', { ...data, newFile });
if (data.folid && data.cntid) {
apiCall('cloud/rename-content', {
folid: data.folid,
cntid: data.cntid,
name: newFile,
});
} else {
apiCall('files/rename', { ...data, newFile });
}
},
});
};
@@ -226,9 +241,17 @@
showModal(InputTextModal, {
value: data.file,
label: 'New file name',
header: 'Rename file',
header: 'Copy file',
onConfirm: newFile => {
apiCall('files/copy', { ...data, newFile });
if (data.folid && data.cntid) {
apiCall('cloud/copy-file', {
folid: data.folid,
cntid: data.cntid,
name: newFile,
});
} else {
apiCall('files/copy', { ...data, newFile });
}
},
});
};
@@ -236,11 +259,19 @@
const handleDownload = () => {
saveFileToDisk(
async filePath => {
await apiCall('files/export-file', {
folder,
file: data.file,
filePath,
});
if (data.folid && data.cntid) {
await apiCall('cloud/export-file', {
folid: data.folid,
cntid: data.cntid,
filePath,
});
} else {
await apiCall('files/export-file', {
folder,
file: data.file,
filePath,
});
}
},
{ formatLabel: handler.label, formatExtension: handler.format, defaultFileName: data.file }
);

View File

@@ -10,7 +10,6 @@
import { writable } from 'svelte/store';
import getElectron from '../utility/getElectron';
import ChooseCloudFolderModal from './ChooseCloudFolderModal.svelte';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal, showModal } from './modalTools';
import FormCloudFolderSelect from '../forms/FormCloudFolderSelect.svelte';
@@ -22,8 +21,10 @@
export let fileExtension;
export let filePath;
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();
@@ -37,6 +38,8 @@
savedFile: name,
savedFolder: folder,
savedFilePath: null,
savedCloudFolderId: null,
savedCloudContentId: null,
});
}
} else {
@@ -46,6 +49,7 @@
data,
contentFolder: folder,
format,
// cntid,
});
if (resp.cntid) {
closeCurrentModal();
@@ -55,7 +59,7 @@
savedFolder: folder,
savedFilePath: null,
savedCloudFolderId: cloudFolder,
savedCloudContentId: resp.cntid,
// savedCloudContentId: resp.cntid,
});
}
}
@@ -75,6 +79,8 @@
savedFile: null,
savedFolder: null,
savedFilePath: filePath,
savedCloudFolderId: null,
savedCloudContentId: null,
});
}
};

View File

@@ -47,5 +47,11 @@ export function installCloudListeners() {
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: {
savedFile: null,
savedFolder: null,
savedCloudFolderId: null,
savedCloudContentId: null,
savedFilePath: filePath,
savedFormat: handler.format,
...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) {
const connection = await getConnectionInfo({ conid });
@@ -49,7 +50,9 @@ export default async function openNewTab(newTab, initialData: any = undefined, o
x.closedTime == null &&
x.props.savedFile == savedFile &&
x.props.savedFolder == savedFolder &&
x.props.savedFilePath == savedFilePath
x.props.savedFilePath == savedFilePath &&
x.props.savedCloudFolderId == savedCloudFolderId &&
x.props.savedCloudContentId == savedCloudContentId
);
}

View File

@@ -15,16 +15,31 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
const tabs = get(openedTabs);
const tabid = editor.activator.tabid;
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 () => {
if (savedFile) {
await apiCall('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
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) {
await apiCall('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
}
if (savedFilePath) {
await apiCall('files/save-as', { filePath: savedFilePath, data, format });
}
markTabSaved(tabid);
}
if (savedFilePath) {
await apiCall('files/save-as', { filePath: savedFilePath, data, format });
}
markTabSaved(tabid);
};
const onSave = (title, newProps) => {
@@ -60,6 +75,8 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
savedFile: null,
savedFolder: null,
savedFilePath: file,
savedCloudFolderId: null,
savedCloudContentId: null,
});
}
} else if ((savedFile || savedFilePath) && saveMode == 'save') {
@@ -73,6 +90,8 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
name: savedFile || 'newFile',
filePath: savedFilePath,
onSave,
folid: savedCloudFolderId,
// cntid: savedCloudContentId,
});
}
}

View File

@@ -41,22 +41,25 @@
const serverStatus = useServerStatus();
$: emptyCloudContent = ($cloudContentList || []).filter(x => !x.items?.length).map(x => x.folid);
$: cloudContentFlat = ($cloudContentList || [])
.flatMap(fld => fld.items ?? [])
.map(data => {
if (data.type == 'connection') {
const conid = `cloud://${data.folid}/${data.cntid}`;
const status = $serverStatus ? $serverStatus[$volatileConnectionMapStore[conid] || conid] : undefined;
$: cloudContentFlat = _.sortBy(
($cloudContentList || [])
.flatMap(fld => fld.items ?? [])
.map(data => {
if (data.type == 'connection') {
const conid = `cloud://${data.folid}/${data.cntid}`;
const status = $serverStatus ? $serverStatus[$volatileConnectionMapStore[conid] || conid] : undefined;
return {
...data,
conid,
status,
};
}
return {
...data,
conid,
status,
};
}
return data;
});
return data;
}),
'name'
);
$: contentGroupMap = _.keyBy($cloudContentList || [], x => x.folid);
// $: console.log('cloudContentFlat', cloudContentFlat);