diff --git a/packages/web/src/stores.ts b/packages/web/src/stores.ts index 150df6f5b..ff531588f 100644 --- a/packages/web/src/stores.ts +++ b/packages/web/src/stores.ts @@ -44,6 +44,7 @@ export const activeTab = derived([openedTabs], ([$openedTabs]) => $openedTabs.fi export const recentDatabases = writableWithStorage([], 'recentDatabases'); export const pinnedDatabases = writableWithStorage([], 'pinnedDatabases'); export const pinnedTables = writableWithStorage([], 'pinnedTables'); +export const tabDatabaseGroupOrder = writableWithStorage({}, 'tabDatabaseGroupOrder'); export const commandsSettings = writable({}); export const allResultsInOneTabDefault = writableWithStorage(false, 'allResultsInOneTabDefault'); export const archiveFilesAsDataSheets = writableWithStorage([], 'archiveFilesAsDataSheets'); diff --git a/packages/web/src/utility/openNewTab.ts b/packages/web/src/utility/openNewTab.ts index ccc47190c..f0222bb46 100644 --- a/packages/web/src/utility/openNewTab.ts +++ b/packages/web/src/utility/openNewTab.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; import uuidv1 from 'uuid/v1'; import { get } from 'svelte/store'; -import { openedTabs } from '../stores'; +import { getOpenedTabs, openedTabs, tabDatabaseGroupOrder } from '../stores'; import tabs from '../tabs'; import { setSelectedTabFunc } from './common'; import localforage from 'localforage'; @@ -72,15 +72,38 @@ export default async function openNewTab(newTab, initialData = undefined, option } } } + openedTabs.update(files => [ ...(files || []).map(x => ({ ...x, selected: false })), { ...newTab, tabid, selected: true, + // @ts-ignore + tabOrder: (_.max(files.map(x => x.tabOrder || 0)) || 0) + 1, }, ]); + const allOpenedTabs = getOpenedTabs(); + + tabDatabaseGroupOrder.update(groupOrder => { + const groupOrderFiltered = _.pickBy(groupOrder, (v, k) => + allOpenedTabs.filter(x => x.closedTime == null).find(x => getTabDbKey(x) == k) + ); + const dbKey = getTabDbKey({ + ...newTab, + tabid, + }); + const newOrder = + groupOrderFiltered[dbKey] || + // @ts-ignore + (_.max(Object.values(groupOrderFiltered)) || 0) + 1; + return { + ...groupOrderFiltered, + [dbKey]: newOrder, + }; + }); + // console.log('OPENING NEW TAB', newTab); // const tabid = uuidv1(); // openedTabs.update(tabs => [ @@ -124,3 +147,16 @@ export async function duplicateTab(tab) { { forceNewTab: true } ); } + +export function getTabDbKey(tab) { + if (tab.props && tab.props.conid && tab.props.database) { + return `database://${tab.props.database}-${tab.props.conid}`; + } + if (tab.props && tab.props.conid) { + return `server://${tab.props.conid}`; + } + if (tab.props && tab.props.archiveFolder) { + return `archive://${tab.props.archiveFolder}`; + } + return `no://${tab.tabid}`; +} diff --git a/packages/web/src/widgets/TabsPanel.svelte b/packages/web/src/widgets/TabsPanel.svelte index ee2053527..bf9b76845 100644 --- a/packages/web/src/widgets/TabsPanel.svelte +++ b/packages/web/src/widgets/TabsPanel.svelte @@ -59,19 +59,6 @@ return '(no DB)'; } - function getTabDbKey(tab) { - if (tab.props && tab.props.conid && tab.props.database) { - return `database://${tab.props.database}-${tab.props.conid}`; - } - if (tab.props && tab.props.conid) { - return `server://${tab.props.conid}`; - } - if (tab.props && tab.props.archiveFolder) { - return `archive://${tab.props.archiveFolder}`; - } - return '_no'; - } - function getDbIcon(key) { if (key.startsWith('database://')) return 'icon database'; if (key.startsWith('archive://')) return 'icon archive'; @@ -132,14 +119,22 @@ import FavoriteModal from '../modals/FavoriteModal.svelte'; import { showModal } from '../modals/modalTools'; - import { currentDatabase, getActiveTab, getOpenedTabs, openedTabs, activeTabId, getActiveTabId } from '../stores'; + import { + currentDatabase, + getActiveTab, + getOpenedTabs, + openedTabs, + activeTabId, + getActiveTabId, + tabDatabaseGroupOrder, + } from '../stores'; import tabs from '../tabs'; import { setSelectedTab } from '../utility/common'; import contextMenu from '../utility/contextMenu'; import getConnectionLabel from '../utility/getConnectionLabel'; import { isElectronAvailable } from '../utility/getElectron'; import { getConnectionInfo, useConnectionList } from '../utility/metadataLoaders'; - import { duplicateTab } from '../utility/openNewTab'; + import { duplicateTab, getTabDbKey } from '../utility/openNewTab'; import { useConnectionColorFactory } from '../utility/useConnectionColor'; $: connectionList = useConnectionList(); @@ -160,7 +155,7 @@ })); $: tabsByDb = _.groupBy(tabsWithDb, 'tabDbKey'); - $: dbKeys = _.keys(tabsByDb).sort(); + $: dbKeys = _.sortBy(_.keys(tabsByDb), [x => $tabDatabaseGroupOrder[x] || 0, x => x]); $: scrollInViewTab($activeTabId); @@ -265,12 +260,14 @@ {tabsByDb[dbKey][0].tabDbName} - closeWithSameDb(tabsByDb[dbKey][0].tabid)}> - - + {#if tabsByDb[dbKey].length > 1} + closeWithSameDb(tabsByDb[dbKey][0].tabid)}> + + + {/if}
- {#each _.sortBy(tabsByDb[dbKey], ['title', 'tabid']) as tab} + {#each _.sortBy(tabsByDb[dbKey], [x => x['tabOrder'] || 0, 'title', 'tabid']) as tab}