From 517db739ae0b1cf1a0ede99485f88e29d725ecf0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 29 Mar 2024 22:38:18 +0800 Subject: [PATCH 1/4] CB-4938 CB-4937 fix: metadata editor and shortcuts (#2520) --- .../core-blocks/src/Containers/Group.m.css | 17 ++++++-------- .../src/Containers/GroupTitle.m.css | 2 +- .../Users/UserForm/Info/UserFormInfoTeams.tsx | 2 +- .../src/TableViewer/TableGrid.m.css | 12 ++++++++++ .../src/TableViewer/TableGrid.tsx | 22 ++++++++++--------- .../src/Shortcuts/SHORTCUTS_DATA.ts | 4 ++-- .../plugin-help/src/Shortcuts/Shortcut.m.css | 1 + .../src/Shortcuts/ShortcutsDialog.m.css | 8 ------- .../src/Shortcuts/ShortcutsDialog.tsx | 8 +++---- .../ObjectPropertyTableFooterService.ts | 2 +- 10 files changed, 41 insertions(+), 37 deletions(-) create mode 100644 webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.m.css diff --git a/webapp/packages/core-blocks/src/Containers/Group.m.css b/webapp/packages/core-blocks/src/Containers/Group.m.css index c5f59ff949..5ccac992fe 100644 --- a/webapp/packages/core-blocks/src/Containers/Group.m.css +++ b/webapp/packages/core-blocks/src/Containers/Group.m.css @@ -18,7 +18,7 @@ padding: 24px; border-radius: var(--theme-group-element-radius); - > .groupTitle { + &.gap > .groupTitle { padding: 24px 0; margin: -24px 0; } @@ -26,7 +26,7 @@ &.dense { padding: 8px; - > .groupTitle { + &.gap > .groupTitle { padding: 8px 0; margin: -8px 0; } @@ -36,16 +36,13 @@ margin-right: 25%; } - &.box { - padding: 0; - overflow: hidden; - - > .groupTitle { - padding: 24px; - margin: 0; - } + &.box > .groupTitle { + padding: 24px; + margin: 0; } + &.box, + &.box.dense, &.boxNoOverflow { padding: 0; overflow: initial; diff --git a/webapp/packages/core-blocks/src/Containers/GroupTitle.m.css b/webapp/packages/core-blocks/src/Containers/GroupTitle.m.css index 6535b7892d..caa6f6d0b1 100644 --- a/webapp/packages/core-blocks/src/Containers/GroupTitle.m.css +++ b/webapp/packages/core-blocks/src/Containers/GroupTitle.m.css @@ -5,10 +5,10 @@ margin: 0; text-transform: uppercase; opacity: 0.9; - background-color: inherit; &.sticky { position: sticky; + background-color: inherit; top: 0; z-index: 1; opacity: 1; diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoTeams.tsx b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoTeams.tsx index 15b422da48..30c6b0638e 100644 --- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoTeams.tsx +++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoTeams.tsx @@ -32,7 +32,7 @@ export const UserFormInfoTeams = observer(function UserFormInfoTeams({ fo return ( <> {translate('authentication_user_team')} - + {teams.map(team => { const isDefault = team.teamId === defaultTeam; const label = `${team.teamId}${team.teamName && team.teamName !== team.teamId ? ' (' + team.teamName + ')' : ''}`; diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.m.css b/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.m.css new file mode 100644 index 0000000000..79cb87d56d --- /dev/null +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.m.css @@ -0,0 +1,12 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.presentation { + flex: 1; + overflow: auto; +} diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.tsx b/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.tsx index c989038793..f12a7d7562 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.tsx +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableGrid.tsx @@ -6,14 +6,14 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; -import styled, { css } from 'reshadow'; -import { TextPlaceholder } from '@cloudbeaver/core-blocks'; +import { s, TextPlaceholder } from '@cloudbeaver/core-blocks'; import type { ResultDataFormat } from '@cloudbeaver/core-sdk'; import type { IDatabaseDataModel } from '../DatabaseDataModel/IDatabaseDataModel'; import type { IDataPresentationOptions } from '../DataPresentationService'; import type { IDataTableActions } from './IDataTableActions'; +import styles from './TableGrid.m.css'; import { TableStatistics } from './TableStatistics'; interface Props { @@ -26,13 +26,6 @@ interface Props { isStatistics: boolean; } -const styles = css` - Presentation { - flex: 1; - overflow: auto; - } -`; - export const TableGrid = observer(function TableGrid({ model, actions, dataFormat, presentation, resultIndex, simple, isStatistics }) { if ((presentation.dataFormat !== undefined && dataFormat !== presentation.dataFormat) || !model.source.hasResult(resultIndex)) { if (model.isLoading()) { @@ -49,5 +42,14 @@ export const TableGrid = observer(function TableGrid({ model, actions, da return ; } - return styled(styles)(); + return ( + + ); }); diff --git a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts index 9ab17f4e02..a6ee2d7489 100644 --- a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts +++ b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts @@ -107,12 +107,12 @@ function transformKeys(keyBinding: IKeyBinding): string[] { function transformModToDisplayKey(key: string): string { const OS = getOS(); - if (OS === OperatingSystem.windowsOS || OperatingSystem.linuxOS) { + if (OS === OperatingSystem.windowsOS || OS === OperatingSystem.linuxOS) { return key.replace('MOD', 'CTRL'); } if (OS === OperatingSystem.macOS) { - return key.replace('MOD', 'CMD'); + return key.replace('MOD', 'CMD').replace('ALT', 'OPTION').replace('BACKSPACE', 'DELETE'); } return key; } diff --git a/webapp/packages/plugin-help/src/Shortcuts/Shortcut.m.css b/webapp/packages/plugin-help/src/Shortcuts/Shortcut.m.css index 4af5faf5a8..261e26843d 100644 --- a/webapp/packages/plugin-help/src/Shortcuts/Shortcut.m.css +++ b/webapp/packages/plugin-help/src/Shortcuts/Shortcut.m.css @@ -19,6 +19,7 @@ flex-shrink: 0; font-family: monospace; font-weight: bold; + text-transform: uppercase; width: max-content; padding: 4px 8px; } diff --git a/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.m.css b/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.m.css index 80eb2046cb..43d803daf5 100644 --- a/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.m.css +++ b/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.m.css @@ -3,14 +3,6 @@ } .container { composes: theme-typography--body2 from global; - gap: 32px; -} -.group { - gap: 16px; -} -.groupTitle, -.group { - padding: 0 !important; } .groupTitle { font-weight: bold; diff --git a/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.tsx b/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.tsx index 713e028ba8..54429dbfd4 100644 --- a/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.tsx +++ b/webapp/packages/plugin-help/src/Shortcuts/ShortcutsDialog.tsx @@ -33,8 +33,8 @@ export const ShortcutsDialog: DialogComponent = function ShortcutsDialog({ - - + + Data Viewer @@ -44,7 +44,7 @@ export const ShortcutsDialog: DialogComponent = function ShortcutsDialog({ ))} - + SQL Editor @@ -54,7 +54,7 @@ export const ShortcutsDialog: DialogComponent = function ShortcutsDialog({ ))} - + Navigation Tree diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts index b5219cac05..ef1f4bab21 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts @@ -28,7 +28,7 @@ export class ObjectPropertyTableFooterService { menus: [MENU_OBJECT_VIEWER_FOOTER], isApplicable: context => { const selected = context.tryGet(DATA_CONTEXT_NAV_NODES); - return selected !== undefined && !this.navTreeSettingsService.deleting; + return selected !== undefined && this.navTreeSettingsService.deleting; }, getItems: (_, items) => [...items, ACTION_DELETE], }); From 552163e6ee26a254e0a07d9a0e3954b7e6f1ef6b Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Fri, 29 Mar 2024 19:31:42 +0400 Subject: [PATCH 2/4] CB-4836 convert max idle time to seconds (#2514) Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../server/jetty/CBJettyServer.java | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java index 1a4cff4474..7a41073d7f 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java @@ -16,7 +16,6 @@ */ package io.cloudbeaver.server.jetty; -import io.cloudbeaver.model.app.WebServerConfigurationController; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBServerConfig; @@ -201,31 +200,19 @@ private void initSessionManager( } } - SessionHandler sessionHandler = new SessionHandler()/* { - public HttpCookie access(HttpSession session, boolean secure) { - HttpCookie cookie = getSessionCookie(session, _context == null ? "/" : (_context.getContextPath()), secure); - return cookie; - } - - @Override - public int getRefreshCookieAge() { - // Refresh cookie always (we need it for FA requests) - return 1; - } - }*/; - var maxIdleSeconds = application.getMaxSessionIdleTime(); + SessionHandler sessionHandler = new SessionHandler(); + var maxIdleTime = application.getMaxSessionIdleTime(); int intMaxIdleSeconds; - if (maxIdleSeconds > Integer.MAX_VALUE) { + if (maxIdleTime > Integer.MAX_VALUE) { log.warn("Max session idle time value is greater than Integer.MAX_VALUE. Integer.MAX_VALUE will be used instead"); - intMaxIdleSeconds = Integer.MAX_VALUE; - } else { - intMaxIdleSeconds = (int) maxIdleSeconds; + maxIdleTime = Integer.MAX_VALUE; } + intMaxIdleSeconds = (int) (maxIdleTime / 1000); + log.debug("Max http session idle time: " + intMaxIdleSeconds + "s"); sessionHandler.setMaxInactiveInterval(intMaxIdleSeconds); DefaultSessionCache sessionCache = new DefaultSessionCache(sessionHandler); FileSessionDataStore sessionStore = new FileSessionDataStore(); - sessionStore.setStoreDir(sessionCacheFolder.toFile()); sessionCache.setSessionDataStore(sessionStore); sessionHandler.setSessionCache(sessionCache); From 9f46e49e01300a5e158812ee0542a231a9fa8ccf Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 2 Apr 2024 17:44:17 +0800 Subject: [PATCH 3/4] CB-4776 fix: input default value handling (#2518) Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> --- .../src/FormControls/InputField/InputFieldState.tsx | 12 +++--------- .../src/FormControls/useFormStateControl.ts | 8 ++++---- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/webapp/packages/core-blocks/src/FormControls/InputField/InputFieldState.tsx b/webapp/packages/core-blocks/src/FormControls/InputField/InputFieldState.tsx index 3fdb281932..401968cd95 100644 --- a/webapp/packages/core-blocks/src/FormControls/InputField/InputFieldState.tsx +++ b/webapp/packages/core-blocks/src/FormControls/InputField/InputFieldState.tsx @@ -29,14 +29,8 @@ export const InputFieldState: InputFieldType = observer - ); + const defaultValue = rest.type === 'password' ? null : controlState.defaultStringValue; + + return ; }), ) as InputFieldType; diff --git a/webapp/packages/core-blocks/src/FormControls/useFormStateControl.ts b/webapp/packages/core-blocks/src/FormControls/useFormStateControl.ts index 7d7febcf41..436875f942 100644 --- a/webapp/packages/core-blocks/src/FormControls/useFormStateControl.ts +++ b/webapp/packages/core-blocks/src/FormControls/useFormStateControl.ts @@ -47,14 +47,14 @@ export function useFormStateControl, TKey ext value = value[name]; } - let stringValue: string | typeof value; - let defaultStringValue: string | typeof defaultValue; + let stringValue: string | typeof value | null; + let defaultStringValue: string | typeof defaultValue | null; if (mapToString) { stringValue = mapToString(value as any); defaultStringValue = mapToString(defaultValue as any); } else { - stringValue = isNotNullDefined(value) ? String(value) : ''; - defaultStringValue = isNotNullDefined(defaultValue) ? String(defaultValue) : ''; + stringValue = isNotNullDefined(value) ? String(value) : null; + defaultStringValue = isNotNullDefined(defaultValue) ? String(defaultValue) : null; } const hide = 'autoHide' in rest && !!rest.autoHide && presented === false; From 44b6f8a3ae147e003abcd07826e246e5c5f224e0 Mon Sep 17 00:00:00 2001 From: sergeyteleshev Date: Tue, 2 Apr 2024 11:55:42 +0200 Subject: [PATCH 4/4] Cb 4548 sql editor resultsets can be closed one by one only when execute sql statement has been used for several queries (#2503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * CB-4548 fix: removes all result tabs on "close all" action * CB-4548 adds "close all of the same query" action for sql result tabs * Revert "CB-4548 adds "close all of the same query" action for sql result tabs" This reverts commit 453664e41c35cc893eae1021747f0de1dd19a2e5. * CB-4548 adds close all of the same group * CB-4548 adds handleCloseTabGroup with SqlResultTabService * CB-4548 sql editor bootstrap cleanup * СB-4548 group tabs logic moved logic to sql-editor-plugin * СB-4548 cleanup * CB-4548 adds ACTION_TAB_CLOSE_SQL_RESULT_GROUP to the end of the tabs * CB-4548 closes group tabs via tabs context close function (to save highlight tab logic) * CB-4548 pr fixes * CB-4548 code cleanup --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../src/ACTION_TAB_CLOSE_SQL_RESULT_GROUP.ts | 13 +++ .../src/SqlEditorGroupTabsBootstrap.ts | 88 +++++++++++++++++++ .../src/SqlResultTabs/SqlResultTabs.tsx | 4 +- .../src/SqlResultTabs/SqlResultTabsService.ts | 4 + .../plugin-sql-editor/src/locales/en.ts | 1 + .../plugin-sql-editor/src/locales/it.ts | 1 + .../plugin-sql-editor/src/locales/ru.ts | 1 + .../plugin-sql-editor/src/locales/zh.ts | 1 + .../plugin-sql-editor/src/manifest.ts | 4 +- 9 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 webapp/packages/plugin-sql-editor/src/ACTION_TAB_CLOSE_SQL_RESULT_GROUP.ts create mode 100644 webapp/packages/plugin-sql-editor/src/SqlEditorGroupTabsBootstrap.ts diff --git a/webapp/packages/plugin-sql-editor/src/ACTION_TAB_CLOSE_SQL_RESULT_GROUP.ts b/webapp/packages/plugin-sql-editor/src/ACTION_TAB_CLOSE_SQL_RESULT_GROUP.ts new file mode 100644 index 0000000000..6f50822b05 --- /dev/null +++ b/webapp/packages/plugin-sql-editor/src/ACTION_TAB_CLOSE_SQL_RESULT_GROUP.ts @@ -0,0 +1,13 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createAction } from '@cloudbeaver/core-view'; + +export const ACTION_TAB_CLOSE_SQL_RESULT_GROUP = createAction('tab-close-sql-result-group', { + label: 'plugin_sql_editor_action_close_group', + tooltip: 'plugin_sql_editor_action_close_group', +}); diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditorGroupTabsBootstrap.ts b/webapp/packages/plugin-sql-editor/src/SqlEditorGroupTabsBootstrap.ts new file mode 100644 index 0000000000..3f1404ee55 --- /dev/null +++ b/webapp/packages/plugin-sql-editor/src/SqlEditorGroupTabsBootstrap.ts @@ -0,0 +1,88 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import type { IDataContextProvider } from '@cloudbeaver/core-data-context'; +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { DATA_CONTEXT_TABS_CONTEXT, MENU_TAB } from '@cloudbeaver/core-ui'; +import { ActionService, DATA_CONTEXT_MENU, menuExtractItems, MenuService } from '@cloudbeaver/core-view'; + +import { ACTION_TAB_CLOSE_SQL_RESULT_GROUP } from './ACTION_TAB_CLOSE_SQL_RESULT_GROUP'; +import { DATA_CONTEXT_SQL_EDITOR_STATE } from './DATA_CONTEXT_SQL_EDITOR_STATE'; +import { DATA_CONTEXT_SQL_EDITOR_RESULT_ID } from './SqlResultTabs/DATA_CONTEXT_SQL_EDITOR_RESULT_ID'; +import { SqlResultTabsService } from './SqlResultTabs/SqlResultTabsService'; + +@injectable() +export class SqlEditorGroupTabsBootstrap extends Bootstrap { + constructor( + private readonly actionService: ActionService, + private readonly menuService: MenuService, + private readonly sqlResultTabsService: SqlResultTabsService, + ) { + super(); + } + + register(): void { + this.menuService.addCreator({ + isApplicable: context => { + const tab = context.tryGet(DATA_CONTEXT_SQL_EDITOR_RESULT_ID); + const state = context.tryGet(DATA_CONTEXT_TABS_CONTEXT); + const menu = context.hasValue(DATA_CONTEXT_MENU, MENU_TAB); + return !!tab && !!state?.enabledBaseActions && menu; + }, + getItems: (context, items) => [...items, ACTION_TAB_CLOSE_SQL_RESULT_GROUP], + orderItems: (context, items) => { + const actions = menuExtractItems(items, [ACTION_TAB_CLOSE_SQL_RESULT_GROUP]); + + if (actions.length > 0) { + items.push(...actions); + } + + return items; + }, + }); + + this.actionService.addHandler({ + id: 'result-tabs-group-base-handler', + isActionApplicable: (context, action) => { + const menu = context.hasValue(DATA_CONTEXT_MENU, MENU_TAB); + const tab = context.tryGet(DATA_CONTEXT_SQL_EDITOR_RESULT_ID); + const sqlEditorState = context.tryGet(DATA_CONTEXT_SQL_EDITOR_STATE); + + const groupId = sqlEditorState?.resultTabs.find(tabState => tabState.tabId === tab?.id)?.groupId; + const hasTabsInGroup = (sqlEditorState?.resultTabs.filter(tabState => tabState.groupId === groupId) ?? []).length > 1; + + if (!menu || !tab || !hasTabsInGroup) { + return false; + } + return [ACTION_TAB_CLOSE_SQL_RESULT_GROUP].includes(action); + }, + handler: async (context, action) => { + switch (action) { + case ACTION_TAB_CLOSE_SQL_RESULT_GROUP: + this.closeResultTabGroup(context); + break; + default: + break; + } + }, + }); + } + + async closeResultTabGroup(context: IDataContextProvider) { + const tab = context.get(DATA_CONTEXT_SQL_EDITOR_RESULT_ID); + const sqlEditorState = context.get(DATA_CONTEXT_SQL_EDITOR_STATE); + const tabsContext = context.get(DATA_CONTEXT_TABS_CONTEXT); + const resultTabs = this.sqlResultTabsService.getResultTabs(sqlEditorState); + + const resultTab = resultTabs.find(tabState => tabState.tabId === tab.id); + const groupResultTabs = resultTabs.filter(tab => tab.groupId === resultTab?.groupId); + + groupResultTabs.forEach(groupTab => { + tabsContext.close(groupTab.tabId); + }); + } +} diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx index 6bd6186df7..1678ab91d5 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx +++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx @@ -57,8 +57,8 @@ export const SqlResultTabs = observer(function SqlDataResult({ state, onT onTabSelect?.(tab.tabId); } - async function handleClose(tab: ITabData) { - const canClose = await sqlResultTabsService.canCloseResultTab(state, tab.tabId); + function handleClose(tab: ITabData) { + const canClose = handleCanClose(tab); if (canClose) { sqlResultTabsService.removeResultTab(state, tab.tabId); diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts index 33d3f0f22b..5e440fea85 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts @@ -28,6 +28,10 @@ export class SqlResultTabsService { }); } + getResultTabs(state: ISqlEditorTabState) { + return state.resultTabs; + } + async canCloseResultTab(state: ISqlEditorTabState, tabId: string): Promise { const tab = state.tabs.find(tab => tab.id === tabId); diff --git a/webapp/packages/plugin-sql-editor/src/locales/en.ts b/webapp/packages/plugin-sql-editor/src/locales/en.ts index 7f917f67eb..fb9b799386 100644 --- a/webapp/packages/plugin-sql-editor/src/locales/en.ts +++ b/webapp/packages/plugin-sql-editor/src/locales/en.ts @@ -38,4 +38,5 @@ export default [ ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ['plugin_sql_editor_action_overlay_title', 'Action required'], ['plugin_sql_editor_action_overlay_description', 'Please reopen editor to continue working.'], + ['plugin_sql_editor_action_close_group', 'Close all of the same query'], ]; diff --git a/webapp/packages/plugin-sql-editor/src/locales/it.ts b/webapp/packages/plugin-sql-editor/src/locales/it.ts index 94cc6e0ed2..9f8d490f3f 100644 --- a/webapp/packages/plugin-sql-editor/src/locales/it.ts +++ b/webapp/packages/plugin-sql-editor/src/locales/it.ts @@ -31,4 +31,5 @@ export default [ ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ['plugin_sql_editor_action_overlay_title', 'Action required'], ['plugin_sql_editor_action_overlay_description', 'Please reopen editor to continue working.'], + ['plugin_sql_editor_action_close_group', 'Close all of the same query'], ]; diff --git a/webapp/packages/plugin-sql-editor/src/locales/ru.ts b/webapp/packages/plugin-sql-editor/src/locales/ru.ts index 5ad624d04f..5c9c223d44 100644 --- a/webapp/packages/plugin-sql-editor/src/locales/ru.ts +++ b/webapp/packages/plugin-sql-editor/src/locales/ru.ts @@ -35,4 +35,5 @@ export default [ ['sql_editor_close_result_tabs_dialog_title', 'Подтвердить закрытие вкладок'], ['plugin_sql_editor_action_overlay_title', 'Требуется действие'], ['plugin_sql_editor_action_overlay_description', 'Пожалуйста, перезапустите редактор для продолжения работы.'], + ['plugin_sql_editor_action_close_group', 'Закрыть все из этого запроса'], ]; diff --git a/webapp/packages/plugin-sql-editor/src/locales/zh.ts b/webapp/packages/plugin-sql-editor/src/locales/zh.ts index 477e7e9370..b2180f639a 100644 --- a/webapp/packages/plugin-sql-editor/src/locales/zh.ts +++ b/webapp/packages/plugin-sql-editor/src/locales/zh.ts @@ -35,4 +35,5 @@ export default [ ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ['plugin_sql_editor_action_overlay_title', 'Action required'], ['plugin_sql_editor_action_overlay_description', 'Please reopen editor to continue working.'], + ['plugin_sql_editor_action_close_group', 'Close all of the same query'], ]; diff --git a/webapp/packages/plugin-sql-editor/src/manifest.ts b/webapp/packages/plugin-sql-editor/src/manifest.ts index 79c73a471b..2e08e5e942 100644 --- a/webapp/packages/plugin-sql-editor/src/manifest.ts +++ b/webapp/packages/plugin-sql-editor/src/manifest.ts @@ -12,15 +12,16 @@ import { MenuBootstrap } from './MenuBootstrap'; import { LocalStorageSqlDataSourceBootstrap } from './SqlDataSource/LocalStorage/LocalStorageSqlDataSourceBootstrap'; import { SqlDataSourceService } from './SqlDataSource/SqlDataSourceService'; import { SqlDialectInfoService } from './SqlDialectInfoService'; +import { SqlEditorGroupTabsBootstrap } from './SqlEditorGroupTabsBootstrap'; import { SqlEditorModeService } from './SqlEditorModeService'; import { SqlEditorService } from './SqlEditorService'; import { SqlEditorSettingsService } from './SqlEditorSettingsService'; import { SqlEditorView } from './SqlEditorView'; import { SqlExecutionPlanService } from './SqlResultTabs/ExecutionPlan/SqlExecutionPlanService'; -import { OutputMenuBootstrap } from './SqlResultTabs/OutputLogs/OutputMenuBootstrap'; import { OutputLogsEventHandler } from './SqlResultTabs/OutputLogs/OutputLogsEventHandler'; import { OutputLogsResource } from './SqlResultTabs/OutputLogs/OutputLogsResource'; import { OutputLogsService } from './SqlResultTabs/OutputLogs/OutputLogsService'; +import { OutputMenuBootstrap } from './SqlResultTabs/OutputLogs/OutputMenuBootstrap'; import { SqlQueryResultService } from './SqlResultTabs/SqlQueryResultService'; import { SqlQueryService } from './SqlResultTabs/SqlQueryService'; import { SqlResultTabsService } from './SqlResultTabs/SqlResultTabsService'; @@ -48,5 +49,6 @@ export const sqlEditorPluginManifest: PluginManifest = { OutputLogsResource, OutputLogsService, OutputMenuBootstrap, + SqlEditorGroupTabsBootstrap, ], };