electron: save file to custom location

This commit is contained in:
Jan Prochazka
2021-01-28 18:52:59 +01:00
parent df976a84d2
commit fe1c5f5801
14 changed files with 132 additions and 13 deletions

View File

@@ -124,6 +124,15 @@ function getDbIcon(key) {
return 'icon file';
}
function buildTooltip(tab) {
let res = tab.tooltip;
if (tab.props && tab.props.savedFilePath) {
if (res) res += '\n';
res += tab.props.savedFilePath;
}
return res;
}
export default function TabsPanel() {
// const formatDbKey = (conid, database) => `${database}-${conid}`;
const theme = useTheme();
@@ -252,7 +261,7 @@ export default function TabsPanel() {
{_.sortBy(tabsByDb[dbKey], ['title', 'tabid']).map(tab => (
<FileTabItem
{...tab}
title={tab.tooltip}
title={buildTooltip(tab)}
key={tab.tabid}
theme={theme}
onClick={e => handleTabClick(e, tab.tabid)}

View File

@@ -149,7 +149,7 @@ export async function openDatabaseObjectDetail(
openNewTab(
{
title: pureName,
title: 'Query #',
tooltip,
icon: sqlTemplate ? 'img sql-file' : icons[objectTypeField],
tabComponent: sqlTemplate ? 'QueryTab' : tabComponent,

View File

@@ -6,14 +6,52 @@ import ModalHeader from './ModalHeader';
import ModalContent from './ModalContent';
import ModalFooter from './ModalFooter';
import { FormProvider } from '../utility/FormProvider';
import FormStyledButton from '../widgets/FormStyledButton';
import getElectron from '../utility/getElectron';
export default function SaveFileModal({
data,
folder,
format,
modalState,
name,
fileExtension,
filePath,
onSave = undefined,
}) {
const electron = getElectron();
export default function SaveFileModal({ data, folder, format, modalState, name, onSave = undefined }) {
const handleSubmit = async values => {
const { name } = values;
await axios.post('files/save', { folder, file: name, data, format });
modalState.close();
if (onSave) onSave(name);
if (onSave) {
onSave(name, {
savedFile: name,
savedFolder: folder,
savedFilePath: null,
});
}
};
const handleSaveAs = async filePath => {
const path = window.require('path');
const parsed = path.parse(filePath);
if (!parsed.ext) filePath += `.${fileExtension}`;
await axios.post('files/save-as', { filePath, data, format });
modalState.close();
if (onSave) {
onSave(parsed.name, {
savedFile: null,
savedFolder: null,
savedFilePath: filePath,
});
}
};
return (
<ModalBase modalState={modalState}>
<ModalHeader modalState={modalState}>Save file</ModalHeader>
@@ -23,6 +61,21 @@ export default function SaveFileModal({ data, folder, format, modalState, name,
</ModalContent>
<ModalFooter>
<FormSubmit value="Save" onClick={handleSubmit} />
{electron && (
<FormStyledButton
type="button"
value="Save to disk"
onClick={() => {
const file = electron.remote.dialog.showSaveDialogSync(electron.remote.getCurrentWindow(), {
filters: { name: `${fileExtension.toUpperCase()} files`, extensions: [fileExtension] },
defaultPath: filePath,
});
if (file) {
handleSaveAs(file);
}
}}
/>
)}
</ModalFooter>
</FormProvider>
</ModalBase>

View File

@@ -4,22 +4,22 @@ import { useOpenedTabs, useSetOpenedTabs } from '../utility/globalState';
import keycodes from '../utility/keycodes';
import SaveFileModal from './SaveFileModal';
export default function SaveTabModal({ data, folder, format, modalState, tabid, tabVisible }) {
export default function SaveTabModal({ data, folder, format, modalState, tabid, tabVisible, fileExtension }) {
const setOpenedTabs = useSetOpenedTabs();
const openedTabs = useOpenedTabs();
const { savedFile } = openedTabs.find(x => x.tabid == tabid).props || {};
const onSave = name =>
const { savedFile, savedFilePath } = openedTabs.find(x => x.tabid == tabid).props || {};
const onSave = (title, newProps) => {
changeTab(tabid, setOpenedTabs, tab => ({
...tab,
title: name,
title,
props: {
...tab.props,
savedFile: name,
savedFolder: folder,
savedFormat: format,
...newProps,
},
}));
};
const handleKeyboard = React.useCallback(
e => {
@@ -47,6 +47,8 @@ export default function SaveTabModal({ data, folder, format, modalState, tabid,
format={format}
modalState={modalState}
name={savedFile || 'newFile'}
filePath={savedFilePath}
fileExtension={fileExtension}
onSave={onSave}
/>
);

View File

@@ -63,6 +63,7 @@ export default function ChartTab({ tabVisible, toolbarPortalRef, conid, database
format="json"
folder="charts"
tabid={tabid}
fileExtension='chart'
/>
{toolbarPortalRef &&
toolbarPortalRef.current &&

View File

@@ -75,6 +75,7 @@ export default function MarkdownEditorTab({ tabid, tabVisible, toolbarPortalRef,
format="text"
folder="markdown"
tabid={tabid}
fileExtension='md'
/>
</>
);

View File

@@ -225,6 +225,7 @@ export default function QueryDesignTab({
format="json"
folder="query"
tabid={tabid}
fileExtension='qdesign'
/>
</>
);

View File

@@ -228,6 +228,7 @@ export default function QueryTab({
format="text"
folder="sql"
tabid={tabid}
fileExtension='sql'
/>
</>
);

View File

@@ -145,6 +145,7 @@ export default function ShellTab({ tabid, tabVisible, toolbarPortalRef, statusba
format="text"
folder="shell"
tabid={tabid}
fileExtension='js'
/>
</>
);

View File

@@ -0,0 +1,31 @@
import useNewQuery from '../query/useNewQuery';
import getElectron from './getElectron';
export default function useOpenElectronFile() {
const electron = getElectron();
const newQuery = useNewQuery();
return () => {
const filePaths = electron.remote.dialog.showOpenDialogSync(electron.remote.getCurrentWindow(), {
filters: { name: `SQL files`, extensions: ['sql'] },
});
const filePath = filePaths && filePaths[0];
if (filePath) {
if (filePath.match(/.sql$/i)) {
const path = window.require('path');
const fs = window.require('fs');
const parsed = path.parse(filePath);
const data = fs.readFileSync(filePath, { encoding: 'utf-8' });
newQuery({
title: parsed.name,
initialData: data,
// @ts-ignore
savedFilePath: filePath,
savedFormat: 'text',
});
}
}
};
}

View File

@@ -23,11 +23,16 @@ export default function useOpenNewTab() {
async (newTab, initialData = undefined, options) => {
let existing = null;
const { savedFile } = newTab.props || {};
if (savedFile) {
const { savedFile, savedFolder, savedFilePath } = newTab.props || {};
if (savedFile || savedFilePath) {
existing = openedTabs.find(
x =>
x.props && x.tabComponent == newTab.tabComponent && x.closedTime == null && x.props.savedFile == savedFile
x.props &&
x.tabComponent == newTab.tabComponent &&
x.closedTime == null &&
x.props.savedFile == savedFile &&
x.props.savedFolder == savedFolder &&
x.props.savedFilePath == savedFilePath
);
}

View File

@@ -25,6 +25,7 @@ import tabs from '../tabs';
import FavoriteModal from '../modals/FavoriteModal';
import { useOpenFavorite } from '../appobj/FavoriteFileAppObject';
import ErrorMessageModal from '../modals/ErrorMessageModal';
import useOpenElectronFile from '../utility/useOpenElectronFile';
const ToolbarContainer = styled.div`
display: flex;
@@ -48,6 +49,7 @@ export default function ToolBar({ toolbarPortalRef }) {
const electron = getElectron();
const favorites = useFavorites();
const openFavorite = useOpenFavorite();
const openElectronFile = useOpenElectronFile();
const currentTab = openedTabs.find(x => x.selected);
@@ -58,6 +60,7 @@ export default function ToolBar({ toolbarPortalRef }) {
window['dbgate_newQuery'] = newQuery;
window['dbgate_closeAll'] = () => setOpenedTabs([]);
window['dbgate_showAbout'] = showAbout;
window['dbgate_openFile'] = openElectronFile;
});
const showAbout = () => {