mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +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 uploads = require('./controllers/uploads');
|
||||
const plugins = require('./controllers/plugins');
|
||||
const files = require('./controllers/files');
|
||||
|
||||
const { rundir } = require('./utility/directories');
|
||||
|
||||
@@ -67,6 +68,7 @@ function start(argument = null) {
|
||||
useController(app, '/archive', archive);
|
||||
useController(app, '/uploads', uploads);
|
||||
useController(app, '/plugins', plugins);
|
||||
useController(app, '/files', files);
|
||||
|
||||
if (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 pluginsdir = dirFunc('plugins');
|
||||
const archivedir = dirFunc('archive');
|
||||
const filesdir = dirFunc('files');
|
||||
|
||||
module.exports = {
|
||||
datadir,
|
||||
@@ -46,4 +47,5 @@ module.exports = {
|
||||
archivedir,
|
||||
ensureDirectory,
|
||||
pluginsdir,
|
||||
filesdir,
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
CurrentWidgetProvider,
|
||||
CurrentDatabaseProvider,
|
||||
OpenedTabsProvider,
|
||||
SavedSqlFilesProvider,
|
||||
OpenedConnectionsProvider,
|
||||
LeftPanelWidthProvider,
|
||||
CurrentArchiveProvider,
|
||||
@@ -25,28 +24,26 @@ function App() {
|
||||
<CurrentDatabaseProvider>
|
||||
<SocketProvider>
|
||||
<OpenedTabsProvider>
|
||||
<SavedSqlFilesProvider>
|
||||
<OpenedConnectionsProvider>
|
||||
<LeftPanelWidthProvider>
|
||||
<ConnectionsPinger>
|
||||
<PluginsProvider>
|
||||
<ExtensionsProvider>
|
||||
<ModalLayerProvider>
|
||||
<CurrentArchiveProvider>
|
||||
<CurrentThemeProvider>
|
||||
<UploadsProvider>
|
||||
<ThemeHelmet />
|
||||
<Screen />
|
||||
</UploadsProvider>
|
||||
</CurrentThemeProvider>
|
||||
</CurrentArchiveProvider>
|
||||
</ModalLayerProvider>
|
||||
</ExtensionsProvider>
|
||||
</PluginsProvider>
|
||||
</ConnectionsPinger>
|
||||
</LeftPanelWidthProvider>
|
||||
</OpenedConnectionsProvider>
|
||||
</SavedSqlFilesProvider>
|
||||
<OpenedConnectionsProvider>
|
||||
<LeftPanelWidthProvider>
|
||||
<ConnectionsPinger>
|
||||
<PluginsProvider>
|
||||
<ExtensionsProvider>
|
||||
<ModalLayerProvider>
|
||||
<CurrentArchiveProvider>
|
||||
<CurrentThemeProvider>
|
||||
<UploadsProvider>
|
||||
<ThemeHelmet />
|
||||
<Screen />
|
||||
</UploadsProvider>
|
||||
</CurrentThemeProvider>
|
||||
</CurrentArchiveProvider>
|
||||
</ModalLayerProvider>
|
||||
</ExtensionsProvider>
|
||||
</PluginsProvider>
|
||||
</ConnectionsPinger>
|
||||
</LeftPanelWidthProvider>
|
||||
</OpenedConnectionsProvider>
|
||||
</OpenedTabsProvider>
|
||||
</SocketProvider>
|
||||
</CurrentDatabaseProvider>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import axios from '../utility/axios';
|
||||
import _ from 'lodash';
|
||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
||||
|
||||
function Menu({ data, setSavedSqlFiles }) {
|
||||
function Menu({ data }) {
|
||||
const handleDelete = () => {
|
||||
setSavedSqlFiles((files) => files.filter((x) => x.storageKey != data.storageKey));
|
||||
axios.post('files/delete', { folder: 'sql', file: data.name });
|
||||
};
|
||||
return (
|
||||
<>
|
||||
@@ -13,26 +14,17 @@ function Menu({ data, setSavedSqlFiles }) {
|
||||
);
|
||||
}
|
||||
|
||||
const savedSqlFileAppObject = () => ({ name, storageKey }, { setOpenedTabs, newQuery, openedTabs }) => {
|
||||
const key = storageKey;
|
||||
const savedSqlFileAppObject = () => ({ name }, { setOpenedTabs, newQuery, openedTabs }) => {
|
||||
const key = name;
|
||||
const title = name;
|
||||
const icon = 'img sql-file';
|
||||
|
||||
const onClick = () => {
|
||||
const existing = openedTabs.find((x) => x.props && x.props.storageKey == storageKey);
|
||||
if (existing) {
|
||||
setOpenedTabs(
|
||||
openedTabs.map((x) => ({
|
||||
...x,
|
||||
selected: x == existing,
|
||||
}))
|
||||
);
|
||||
} else {
|
||||
newQuery({
|
||||
title,
|
||||
storageKey,
|
||||
});
|
||||
}
|
||||
const onClick = async () => {
|
||||
const resp = await axios.post('files/load', { folder: 'sql', file: name });
|
||||
newQuery({
|
||||
title: name,
|
||||
initialScript: resp.data,
|
||||
});
|
||||
};
|
||||
|
||||
return { title, key, icon, onClick, Menu };
|
||||
|
||||
@@ -4,7 +4,6 @@ import ModalBase from './ModalBase';
|
||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { useSetSavedSqlFiles } from '../utility/globalState';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
|
||||
@@ -4,23 +4,15 @@ import ModalBase from './ModalBase';
|
||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { useSetSavedSqlFiles } from '../utility/globalState';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
// import FormikForm from '../utility/FormikForm';
|
||||
|
||||
export default function SaveSqlFileModal({ storageKey, modalState, name, onSave = undefined }) {
|
||||
const setSavedSqlFiles = useSetSavedSqlFiles();
|
||||
const handleSubmit = async (values) => {
|
||||
const { name } = values;
|
||||
setSavedSqlFiles((files) => [
|
||||
...files.filter((x) => x.storageKey != storageKey),
|
||||
{
|
||||
name,
|
||||
storageKey,
|
||||
},
|
||||
]);
|
||||
await axios.post('files/save', { folder: 'sql', file: name, data: localStorage.getItem(storageKey) });
|
||||
modalState.close();
|
||||
if (onSave) onSave(name);
|
||||
};
|
||||
|
||||
@@ -85,7 +85,6 @@ export function useAppObjectParams() {
|
||||
const currentDatabase = useCurrentDatabase();
|
||||
const newQuery = useNewQuery();
|
||||
const openedTabs = useOpenedTabs();
|
||||
const setSavedSqlFiles = useSetSavedSqlFiles();
|
||||
const openedConnections = useOpenedConnections();
|
||||
const setOpenedConnections = useSetOpenedConnections();
|
||||
const currentArchive = useCurrentArchive();
|
||||
@@ -99,7 +98,6 @@ export function useAppObjectParams() {
|
||||
currentArchive,
|
||||
newQuery,
|
||||
openedTabs,
|
||||
setSavedSqlFiles,
|
||||
openedConnections,
|
||||
setOpenedConnections,
|
||||
config,
|
||||
@@ -108,9 +106,6 @@ export function useAppObjectParams() {
|
||||
};
|
||||
}
|
||||
|
||||
const [SavedSqlFilesProvider, useSavedSqlFiles, useSetSavedSqlFiles] = createStorageState('savedSqlFiles', []);
|
||||
export { SavedSqlFilesProvider, useSavedSqlFiles, useSetSavedSqlFiles };
|
||||
|
||||
const [OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections] = createGlobalState([]);
|
||||
|
||||
export { OpenedConnectionsProvider, useOpenedConnections, useSetOpenedConnections };
|
||||
|
||||
@@ -94,6 +94,12 @@ const installedPluginsLoader = () => ({
|
||||
reloadTrigger: `installed-plugins-changed`,
|
||||
});
|
||||
|
||||
const filesLoader = ({ folder }) => ({
|
||||
url: 'files/list',
|
||||
params: { folder },
|
||||
reloadTrigger: `files-changed-${folder}`,
|
||||
});
|
||||
|
||||
async function getCore(loader, args) {
|
||||
const { url, params, reloadTrigger, transform } = loader(args);
|
||||
const key = stableStringify({ url, ...params });
|
||||
@@ -256,3 +262,10 @@ export function getInstalledPlugins(args) {
|
||||
export function useInstalledPlugins(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 styled from 'styled-components';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { AppObjectList } from '../appobj/AppObjectList';
|
||||
import { useOpenedTabs, useSavedSqlFiles } from '../utility/globalState';
|
||||
import { useOpenedTabs } from '../utility/globalState';
|
||||
import closedTabAppObject from '../appobj/closedTabAppObject';
|
||||
import {
|
||||
SearchBoxWrapper,
|
||||
WidgetsInnerContainer,
|
||||
WidgetsMainContainer,
|
||||
WidgetsOuterContainer,
|
||||
WidgetTitle,
|
||||
} from './WidgetStyles';
|
||||
import { WidgetsInnerContainer } from './WidgetStyles';
|
||||
import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject';
|
||||
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
|
||||
import { useFiles } from '../utility/metadataLoaders';
|
||||
|
||||
function ClosedTabsList() {
|
||||
const tabs = useOpenedTabs();
|
||||
@@ -34,7 +28,7 @@ function ClosedTabsList() {
|
||||
}
|
||||
|
||||
function SavedSqlFilesList() {
|
||||
const files = useSavedSqlFiles();
|
||||
const files = useFiles({ folder: 'sql' });
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user