diff --git a/packages/web/src/appobj/SavedFileAppObject.js b/packages/web/src/appobj/SavedFileAppObject.js
index f2b4a39ae..23baaec71 100644
--- a/packages/web/src/appobj/SavedFileAppObject.js
+++ b/packages/web/src/appobj/SavedFileAppObject.js
@@ -109,6 +109,8 @@ export function SavedSqlFileAppObject({ data, commonProps }) {
newQuery({
title: file,
initialData: data,
+ // @ts-ignore
+ savedFile: file,
});
}}
/>
@@ -131,6 +133,9 @@ export function SavedShellFileAppObject({ data, commonProps }) {
title: file,
icon: 'img shell',
tabComponent: 'ShellTab',
+ props: {
+ savedFile: file,
+ },
},
data
);
@@ -165,6 +170,7 @@ export function SavedChartFileAppObject({ data, commonProps }) {
props: {
conid: connection._id,
database,
+ savedFile: file,
},
tabComponent: 'ChartTab',
},
@@ -201,6 +207,9 @@ export function SavedMarkdownFileAppObject({ data, commonProps }) {
title: file,
icon: 'img markdown',
tabComponent: 'MarkdownEditorTab',
+ props: {
+ savedFile: file,
+ },
},
data
);
diff --git a/packages/web/src/modals/SaveTabModal.js b/packages/web/src/modals/SaveTabModal.js
index 50e29c1c3..0a9f55e85 100644
--- a/packages/web/src/modals/SaveTabModal.js
+++ b/packages/web/src/modals/SaveTabModal.js
@@ -8,8 +8,13 @@ export default function SaveTabModal({ data, folder, format, modalState, tabid,
const setOpenedTabs = useSetOpenedTabs();
const openedTabs = useOpenedTabs();
- const name = openedTabs.find((x) => x.tabid == tabid).title;
- const onSave = (name) => changeTab(tabid, setOpenedTabs, (tab) => ({ ...tab, title: name }));
+ const { savedFile } = openedTabs.find((x) => x.tabid == tabid).props || {};
+ const onSave = (name) =>
+ changeTab(tabid, setOpenedTabs, (tab) => ({
+ ...tab,
+ title: name,
+ props: { ...tab.props, savedFile: name },
+ }));
const handleKeyboard = React.useCallback(
(e) => {
@@ -31,6 +36,13 @@ export default function SaveTabModal({ data, folder, format, modalState, tabid,
}, [tabVisible, handleKeyboard]);
return (
-
+
);
}
diff --git a/packages/web/src/tabs/ArchiveFileTab.js b/packages/web/src/tabs/ArchiveFileTab.js
index 0328d1063..ebde08373 100644
--- a/packages/web/src/tabs/ArchiveFileTab.js
+++ b/packages/web/src/tabs/ArchiveFileTab.js
@@ -4,3 +4,5 @@ import JslDataGrid from '../sqleditor/JslDataGrid';
export default function ArchiveFileTab({ archiveFolder, archiveFile, tabVisible, toolbarPortalRef, tabid }) {
return ;
}
+
+ArchiveFileTab.matchingProps = ['archiveFile', 'archiveFolder'];
diff --git a/packages/web/src/tabs/TableDataTab.js b/packages/web/src/tabs/TableDataTab.js
index b295f95db..cd67a3a33 100644
--- a/packages/web/src/tabs/TableDataTab.js
+++ b/packages/web/src/tabs/TableDataTab.js
@@ -26,3 +26,5 @@ export default function TableDataTab({ conid, database, schemaName, pureName, ta
/>
);
}
+
+TableDataTab.matchingProps = ['conid', 'database', 'schemaName', 'pureName'];
diff --git a/packages/web/src/tabs/ViewDataTab.js b/packages/web/src/tabs/ViewDataTab.js
index c3787fed3..949e65d0a 100644
--- a/packages/web/src/tabs/ViewDataTab.js
+++ b/packages/web/src/tabs/ViewDataTab.js
@@ -54,3 +54,5 @@ export default function ViewDataTab({ conid, database, schemaName, pureName, tab
/>
);
}
+
+ViewDataTab.matchingProps = ['conid', 'database', 'schemaName', 'pureName'];
\ No newline at end of file
diff --git a/packages/web/src/utility/useOpenNewTab.js b/packages/web/src/utility/useOpenNewTab.js
index f1aec4754..24d33f5e5 100644
--- a/packages/web/src/utility/useOpenNewTab.js
+++ b/packages/web/src/utility/useOpenNewTab.js
@@ -1,13 +1,49 @@
import uuidv1 from 'uuid/v1';
import React from 'react';
import localforage from 'localforage';
-import { useSetOpenedTabs } from './globalState';
+import stableStringify from 'json-stable-stringify';
+import _ from 'lodash';
+import { useOpenedTabs, useSetOpenedTabs } from './globalState';
+import tabs from '../tabs';
export default function useOpenNewTab() {
const setOpenedTabs = useSetOpenedTabs();
+ const openedTabs = useOpenedTabs();
const openNewTab = React.useCallback(
async (newTab, initialData = undefined) => {
+ let existing = null;
+
+ const { savedFile } = newTab.props || {};
+ if (savedFile) {
+ existing = openedTabs.find(
+ (x) =>
+ x.props && x.tabComponent == newTab.tabComponent && x.closedTime == null && x.props.savedFile == savedFile
+ );
+ }
+
+ const component = tabs[newTab.tabComponent];
+ if (!existing && component && component.matchingProps) {
+ const testString = stableStringify(_.pick(newTab.props || {}, component.matchingProps));
+ existing = openedTabs.find(
+ (x) =>
+ x.props &&
+ x.tabComponent == newTab.tabComponent &&
+ x.closedTime == null &&
+ stableStringify(_.pick(x.props || {}, component.matchingProps)) == testString
+ );
+ }
+
+ if (existing) {
+ setOpenedTabs((tabs) =>
+ tabs.map((x) => ({
+ ...x,
+ selected: x.tabid == existing.tabid,
+ }))
+ );
+ return;
+ }
+
const tabid = uuidv1();
if (initialData) {
await localforage.setItem(`tabdata_${tabid}`, initialData);