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