mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 09:36:00 +00:00
saved sql files - save to server (minimal version)
This commit is contained in:
46
packages/api/src/controllers/files.js
Normal file
46
packages/api/src/controllers/files.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
const { filesdir } = require('../utility/directories');
|
||||||
|
const socket = require('../utility/socket');
|
||||||
|
|
||||||
|
function serialize(folder, data) {
|
||||||
|
if (folder == 'sql') return data;
|
||||||
|
return JSON.stringify(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deserialize(folder, text) {
|
||||||
|
if (folder == 'sql') return text;
|
||||||
|
return JSON.parse(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
list_meta: 'get',
|
||||||
|
async list({ folder }) {
|
||||||
|
const dir = path.join(filesdir(), folder);
|
||||||
|
if (!(await fs.exists(dir))) return [];
|
||||||
|
const files = (await fs.readdir(dir)).map((name) => ({ name }));
|
||||||
|
return files;
|
||||||
|
},
|
||||||
|
|
||||||
|
delete_meta: 'post',
|
||||||
|
async delete({ folder, file }) {
|
||||||
|
await fs.unlink(path.join(filesdir(), folder, file));
|
||||||
|
socket.emitChanged(`files-changed-${folder}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
load_meta: 'post',
|
||||||
|
async load({ folder, file }) {
|
||||||
|
const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
|
||||||
|
return deserialize(folder, text);
|
||||||
|
},
|
||||||
|
|
||||||
|
save_meta: 'post',
|
||||||
|
async save({ folder, file, data }) {
|
||||||
|
const dir = path.join(filesdir(), folder);
|
||||||
|
if (!(await fs.exists(dir))) {
|
||||||
|
await fs.mkdir(dir);
|
||||||
|
}
|
||||||
|
await fs.writeFile(path.join(dir, file), serialize(folder, data));
|
||||||
|
socket.emitChanged(`files-changed-${folder}`);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -23,6 +23,7 @@ const config = require('./controllers/config');
|
|||||||
const archive = require('./controllers/archive');
|
const archive = require('./controllers/archive');
|
||||||
const uploads = require('./controllers/uploads');
|
const uploads = require('./controllers/uploads');
|
||||||
const plugins = require('./controllers/plugins');
|
const plugins = require('./controllers/plugins');
|
||||||
|
const files = require('./controllers/files');
|
||||||
|
|
||||||
const { rundir } = require('./utility/directories');
|
const { rundir } = require('./utility/directories');
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ function start(argument = null) {
|
|||||||
useController(app, '/archive', archive);
|
useController(app, '/archive', archive);
|
||||||
useController(app, '/uploads', uploads);
|
useController(app, '/uploads', uploads);
|
||||||
useController(app, '/plugins', plugins);
|
useController(app, '/plugins', plugins);
|
||||||
|
useController(app, '/files', files);
|
||||||
|
|
||||||
if (process.env.PAGES_DIRECTORY) {
|
if (process.env.PAGES_DIRECTORY) {
|
||||||
app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
|
app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const rundir = dirFunc('run', true);
|
|||||||
const uploadsdir = dirFunc('uploads', true);
|
const uploadsdir = dirFunc('uploads', true);
|
||||||
const pluginsdir = dirFunc('plugins');
|
const pluginsdir = dirFunc('plugins');
|
||||||
const archivedir = dirFunc('archive');
|
const archivedir = dirFunc('archive');
|
||||||
|
const filesdir = dirFunc('files');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
datadir,
|
datadir,
|
||||||
@@ -46,4 +47,5 @@ module.exports = {
|
|||||||
archivedir,
|
archivedir,
|
||||||
ensureDirectory,
|
ensureDirectory,
|
||||||
pluginsdir,
|
pluginsdir,
|
||||||
|
filesdir,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
CurrentWidgetProvider,
|
CurrentWidgetProvider,
|
||||||
CurrentDatabaseProvider,
|
CurrentDatabaseProvider,
|
||||||
OpenedTabsProvider,
|
OpenedTabsProvider,
|
||||||
SavedSqlFilesProvider,
|
|
||||||
OpenedConnectionsProvider,
|
OpenedConnectionsProvider,
|
||||||
LeftPanelWidthProvider,
|
LeftPanelWidthProvider,
|
||||||
CurrentArchiveProvider,
|
CurrentArchiveProvider,
|
||||||
@@ -25,7 +24,6 @@ function App() {
|
|||||||
<CurrentDatabaseProvider>
|
<CurrentDatabaseProvider>
|
||||||
<SocketProvider>
|
<SocketProvider>
|
||||||
<OpenedTabsProvider>
|
<OpenedTabsProvider>
|
||||||
<SavedSqlFilesProvider>
|
|
||||||
<OpenedConnectionsProvider>
|
<OpenedConnectionsProvider>
|
||||||
<LeftPanelWidthProvider>
|
<LeftPanelWidthProvider>
|
||||||
<ConnectionsPinger>
|
<ConnectionsPinger>
|
||||||
@@ -46,7 +44,6 @@ function App() {
|
|||||||
</ConnectionsPinger>
|
</ConnectionsPinger>
|
||||||
</LeftPanelWidthProvider>
|
</LeftPanelWidthProvider>
|
||||||
</OpenedConnectionsProvider>
|
</OpenedConnectionsProvider>
|
||||||
</SavedSqlFilesProvider>
|
|
||||||
</OpenedTabsProvider>
|
</OpenedTabsProvider>
|
||||||
</SocketProvider>
|
</SocketProvider>
|
||||||
</CurrentDatabaseProvider>
|
</CurrentDatabaseProvider>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import axios from '../utility/axios';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
||||||
|
|
||||||
function Menu({ data, setSavedSqlFiles }) {
|
function Menu({ data }) {
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
setSavedSqlFiles((files) => files.filter((x) => x.storageKey != data.storageKey));
|
axios.post('files/delete', { folder: 'sql', file: data.name });
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -13,26 +14,17 @@ function Menu({ data, setSavedSqlFiles }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const savedSqlFileAppObject = () => ({ name, storageKey }, { setOpenedTabs, newQuery, openedTabs }) => {
|
const savedSqlFileAppObject = () => ({ name }, { setOpenedTabs, newQuery, openedTabs }) => {
|
||||||
const key = storageKey;
|
const key = name;
|
||||||
const title = name;
|
const title = name;
|
||||||
const icon = 'img sql-file';
|
const icon = 'img sql-file';
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = async () => {
|
||||||
const existing = openedTabs.find((x) => x.props && x.props.storageKey == storageKey);
|
const resp = await axios.post('files/load', { folder: 'sql', file: name });
|
||||||
if (existing) {
|
|
||||||
setOpenedTabs(
|
|
||||||
openedTabs.map((x) => ({
|
|
||||||
...x,
|
|
||||||
selected: x == existing,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
newQuery({
|
newQuery({
|
||||||
title,
|
title: name,
|
||||||
storageKey,
|
initialScript: resp.data,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return { title, key, icon, onClick, Menu };
|
return { title, key, icon, onClick, Menu };
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import ModalBase from './ModalBase';
|
|||||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||||
import { TextField } from '../utility/inputs';
|
import { TextField } from '../utility/inputs';
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
import { useSetSavedSqlFiles } from '../utility/globalState';
|
|
||||||
import ModalHeader from './ModalHeader';
|
import ModalHeader from './ModalHeader';
|
||||||
import ModalContent from './ModalContent';
|
import ModalContent from './ModalContent';
|
||||||
import ModalFooter from './ModalFooter';
|
import ModalFooter from './ModalFooter';
|
||||||
|
|||||||
@@ -4,23 +4,15 @@ import ModalBase from './ModalBase';
|
|||||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||||
import { TextField } from '../utility/inputs';
|
import { TextField } from '../utility/inputs';
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
import { useSetSavedSqlFiles } from '../utility/globalState';
|
|
||||||
import ModalHeader from './ModalHeader';
|
import ModalHeader from './ModalHeader';
|
||||||
import ModalContent from './ModalContent';
|
import ModalContent from './ModalContent';
|
||||||
import ModalFooter from './ModalFooter';
|
import ModalFooter from './ModalFooter';
|
||||||
// import FormikForm from '../utility/FormikForm';
|
// import FormikForm from '../utility/FormikForm';
|
||||||
|
|
||||||
export default function SaveSqlFileModal({ storageKey, modalState, name, onSave = undefined }) {
|
export default function SaveSqlFileModal({ storageKey, modalState, name, onSave = undefined }) {
|
||||||
const setSavedSqlFiles = useSetSavedSqlFiles();
|
|
||||||
const handleSubmit = async (values) => {
|
const handleSubmit = async (values) => {
|
||||||
const { name } = values;
|
const { name } = values;
|
||||||
setSavedSqlFiles((files) => [
|
await axios.post('files/save', { folder: 'sql', file: name, data: localStorage.getItem(storageKey) });
|
||||||
...files.filter((x) => x.storageKey != storageKey),
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
storageKey,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
modalState.close();
|
modalState.close();
|
||||||
if (onSave) onSave(name);
|
if (onSave) onSave(name);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ export function useAppObjectParams() {
|
|||||||
const currentDatabase = useCurrentDatabase();
|
const currentDatabase = useCurrentDatabase();
|
||||||
const newQuery = useNewQuery();
|
const newQuery = useNewQuery();
|
||||||
const openedTabs = useOpenedTabs();
|
const openedTabs = useOpenedTabs();
|
||||||
const setSavedSqlFiles = useSetSavedSqlFiles();
|
|
||||||
const openedConnections = useOpenedConnections();
|
const openedConnections = useOpenedConnections();
|
||||||
const setOpenedConnections = useSetOpenedConnections();
|
const setOpenedConnections = useSetOpenedConnections();
|
||||||
const currentArchive = useCurrentArchive();
|
const currentArchive = useCurrentArchive();
|
||||||
@@ -99,7 +98,6 @@ export function useAppObjectParams() {
|
|||||||
currentArchive,
|
currentArchive,
|
||||||
newQuery,
|
newQuery,
|
||||||
openedTabs,
|
openedTabs,
|
||||||
setSavedSqlFiles,
|
|
||||||
openedConnections,
|
openedConnections,
|
||||||
setOpenedConnections,
|
setOpenedConnections,
|
||||||
config,
|
config,
|
||||||
@@ -108,9 +106,6 @@ export function useAppObjectParams() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const [SavedSqlFilesProvider, useSavedSqlFiles, useSetSavedSqlFiles] = createStorageState('savedSqlFiles', []);
|
|
||||||
export { SavedSqlFilesProvider, useSavedSqlFiles, useSetSavedSqlFiles };
|
|
||||||
|
|
||||||
const [OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections] = createGlobalState([]);
|
const [OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections] = createGlobalState([]);
|
||||||
|
|
||||||
export { OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections };
|
export { OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections };
|
||||||
|
|||||||
@@ -94,6 +94,12 @@ const installedPluginsLoader = () => ({
|
|||||||
reloadTrigger: `installed-plugins-changed`,
|
reloadTrigger: `installed-plugins-changed`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filesLoader = ({ folder }) => ({
|
||||||
|
url: 'files/list',
|
||||||
|
params: { folder },
|
||||||
|
reloadTrigger: `files-changed-${folder}`,
|
||||||
|
});
|
||||||
|
|
||||||
async function getCore(loader, args) {
|
async function getCore(loader, args) {
|
||||||
const { url, params, reloadTrigger, transform } = loader(args);
|
const { url, params, reloadTrigger, transform } = loader(args);
|
||||||
const key = stableStringify({ url, ...params });
|
const key = stableStringify({ url, ...params });
|
||||||
@@ -256,3 +262,10 @@ export function getInstalledPlugins(args) {
|
|||||||
export function useInstalledPlugins(args) {
|
export function useInstalledPlugins(args) {
|
||||||
return useCore(installedPluginsLoader, args) || [];
|
return useCore(installedPluginsLoader, args) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFiles(args) {
|
||||||
|
return getCore(filesLoader, args);
|
||||||
|
}
|
||||||
|
export function useFiles(args) {
|
||||||
|
return useCore(filesLoader, args);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { AppObjectList } from '../appobj/AppObjectList';
|
import { AppObjectList } from '../appobj/AppObjectList';
|
||||||
import { useOpenedTabs, useSavedSqlFiles } from '../utility/globalState';
|
import { useOpenedTabs } from '../utility/globalState';
|
||||||
import closedTabAppObject from '../appobj/closedTabAppObject';
|
import closedTabAppObject from '../appobj/closedTabAppObject';
|
||||||
import {
|
import { WidgetsInnerContainer } from './WidgetStyles';
|
||||||
SearchBoxWrapper,
|
|
||||||
WidgetsInnerContainer,
|
|
||||||
WidgetsMainContainer,
|
|
||||||
WidgetsOuterContainer,
|
|
||||||
WidgetTitle,
|
|
||||||
} from './WidgetStyles';
|
|
||||||
import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject';
|
import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject';
|
||||||
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
|
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
|
||||||
|
import { useFiles } from '../utility/metadataLoaders';
|
||||||
|
|
||||||
function ClosedTabsList() {
|
function ClosedTabsList() {
|
||||||
const tabs = useOpenedTabs();
|
const tabs = useOpenedTabs();
|
||||||
@@ -34,7 +28,7 @@ function ClosedTabsList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function SavedSqlFilesList() {
|
function SavedSqlFilesList() {
|
||||||
const files = useSavedSqlFiles();
|
const files = useFiles({ folder: 'sql' });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user