saved sql files - save to server (minimal version)

This commit is contained in:
Jan Prochazka
2020-12-02 20:02:58 +01:00
parent 203e490321
commit e952d5c6f8
10 changed files with 99 additions and 67 deletions

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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