diff --git a/packages/api/src/controllers/archive.js b/packages/api/src/controllers/archive.js
index 39506a663..c1b38c3f2 100644
--- a/packages/api/src/controllers/archive.js
+++ b/packages/api/src/controllers/archive.js
@@ -38,12 +38,25 @@ module.exports = {
const dir = path.join(archivedir(), folder);
if (!(await fs.exists(dir))) return [];
const files = await fs.readdir(dir);
- return files
- .filter(name => name.endsWith('.jsonl'))
- .map(name => ({
- name: name.slice(0, -'.jsonl'.length),
- type: 'jsonl',
- }));
+
+ function fileType(ext, type) {
+ return files
+ .filter(name => name.endsWith(ext))
+ .map(name => ({
+ name: name.slice(0, -ext.length),
+ type,
+ }));
+ }
+
+ return [
+ ...fileType('.jsonl', 'jsonl'),
+ ...fileType('.table.yaml', 'table.yaml'),
+ ...fileType('.view.sql', 'view.sql'),
+ ...fileType('.proc.sql', 'proc.sql'),
+ ...fileType('.func.sql', 'func.sql'),
+ ...fileType('.trigger.sql', 'trigger.sql'),
+ ...fileType('.matview.sql', 'matview.sql'),
+ ];
},
refreshFiles_meta: 'post',
diff --git a/packages/api/src/controllers/files.js b/packages/api/src/controllers/files.js
index ad3e91cb2..c080c8445 100644
--- a/packages/api/src/controllers/files.js
+++ b/packages/api/src/controllers/files.js
@@ -1,6 +1,6 @@
const fs = require('fs-extra');
const path = require('path');
-const { filesdir } = require('../utility/directories');
+const { filesdir, archivedir } = require('../utility/directories');
const hasPermission = require('../utility/hasPermission');
const socket = require('../utility/socket');
const scheduler = require('./scheduler');
@@ -58,23 +58,36 @@ module.exports = {
load_meta: 'post',
async load({ folder, file, format }) {
- if (!hasPermission(`files/${folder}/read`)) return null;
- const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
- return deserialize(format, text);
+ if (folder.startsWith('archive:')) {
+ const text = await fs.readFile(path.join(archivedir(), folder.substring('archive:'.length), file), {
+ encoding: 'utf-8',
+ });
+ return deserialize(format, text);
+ } else {
+ if (!hasPermission(`files/${folder}/read`)) return null;
+ const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
+ return deserialize(format, text);
+ }
},
save_meta: 'post',
async save({ folder, file, data, format }) {
- if (!hasPermission(`files/${folder}/write`)) return;
- const dir = path.join(filesdir(), folder);
- if (!(await fs.exists(dir))) {
- await fs.mkdir(dir);
- }
- await fs.writeFile(path.join(dir, file), serialize(format, data));
- socket.emitChanged(`files-changed-${folder}`);
- socket.emitChanged(`all-files-changed`);
- if (folder == 'shell') {
- scheduler.reload();
+ if (folder.startsWith('archive:')) {
+ const dir = path.join(archivedir(), folder.substring('archive:'.length));
+ await fs.writeFile(path.join(dir, file), serialize(format, data));
+ socket.emitChanged(`archive-files-changed-${folder.substring('archive:'.length)}`);
+ } else {
+ if (!hasPermission(`files/${folder}/write`)) return;
+ const dir = path.join(filesdir(), folder);
+ if (!(await fs.exists(dir))) {
+ await fs.mkdir(dir);
+ }
+ await fs.writeFile(path.join(dir, file), serialize(format, data));
+ socket.emitChanged(`files-changed-${folder}`);
+ socket.emitChanged(`all-files-changed`);
+ if (folder == 'shell') {
+ scheduler.reload();
+ }
}
},
diff --git a/packages/web/src/appobj/ArchiveFileAppObject.svelte b/packages/web/src/appobj/ArchiveFileAppObject.svelte
index 35cd5f07b..c563c0307 100644
--- a/packages/web/src/appobj/ArchiveFileAppObject.svelte
+++ b/packages/web/src/appobj/ArchiveFileAppObject.svelte
@@ -12,23 +12,66 @@
});
}
+ async function openSqlFile(fileName, fileType, folderName) {
+ const connProps: any = {};
+ let tooltip = undefined;
+
+ const connection = _.get(getCurrentDatabase(), 'connection') || {};
+ const database = _.get(getCurrentDatabase(), 'name');
+ connProps.conid = connection._id;
+ connProps.database = database;
+ tooltip = `${getConnectionLabel(connection)}\n${database}`;
+ const resp = await axiosInstance.post('files/load', {
+ folder: 'archive:' + folderName,
+ file: fileName + '.' + fileType,
+ format: 'text',
+ });
+
+ openNewTab(
+ {
+ title: fileName,
+ icon: 'img sql-file',
+ tabComponent: 'QueryTab',
+ tooltip,
+ props: {
+ savedFile: fileName + '.' + fileType,
+ savedFolder: 'archive:' + folderName,
+ savedFormat: 'text',
+ ...connProps,
+ },
+ },
+ { editor: resp.data }
+ );
+ }
+
export const extractKey = data => data.fileName;
export const createMatcher = ({ fileName }) => filter => filterName(filter, fileName);
-
+ const ARCHIVE_ICONS = {
+ jsonl: 'img archive',
+ 'table.yaml': 'img table',
+ 'view.sql': 'img view',
+ 'proce.sql': 'img procedure',
+ 'func.sql': 'img function',
+ 'trigger.sql': 'img sql-file',
+ 'matview.sql': 'img view',
+ };
diff --git a/packages/web/src/utility/saveTabFile.ts b/packages/web/src/utility/saveTabFile.ts
index b2410a0ad..c04599c64 100644
--- a/packages/web/src/utility/saveTabFile.ts
+++ b/packages/web/src/utility/saveTabFile.ts
@@ -14,11 +14,11 @@ export default function saveTabFile(editor, saveAs, folder, format, fileExtensio
const tabs = get(openedTabs);
const tabid = editor.activator.tabid;
const data = editor.getData();
- const { savedFile, savedFilePath } = tabs.find(x => x.tabid == tabid).props || {};
+ const { savedFile, savedFilePath, savedFolder } = tabs.find(x => x.tabid == tabid).props || {};
const handleSave = async () => {
if (savedFile) {
- await axiosInstance.post('files/save', { folder, file: savedFile, data, format });
+ await axiosInstance.post('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
}
if (savedFilePath) {
await axiosInstance.post('files/save-as', { filePath: savedFilePath, data, format });
diff --git a/packages/web/src/widgets/ArchiveFilesList.svelte b/packages/web/src/widgets/ArchiveFilesList.svelte
index aee0e0ffa..7847fb2d1 100644
--- a/packages/web/src/widgets/ArchiveFilesList.svelte
+++ b/packages/web/src/widgets/ArchiveFilesList.svelte
@@ -1,3 +1,15 @@
+
+