diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index b1f956c37..b661e4f63 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -58,6 +58,7 @@ 'icon auth': 'mdi mdi-account-key', 'icon version': 'mdi mdi-ticket-confirmation', 'icon pin': 'mdi mdi-pin', + 'icon pin-outline': 'mdi mdi-pin-outline', 'icon arrange': 'mdi mdi-arrange-send-to-back', 'icon app': 'mdi mdi-layers-triple', 'icon open-in-new': 'mdi mdi-open-in-new', diff --git a/packages/web/src/tabpanel/TabsPanel.svelte b/packages/web/src/tabpanel/TabsPanel.svelte index c38305bdf..7a0a34ca6 100644 --- a/packages/web/src/tabpanel/TabsPanel.svelte +++ b/packages/web/src/tabpanel/TabsPanel.svelte @@ -27,37 +27,44 @@ }); } - const closeTabFunc = closeCondition => async tabid => { - const activeCandidate = getOpenedTabs().find(x => x.tabid == tabid); - const closeCandidates = getOpenedTabs() - .filter(x => closeCondition(x, activeCandidate)) - .filter(x => x.unsaved) - .filter(x => shouldShowTab(x)); + const closeTabFunc = + (closeCondition, afterOperation = null) => + async tabid => { + const activeCandidate = getOpenedTabs().find(x => x.tabid == tabid); + const closeCandidates = getOpenedTabs() + .filter(x => closeCondition(x, activeCandidate)) + .filter(x => x.unsaved) + .filter(x => shouldShowTab(x)); - if (!(await allowCloseTabs(closeCandidates))) return; + if (!(await allowCloseTabs(closeCandidates))) return; - openedTabs.update(files => { - const active = files.find(x => x.tabid == tabid); - if (!active) return files; + openedTabs.update(files => { + const active = files.find(x => x.tabid == tabid); + if (!active) return files; - const newFiles = files.map(x => ({ - ...x, - closedTime: shouldShowTab(x) && closeCondition(x, active) ? new Date().getTime() : x.closedTime, - selected: false, - })); + const newFiles = files.map(x => ({ + ...x, + closedTime: shouldShowTab(x) && closeCondition(x, active) ? new Date().getTime() : x.closedTime, + selected: false, + })); - if (newFiles.find(x => x.selected && shouldShowTab(x))) { - return newFiles; - } + if (newFiles.find(x => x.selected && shouldShowTab(x))) { + return newFiles; + } - const selectedIndex = _.findLastIndex(newFiles, x => shouldShowTab(x)); + const selectedIndex = _.findLastIndex(newFiles, x => shouldShowTab(x)); - return newFiles.map((x, index) => ({ - ...x, - selected: index == selectedIndex, - })); - }); - }; + const res = newFiles.map((x, index) => ({ + ...x, + selected: index == selectedIndex, + })); + + if (afterOperation) { + return afterOperation(res); + } + return res; + }); + }; export const closeMultipleTabs = async (closeCondition, deleteFromHistory = false) => { const closeCandidates = getOpenedTabs() @@ -128,6 +135,10 @@ })) ); }; + const pinTab = tabid => { + openedTabs.update(tabs => tabs.map(x => (x.tabid == tabid ? { ...x, tabPreviewMode: false } : x))); + }; + const closeTabsWithCurrentDb = () => { const db = getCurrentDatabase(); closeMultipleTabs(tab => { @@ -154,7 +165,10 @@ _.get(x, 'props.database') != _.get(active, 'props.database') ); const closeOthersInMultiTab = multiTabIndex => - closeTabFunc((x, active) => x.tabid != active.tabid && (x.multiTabIndex || 0) == multiTabIndex); + closeTabFunc( + (x, active) => x.tabid != active.tabid && (x.multiTabIndex || 0) == multiTabIndex, + tabs => tabs.map(x => (x.selected ? { ...x, tabPreviewMode: false } : x)) + ); const reopenClosedTab = () => { const lastClosedTabId = getOpenedTabs() .filter(x => x.closedTime) @@ -396,6 +410,10 @@ const appobj = appObject ? appObjectTypes[appObject] : null; return [ + tab.tabPreviewMode && { + text: 'Pin tab', + onClick: () => pinTab(tabid), + }, { text: 'Close', onClick: () => closeTab(tabid), @@ -639,6 +657,15 @@ $draggingTabTarget = null; }} > + {#if tab.tabPreviewMode} + pinTab(tab.tabid)} + title="This tab is in preview mode, it will be replaced eg. when clicking table. Click to switch to normal mode. You could also double-click tab header." + > + + + {/if} {tab.title} @@ -775,4 +802,13 @@ .tab-group-button:hover { color: var(--theme-font-1); } + + .pin-button { + color: var(--theme-font-3); + cursor: pointer; + } + + .pin-button:hover { + color: var(--theme-font-1); + }