From 614ed789b9cbe358447390aac1c7002dfafd79a1 Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Tue, 7 Dec 2021 19:55:36 +0300 Subject: [PATCH 1/2] feat(plugin-sql-editor): CB-1284 close tabs on executing new query --- .../src/locales/en.ts | 1 + .../src/locales/it.ts | 1 + .../src/locales/ru.ts | 1 + .../src/locales/zh.ts | 43 ++++++++++--------- .../src/SqlEditor/SqlEditorController.tsx | 29 ++++++++++--- .../src/SqlResultTabs/SqlResultTabsService.ts | 32 +++++++++++--- 6 files changed, 74 insertions(+), 33 deletions(-) diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts index 1781333db8..12dac07b96 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts @@ -19,4 +19,5 @@ export default [ ['sql_editor_download_script_tooltip', 'Download sql script'], ['sql_editor_upload_script_unsaved_changes_dialog_message', 'Your current script will be overwritten by the uploaded script. Do you want to save it first?'], ['sql_editor_upload_script_max_size_title', 'File size exceeds max size'], + ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts index dffd7a63a6..21c35558e5 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts @@ -15,4 +15,5 @@ export default [ ['sql_execution_plan_properties_panel_value', 'Valore'], ['sql_execution_plan_properties_panel_general', 'Generale'], ['sql_execution_plan_properties_panel_details', 'Dettagli'], + ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts index 891f3c5f2f..962b437f83 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts @@ -19,4 +19,5 @@ export default [ ['sql_editor_download_script_tooltip', 'Скачать sql скрипт'], ['sql_editor_upload_script_unsaved_changes_dialog_message', 'Текущий скрипт будет перезаписан загруженным. Сохранить текущий?'], ['sql_editor_upload_script_max_size_title', 'Размер файла превышает максимально допустимый'], + ['sql_editor_close_result_tabs_dialog_title', 'Закрыть лишние вкладки'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts index 322fcd8ba2..65d49f2477 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts @@ -1,22 +1,23 @@ export default [ - ['sql_editor_menu', 'SQL编辑器'], - ['sql_editor_placeholder', '使用Ctrl + Enter执行查询以查看结果'], - ['sql_editor_execution_plan_button_tooltip', '解释执行计划(Shift + Ctrl + E)'], - ['sql_editor_sql_execution_button_tooltip', '执行SQL语句(Ctrl + Enter)'], - ['sql_editor_sql_execution_new_tab_button_tooltip', '在新选项卡中执行SQL语句(Ctrl + \\)(Shift + Ctrl + Enter)'], - ['sql_editor_sql_execution_script_button_tooltip', '执行SQL脚本(Alt + X)'], - ['sql_editor_sql_format_button_tooltip', '格式化SQL脚本(Shift + Ctrl + F)'], - ['sql_editor_sql_statistics_unavailable', '统计不可用'], - ['sql_editor_sql_execution_queries', '查询:'], - ['sql_editor_sql_execution_executing', '执行...'], - ['sql_execution_plan_placeholder', '执行计划为空'], - ['sql_execution_plan_properties_panel_placeholder', '没有要显示的项目'], - ['sql_execution_plan_properties_panel_name', '名称'], - ['sql_execution_plan_properties_panel_value', '值'], - ['sql_execution_plan_properties_panel_general', '一般'], - ['sql_execution_plan_properties_panel_details', '详情'], - ['sql_editor_upload_script_tooltip', '上传SQL脚本'], - ['sql_editor_download_script_tooltip', '下载SQL脚本'], - ['sql_editor_upload_script_unsaved_changes_dialog_message', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'], - ['sql_editor_upload_script_max_size_title', '文件大小超过最大大小'], - ]; + ['sql_editor_menu', 'SQL编辑器'], + ['sql_editor_placeholder', '使用Ctrl + Enter执行查询以查看结果'], + ['sql_editor_execution_plan_button_tooltip', '解释执行计划(Shift + Ctrl + E)'], + ['sql_editor_sql_execution_button_tooltip', '执行SQL语句(Ctrl + Enter)'], + ['sql_editor_sql_execution_new_tab_button_tooltip', '在新选项卡中执行SQL语句(Ctrl + \\)(Shift + Ctrl + Enter)'], + ['sql_editor_sql_execution_script_button_tooltip', '执行SQL脚本(Alt + X)'], + ['sql_editor_sql_format_button_tooltip', '格式化SQL脚本(Shift + Ctrl + F)'], + ['sql_editor_sql_statistics_unavailable', '统计不可用'], + ['sql_editor_sql_execution_queries', '查询:'], + ['sql_editor_sql_execution_executing', '执行...'], + ['sql_execution_plan_placeholder', '执行计划为空'], + ['sql_execution_plan_properties_panel_placeholder', '没有要显示的项目'], + ['sql_execution_plan_properties_panel_name', '名称'], + ['sql_execution_plan_properties_panel_value', '值'], + ['sql_execution_plan_properties_panel_general', '一般'], + ['sql_execution_plan_properties_panel_details', '详情'], + ['sql_editor_upload_script_tooltip', '上传SQL脚本'], + ['sql_editor_download_script_tooltip', '下载SQL脚本'], + ['sql_editor_upload_script_unsaved_changes_dialog_message', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'], + ['sql_editor_upload_script_max_size_title', '文件大小超过最大大小'], + ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], +]; diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx b/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx index e3864d4ffd..0e635328f3 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx +++ b/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx @@ -20,6 +20,7 @@ import type { IControlledCodeMirror } from 'react-codemirror2'; import { ConnectionExecutionContextService } from '@cloudbeaver/core-connections'; import { IDestructibleController, IInitializableController, injectable } from '@cloudbeaver/core-di'; +import { CommonDialogService, ConfirmationDialog, DialogueStateResult } from '@cloudbeaver/core-dialogs'; import type { SqlDialectInfo } from '@cloudbeaver/core-sdk'; import { throttleAsync } from '@cloudbeaver/core-utils'; @@ -29,6 +30,7 @@ import { SqlEditorService } from '../SqlEditorService'; import { ISQLScriptSegment, SQLParser } from '../SQLParser'; import { SqlExecutionPlanService } from '../SqlResultTabs/ExecutionPlan/SqlExecutionPlanService'; import { SqlQueryService } from '../SqlResultTabs/SqlQueryService'; +import { SqlResultTabsService } from '../SqlResultTabs/SqlResultTabsService'; const closeCharacters = /[\s()[\]{};:>,=\\*]/; @@ -113,11 +115,13 @@ export class SqlEditorController implements IInitializableController, IDestructi private reactionDisposer: IReactionDisposer | null; constructor( - private connectionExecutionContextService: ConnectionExecutionContextService, - private sqlQueryService: SqlQueryService, - private sqlDialectInfoService: SqlDialectInfoService, - private sqlEditorService: SqlEditorService, - private sqlExecutionPlanService: SqlExecutionPlanService, + private readonly connectionExecutionContextService: ConnectionExecutionContextService, + private readonly sqlQueryService: SqlQueryService, + private readonly sqlDialectInfoService: SqlDialectInfoService, + private readonly sqlEditorService: SqlEditorService, + private readonly sqlExecutionPlanService: SqlExecutionPlanService, + private readonly sqlResultTabsService: SqlResultTabsService, + private readonly commonDialogService: CommonDialogService ) { this.parser = new SQLParser(); this.getHandleAutocomplete = this.getHandleAutocomplete.bind(this); @@ -228,6 +232,21 @@ export class SqlEditorController implements IInitializableController, IDestructi return; } + if (this.state.tabs.length) { + const result = await this.commonDialogService.open(ConfirmationDialog, { + title: 'sql_editor_close_result_tabs_dialog_title', + message: `There are unclosed result tabs: "${this.state.tabs.length}". Do you want to close these tabs before executing new query?`, + confirmActionText: 'ui_yes', + extraStatus: 'no', + }); + + if (result === DialogueStateResult.Resolved) { + this.sqlResultTabsService.removeResultTabs(this.state); + } else if (result === DialogueStateResult.Rejected) { + return; + } + } + this.beforeExecute(); try { this.executingScript = true; diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts index efb3b3d70c..d97350731b 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabsService.ts @@ -6,9 +6,11 @@ * you may not use this file except in compliance with the License. */ +import { action, makeObservable } from 'mobx'; + import { injectable } from '@cloudbeaver/core-di'; -import type { ISqlEditorTabState } from '../ISqlEditorTabState'; +import type { ISqlEditorTabState, ISqlEditorResultTab } from '../ISqlEditorTabState'; import { SqlExecutionPlanService } from './ExecutionPlan/SqlExecutionPlanService'; import { SqlQueryResultService } from './SqlQueryResultService'; import { SqlQueryService } from './SqlQueryService'; @@ -19,7 +21,11 @@ export class SqlResultTabsService { private sqlQueryService: SqlQueryService, private sqlQueryResultService: SqlQueryResultService, private sqlExecutionPlanService: SqlExecutionPlanService, - ) { } + ) { + makeObservable(this, { + removeResultTabs: action, + }); + } selectResultTab(state: ISqlEditorTabState, resultId: string): void { state.currentTabId = resultId; @@ -29,14 +35,26 @@ export class SqlResultTabsService { const tab = state.tabs.find(tab => tab.id === tabId); if (tab) { - state.tabs.splice(state.tabs.indexOf(tab), 1); + this.removeTab(state, tab); + } else { + console.warn(`Unable to remove tab. Tab with id="${tabId}" was not found`); } + } - this.sqlQueryService.removeStatisticsTab(state, tabId); - this.sqlQueryResultService.removeResultTab(state, tabId); - this.sqlExecutionPlanService.removeExecutionPlanTab(state, tabId); + removeResultTabs(state: ISqlEditorTabState): void { + for (const tab of state.tabs.slice()) { + this.removeTab(state, tab); + } + } - if (state.currentTabId === tabId) { + private removeTab(state: ISqlEditorTabState, tab: ISqlEditorResultTab) { + state.tabs.splice(state.tabs.indexOf(tab), 1); + + this.sqlQueryService.removeStatisticsTab(state, tab.id); + this.sqlQueryResultService.removeResultTab(state, tab.id); + this.sqlExecutionPlanService.removeExecutionPlanTab(state, tab.id); + + if (state.currentTabId === tab.id) { if (state.tabs.length > 0) { state.currentTabId = state.tabs[0].id; } else { From b9e3d9fcb04de69f1ee535603a6950be014d7fda Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Tue, 7 Dec 2021 20:53:15 +0300 Subject: [PATCH 2/2] feat(plugin-sql-editor): CB-1284 locale changes --- .../packages/plugin-sql-editor-navigation-tab/src/locales/en.ts | 2 +- .../packages/plugin-sql-editor-navigation-tab/src/locales/it.ts | 2 +- .../packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts | 2 +- .../packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts | 2 +- .../plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts index 12dac07b96..65312bc376 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/en.ts @@ -19,5 +19,5 @@ export default [ ['sql_editor_download_script_tooltip', 'Download sql script'], ['sql_editor_upload_script_unsaved_changes_dialog_message', 'Your current script will be overwritten by the uploaded script. Do you want to save it first?'], ['sql_editor_upload_script_max_size_title', 'File size exceeds max size'], - ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], + ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts index 21c35558e5..a58e5b971f 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/it.ts @@ -15,5 +15,5 @@ export default [ ['sql_execution_plan_properties_panel_value', 'Valore'], ['sql_execution_plan_properties_panel_general', 'Generale'], ['sql_execution_plan_properties_panel_details', 'Dettagli'], - ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], + ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts index 962b437f83..66baf076a4 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/ru.ts @@ -19,5 +19,5 @@ export default [ ['sql_editor_download_script_tooltip', 'Скачать sql скрипт'], ['sql_editor_upload_script_unsaved_changes_dialog_message', 'Текущий скрипт будет перезаписан загруженным. Сохранить текущий?'], ['sql_editor_upload_script_max_size_title', 'Размер файла превышает максимально допустимый'], - ['sql_editor_close_result_tabs_dialog_title', 'Закрыть лишние вкладки'], + ['sql_editor_close_result_tabs_dialog_title', 'Подтвердить закрытие вкладок'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts index 65d49f2477..624a51f6f1 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/locales/zh.ts @@ -19,5 +19,5 @@ export default [ ['sql_editor_download_script_tooltip', '下载SQL脚本'], ['sql_editor_upload_script_unsaved_changes_dialog_message', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'], ['sql_editor_upload_script_max_size_title', '文件大小超过最大大小'], - ['sql_editor_close_result_tabs_dialog_title', 'Close extra tabs'], + ['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'], ]; diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx b/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx index 0e635328f3..160eca6017 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx +++ b/webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditorController.tsx @@ -235,7 +235,7 @@ export class SqlEditorController implements IInitializableController, IDestructi if (this.state.tabs.length) { const result = await this.commonDialogService.open(ConfirmationDialog, { title: 'sql_editor_close_result_tabs_dialog_title', - message: `There are unclosed result tabs: "${this.state.tabs.length}". Do you want to close these tabs before executing new query?`, + message: `Do you want to close ${this.state.tabs.length} tabs before executing script?`, confirmActionText: 'ui_yes', extraStatus: 'no', });