diff --git a/packages/web/src/TabsPanel.js b/packages/web/src/TabsPanel.js
index 812eb14a5..cb62dcfcb 100644
--- a/packages/web/src/TabsPanel.js
+++ b/packages/web/src/TabsPanel.js
@@ -131,12 +131,26 @@ export default function TabsPanel() {
setOpenedTabs((files) => {
const active = files.find((x) => x.tabid == tabid);
if (!active) return files;
- let index = _.findIndex(files, (x) => x.tabid == tabid);
- const newFiles = files.filter((x) => !closeCondition(x, active));
+ const lastSelectedIndex = _.findIndex(files, (x) => x.tabid == tabid);
+ let selectedIndex = lastSelectedIndex;
- if (!newFiles.find((x) => x.selected)) {
- while (index >= newFiles.length) index -= 1;
- if (index >= 0) newFiles[index].selected = true;
+ const newFiles = files.map((x) => ({
+ ...x,
+ closedTime: x.closedTime || (closeCondition(x, active) ? new Date().getTime() : undefined),
+ }));
+
+ while (selectedIndex >= 0 && newFiles[selectedIndex].closedTime) selectedIndex -= 1;
+
+ if (selectedIndex < 0) {
+ selectedIndex = lastSelectedIndex;
+ while (selectedIndex < newFiles.length && newFiles[selectedIndex].closedTime) selectedIndex += 1;
+ }
+
+ if (selectedIndex != lastSelectedIndex) {
+ return newFiles.map((x, index) => ({
+ ...x,
+ selected: index == selectedIndex,
+ }));
}
return newFiles;
@@ -184,12 +198,14 @@ export default function TabsPanel() {
// 't',
// tabs.map(x => x.tooltip)
// );
- const tabsWithDb = tabs.map((tab) => ({
- ...tab,
- tabDbName: tab.props && tab.props.conid && tab.props.database ? tab.props.database : '(no DB)',
- tabDbKey:
- tab.props && tab.props.conid && tab.props.database ? formatDbKey(tab.props.conid, tab.props.database) : noDbKey,
- }));
+ const tabsWithDb = tabs
+ .filter((x) => !x.closedTime)
+ .map((tab) => ({
+ ...tab,
+ tabDbName: tab.props && tab.props.conid && tab.props.database ? tab.props.database : '(no DB)',
+ tabDbKey:
+ tab.props && tab.props.conid && tab.props.database ? formatDbKey(tab.props.conid, tab.props.database) : noDbKey,
+ }));
const tabsByDb = _.groupBy(tabsWithDb, 'tabDbKey');
const dbKeys = _.keys(tabsByDb).sort();
diff --git a/packages/web/src/appobj/openedTabAppObject.js b/packages/web/src/appobj/closedTabAppObject.js
similarity index 50%
rename from packages/web/src/appobj/openedTabAppObject.js
rename to packages/web/src/appobj/closedTabAppObject.js
index 3fef7335d..cb9e54bd2 100644
--- a/packages/web/src/appobj/openedTabAppObject.js
+++ b/packages/web/src/appobj/closedTabAppObject.js
@@ -1,8 +1,9 @@
import React from 'react';
import _ from 'lodash';
+import moment from 'moment';
import { getIconImage } from '../icons';
-const openedTabAppObject = () => ({ tabid, props, selected, icon, title, busy }, { setOpenedTabs }) => {
+const closedTabAppObject = () => ({ tabid, props, selected, icon, title, closedTime, busy }, { setOpenedTabs }) => {
const key = tabid;
const Icon = (props) => getIconImage(icon, props);
const isBold = !!selected;
@@ -12,11 +13,12 @@ const openedTabAppObject = () => ({ tabid, props, selected, icon, title, busy },
files.map((x) => ({
...x,
selected: x.tabid == tabid,
+ closedTime: x.tabid == tabid ? undefined : x.closedTime,
}))
);
};
- return { title, key, Icon, isBold, onClick, isBusy: busy };
+ return { title: `${title} ${moment(closedTime).fromNow()}`, key, Icon, isBold, onClick, isBusy: busy };
};
-export default openedTabAppObject;
+export default closedTabAppObject;
diff --git a/packages/web/src/tabs/QueryTab.js b/packages/web/src/tabs/QueryTab.js
index 58f855b93..c2314d2e2 100644
--- a/packages/web/src/tabs/QueryTab.js
+++ b/packages/web/src/tabs/QueryTab.js
@@ -76,7 +76,7 @@ export default function QueryTab({
...other
}) {
const loadingText = 'Loading SQL template...';
- const localStorageKey = storageKey || `sql_${tabid}`;
+ const localStorageKey = storageKey || `tabdata_sql_${tabid}`;
const { sqlTemplate } = initialArgs || {};
const [queryText, setQueryText] = React.useState(
() => localStorage.getItem(localStorageKey) || initialScript || (sqlTemplate ? loadingText : '')
diff --git a/packages/web/src/tabs/ShellTab.js b/packages/web/src/tabs/ShellTab.js
index d4018d965..d670b27c4 100644
--- a/packages/web/src/tabs/ShellTab.js
+++ b/packages/web/src/tabs/ShellTab.js
@@ -33,7 +33,7 @@ export default function ShellTab({
storageKey,
...other
}) {
- const localStorageKey = storageKey || `shell_${tabid}`;
+ const localStorageKey = storageKey || `tabdata_shell_${tabid}`;
const [shellText, setShellText] = React.useState(() => localStorage.getItem(localStorageKey) || initialScript || '');
const shellTextRef = React.useRef(shellText);
const [busy, setBusy] = React.useState(false);
diff --git a/packages/web/src/utility/useGridConfig.js b/packages/web/src/utility/useGridConfig.js
index b1d859001..5763fa14a 100644
--- a/packages/web/src/utility/useGridConfig.js
+++ b/packages/web/src/utility/useGridConfig.js
@@ -2,7 +2,7 @@ import { createGridConfig } from '@dbgate/datalib';
import React from 'react';
const loadGridConfigFunc = (tabid) => () => {
- const existing = localStorage.getItem(`grid_${tabid}`);
+ const existing = localStorage.getItem(`tabdata_grid_${tabid}`);
if (existing) return JSON.parse(existing);
return createGridConfig();
};
@@ -11,7 +11,7 @@ export default function useGridConfig(tabid) {
const [config, setConfig] = React.useState(loadGridConfigFunc(tabid));
React.useEffect(() => {
- localStorage.setItem(`grid_${tabid}`, JSON.stringify(config));
+ localStorage.setItem(`tabdata_grid_${tabid}`, JSON.stringify(config));
}, [config]);
return [config, setConfig];
diff --git a/packages/web/src/widgets/FilesWidget.js b/packages/web/src/widgets/FilesWidget.js
index ef36bb221..05d4fcddf 100644
--- a/packages/web/src/widgets/FilesWidget.js
+++ b/packages/web/src/widgets/FilesWidget.js
@@ -4,7 +4,7 @@ import _ from 'lodash';
import { AppObjectList } from '../appobj/AppObjectList';
import { useOpenedTabs, useSavedSqlFiles } from '../utility/globalState';
-import openedTabAppObject from '../appobj/openedTabAppObject';
+import closedTabAppObject from '../appobj/closedTabAppObject';
import {
SearchBoxWrapper,
WidgetsInnerContainer,
@@ -14,14 +14,20 @@ import {
} from './WidgetStyles';
import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject';
-function OpenedTabsList() {
+function ClosedTabsList() {
const tabs = useOpenedTabs();
return (
<>
Recently closed tabs
-
+ x.closedTime),
+ (x) => -x.closedTime
+ )}
+ makeAppObj={closedTabAppObject()}
+ />
>
);
@@ -44,7 +50,7 @@ export default function FilesWidget() {
return (
-
+