CB-4236 feat: script reopen (#2324)

Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
Alexey
2024-01-25 17:40:31 +03:00
committed by GitHub
co-authored by Daria Marutkina
parent 3c4f4a988d
commit ba3ca5e28a
13 changed files with 110 additions and 18 deletions
@@ -1,14 +1,15 @@
.message {
flex-shrink: 0;
padding: 24px 0px 24px 24px;
overflow: auto;
flex: 1;
flex-shrink: 0;
padding: 24px 0px 24px 24px;
overflow: auto;
white-space: pre-wrap;
flex: 1;
&:not(:first-child) {
padding-top: 0px;
}
&:not(:first-child) {
padding-top: 0px;
}
}
.messageBox {
padding-right: 24px;
padding-right: 24px;
}
@@ -36,6 +36,7 @@ export default [
['ui_clear', 'Clear'],
['ui_remove', 'Remove'],
['ui_close', 'Close'],
['ui_open', 'Open'],
['ui_errors_details', 'Details'],
['ui_search', 'Search...'],
['ui_delete', 'Delete'],
@@ -33,6 +33,7 @@ export default [
['ui_clear', 'Clear'],
['ui_remove', 'Remove'],
['ui_close', 'Chiudi'],
['ui_open', 'Open'],
['ui_errors_details', 'Dettagli'],
['ui_search', 'Cerca...'],
['ui_delete', 'Elimina'],
@@ -32,6 +32,7 @@ export default [
['ui_clear', 'Очистить'],
['ui_remove', 'Убрать'],
['ui_close', 'Закрыть'],
['ui_open', 'Открыть'],
['ui_errors_details', 'Информация'],
['ui_search', 'Поиск...'],
['ui_delete', 'Удалить'],
@@ -33,6 +33,7 @@ export default [
['ui_clear', 'Clear'],
['ui_remove', 'Remove'],
['ui_close', '关闭'],
['ui_open', 'Open'],
['ui_errors_details', '详情'],
['ui_search', '搜索...'],
['ui_delete', '删除'],
@@ -23,16 +23,19 @@ const SOURCE_HISTORY = 'history';
@staticImplements<ISqlDataSourceKey>()
export abstract class BaseSqlDataSource implements ISqlDataSource {
static key = 'base';
abstract get name(): string | null;
message?: string;
abstract get script(): string;
abstract get baseScript(): string;
abstract get baseExecutionContext(): IConnectionExecutionContextInfo | undefined;
abstract get executionContext(): IConnectionExecutionContextInfo | undefined;
databaseModels: IDatabaseDataModel<IDataQueryOptions, IDatabaseResultSet>[];
exception?: Error | Error[] | null | undefined;
message?: string;
incomingScript: string | undefined;
incomingExecutionContext: IConnectionExecutionContextInfo | undefined | null;
exception?: Error | Error[] | null | undefined;
get isIncomingChanges(): boolean {
return this.incomingScript !== undefined || this.incomingExecutionContext !== null;
@@ -178,6 +181,10 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
// }
}
isOpened(): boolean {
return true;
}
isError(): boolean {
return isContainsException(this.exception);
}
@@ -255,6 +262,10 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
this.markUpdated();
}
open(): Promise<void> | void {
this.markUpdated();
}
reset(): Promise<void> | void {
this.setScript(this.baseScript);
this.setExecutionContext(this.baseExecutionContext);
@@ -24,34 +24,44 @@ export interface ISetScriptData {
}
export interface ISqlDataSource extends ILoadableState {
readonly sourceKey: string;
readonly name: string | null;
readonly icon?: string;
readonly emptyPlaceholder?: string;
readonly message?: string;
readonly sourceKey: string;
readonly projectId: string | null;
readonly script: string;
readonly incomingScript?: string;
readonly projectId: string | null;
readonly history: ISqlDataSourceHistory;
readonly databaseModels: IDatabaseDataModel<IDataQueryOptions, IDatabaseResultSet>[];
readonly executionContext?: IConnectionExecutionContextInfo;
readonly message?: string;
readonly onUpdate: ISyncExecutor;
readonly onSetScript: ISyncExecutor<ISetScriptData>;
readonly onDatabaseModelUpdate: ISyncExecutor<IDatabaseDataModel<IDataQueryOptions, IDatabaseResultSet>[]>;
readonly features: ESqlDataSourceFeatures[];
readonly history: ISqlDataSourceHistory;
readonly isAutoSaveEnabled: boolean;
readonly isIncomingChanges: boolean;
readonly isSaved: boolean;
readonly isScriptSaved: boolean;
readonly isExecutionContextSaved: boolean;
readonly onUpdate: ISyncExecutor;
readonly onSetScript: ISyncExecutor<ISetScriptData>;
readonly onDatabaseModelUpdate: ISyncExecutor<IDatabaseDataModel<IDataQueryOptions, IDatabaseResultSet>[]>;
isOpened(): boolean;
isReadonly(): boolean;
isEditing(): boolean;
isOutdated(): boolean;
markOutdated(): void;
markUpdated(): void;
hasFeature(feature: ESqlDataSourceFeatures): boolean;
canRename(name: string | null): boolean;
setName(name: string | null): void;
setProject(projectId: string | null): void;
setScript(script: string, source?: string): void;
@@ -59,10 +69,13 @@ export interface ISqlDataSource extends ILoadableState {
setExecutionContext(executionContext?: IConnectionExecutionContextInfo): void;
setIncomingExecutionContext(executionContext?: IConnectionExecutionContextInfo): void;
setIncomingScript(script?: string): void;
applyIncoming(): void;
keepCurrent(): void;
save(): Promise<void> | void;
load(): Promise<void> | void;
open(): Promise<void> | void;
reset(): Promise<void> | void;
dispose(): Promise<void> | void;
}
@@ -15,6 +15,7 @@ import type { ISqlEditorTabState } from './ISqlEditorTabState';
import { SqlDataSourceService } from './SqlDataSource/SqlDataSourceService';
import style from './SqlEditor.m.css';
import { SqlEditorLoader } from './SqlEditor/SqlEditorLoader';
import { SqlEditorOpenOverlay } from './SqlEditorOpenOverlay';
import { SqlEditorOverlay } from './SqlEditorOverlay';
import { SqlEditorStatusBar } from './SqlEditorStatusBar';
import { SqlEditorView } from './SqlEditorView';
@@ -34,6 +35,8 @@ export const SqlEditor = observer<Props>(function SqlEditor({ state }) {
useDataSource(dataSource);
const splitState = useSplitUserState(`sql-editor-${dataSource?.sourceKey ?? 'default'}`);
const opened = dataSource?.isOpened() || false;
return (
<Loader suspense>
<CaptureView className={s(styles, { captureView: true })} view={sqlEditorView}>
@@ -48,7 +51,8 @@ export const SqlEditor = observer<Props>(function SqlEditor({ state }) {
</Loader>
</Pane>
</Split>
<SqlEditorOverlay state={state} />
{opened && <SqlEditorOverlay state={state} />}
{!opened && <SqlEditorOpenOverlay dataSource={dataSource} />}
<SqlEditorStatusBar dataSource={dataSource} />
</CaptureView>
</Loader>
@@ -0,0 +1,51 @@
/*
* 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 { observer } from 'mobx-react-lite';
import {
Button,
Fill,
Overlay,
OverlayActions,
OverlayHeader,
OverlayHeaderIcon,
OverlayHeaderTitle,
OverlayMessage,
useTranslate,
} from '@cloudbeaver/core-blocks';
import type { ISqlDataSource } from './SqlDataSource/ISqlDataSource';
interface Props {
dataSource: ISqlDataSource | undefined;
}
// TODO: probably we need to combine this component with SqlEditorOverlay and use common API for overlays
export const SqlEditorOpenOverlay = observer<Props>(function SqlEditorOpenOverlay({ dataSource }) {
const translate = useTranslate();
function openHandler() {
dataSource?.open();
}
return (
<Overlay active={!dataSource?.isOpened()}>
<OverlayHeader>
<OverlayHeaderIcon icon={dataSource?.icon} />
<OverlayHeaderTitle>{translate('plugin_sql_editor_action_overlay_title')}</OverlayHeaderTitle>
</OverlayHeader>
<OverlayMessage>{translate('plugin_sql_editor_action_overlay_description')}</OverlayMessage>
<OverlayActions>
<Fill />
<Button type="button" mod={['unelevated']} loading={dataSource?.isLoading()} loader onClick={openHandler}>
{translate('ui_open')}
</Button>
</OverlayActions>
</Overlay>
);
});
@@ -33,4 +33,6 @@ export default [
],
['sql_editor_upload_script_max_size_title', 'File size exceeds max size'],
['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.'],
];
@@ -26,4 +26,6 @@ export default [
['sql_execution_plan_properties_panel_general', 'Generale'],
['sql_execution_plan_properties_panel_details', 'Dettagli'],
['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.'],
];
@@ -30,4 +30,6 @@ export default [
['sql_editor_upload_script_unsaved_changes_dialog_message', 'Текущий скрипт будет перезаписан загруженным. Сохранить текущий?'],
['sql_editor_upload_script_max_size_title', 'Размер файла превышает максимально допустимый'],
['sql_editor_close_result_tabs_dialog_title', 'Подтвердить закрытие вкладок'],
['plugin_sql_editor_action_overlay_title', 'Требуется действие'],
['plugin_sql_editor_action_overlay_description', 'Пожалуйста, перезапустите редактор для продолжения работы.'],
];
@@ -30,4 +30,6 @@ export default [
['sql_editor_upload_script_unsaved_changes_dialog_message', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'],
['sql_editor_upload_script_max_size_title', '文件大小超过最大大小'],
['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.'],
];