Skip to content

Commit

Permalink
Merge branch 'devel' into fix/cb-4681/content-downloading-value-panel
Browse files Browse the repository at this point in the history
  • Loading branch information
dariamarutkina authored Feb 27, 2024
2 parents 4ad39e7 + a5f53cb commit f318dff
Show file tree
Hide file tree
Showing 25 changed files with 255 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ public WebSession(
this.lastAccessTime = this.createTime;
setLocale(CommonUtils.toString(httpSession.getAttribute(ATTR_LOCALE), this.locale));
this.sessionHandlers = sessionHandlers;
//force authorization of anonymous session to avoid access error,
//because before authorization could be called by any request,
//but now 'updateInfo' is called only in special requests,
//and the order of requests is not guaranteed.
//look at CB-4747
refreshSessionAuth();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ public WebSession getWebSession(
log.debug((restored ? "Restored " : "New ") + "web session '" + webSession.getSessionId() + "'");

webSession.setCacheExpired(!httpSession.isNew());
webSession.updateInfo(request, response);

sessionMap.put(sessionId, webSession);
} else {
Expand Down
2 changes: 1 addition & 1 deletion server/drivers/postgresql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.2</version>
<version>42.7.2</version>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
Expand Down
2 changes: 0 additions & 2 deletions webapp/packages/plugin-codemirror6/src/IEditorRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import type { EditorView } from '@codemirror/view';
import type { SelectionRange } from '@codemirror/state';

export interface IEditorRef {
container: HTMLDivElement | null;
view: EditorView | null;
selection: SelectionRange | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Compartment, Extension, SelectionRange } from '@codemirror/state';
import type { ViewUpdate } from '@codemirror/view';

/** Currently we support only main selection range */
interface ISelection {
export interface ISelection {
anchor: number;
head?: number;
}
Expand Down
48 changes: 33 additions & 15 deletions webapp/packages/plugin-codemirror6/src/ReactCodemirror.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { MergeView } from '@codemirror/merge';
import { Annotation, Compartment, Extension, StateEffect, TransactionSpec } from '@codemirror/state';
import { Annotation, Compartment, EditorState, Extension, StateEffect, TransactionSpec } from '@codemirror/state';
import { EditorView, ViewUpdate } from '@codemirror/view';
import { observer } from 'mobx-react-lite';
import { forwardRef, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
Expand All @@ -17,6 +17,7 @@ import type { IEditorRef } from './IEditorRef';
import type { IReactCodeMirrorProps } from './IReactCodemirrorProps';
import { type IReactCodemirrorContext, ReactCodemirrorContext } from './ReactCodemirrorContext';
import { useCodemirrorExtensions } from './useCodemirrorExtensions';
import { validateCursorBoundaries } from './validateCursorBoundaries';

const External = Annotation.define<boolean>();

Expand Down Expand Up @@ -55,15 +56,11 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
const [view, setView] = useState<EditorView | null>(null);
const [incomingView, setIncomingView] = useState<EditorView | null>(null);
const callbackRef = useObjectRef({ onChange, onCursorChange, onUpdate });
const [selection, setSelection] = useState(view?.state.selection.main ?? null);

useLayoutEffect(() => {
if (container) {
const updateListener = EditorView.updateListener.of((update: ViewUpdate) => {
const remote = update.transactions.some(tr => tr.annotation(External));
if (update.selectionSet) {
setSelection(update.state.selection.main);
}

if (update.docChanged && !remote) {
const doc = update.state.doc;
Expand All @@ -89,9 +86,15 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
effects.push(compartment.of(extension));
}

const tempState = EditorState.create({
doc: value,
});

if (incomingValue !== undefined) {
merge = new MergeView({
a: {
doc: value,
selection: cursor && validateCursorBoundaries(cursor, tempState.doc.length),
extensions: [updateListener, ...effects],
},
b: {
Expand All @@ -104,11 +107,19 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
incomingView = merge.b;
} else {
editorView = new EditorView({
state: EditorState.create({
doc: value,
selection: cursor && validateCursorBoundaries(cursor, tempState.doc.length),
extensions: [updateListener, ...effects],
}),
parent: container,
extensions: [updateListener, ...effects],
});
}

editorView.dispatch({
scrollIntoView: true,
});

if (incomingView) {
setIncomingView(incomingView);
}
Expand Down Expand Up @@ -168,9 +179,13 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(

let isCursorInDoc = cursor && cursor.anchor > 0 && cursor.anchor < view.state.doc.length;

if (value !== undefined && value !== view.state.doc.toString()) {
transaction.changes = { from: 0, to: view.state.doc.length, insert: value };
isCursorInDoc = cursor && cursor.anchor > 0 && cursor.anchor < value.length;
if (value !== undefined) {
const newText = view.state.toText(value);

if (!newText.eq(view.state.doc)) {
transaction.changes = { from: 0, to: view.state.doc.length, insert: newText };
isCursorInDoc = cursor && cursor.anchor > 0 && cursor.anchor < newText.length;
}
}

if (cursor && isCursorInDoc && (view.state.selection.main.anchor !== cursor.anchor || view.state.selection.main.head !== cursor.head)) {
Expand All @@ -184,10 +199,14 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
});

useLayoutEffect(() => {
if (incomingValue !== undefined && incomingView && incomingValue !== incomingView.state.doc.toString()) {
incomingView.dispatch({
changes: { from: 0, to: incomingView.state.doc.length, insert: incomingValue },
});
if (incomingValue !== undefined && incomingView) {
const newValue = incomingView.state.toText(incomingValue);

if (!newValue.eq(incomingView.state.doc)) {
incomingView.dispatch({
changes: { from: 0, to: incomingView.state.doc.length, insert: newValue },
});
}
}
}, [incomingValue, incomingView]);

Expand All @@ -202,9 +221,8 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
() => ({
container,
view,
selection,
}),
[container, view, selection],
[container, view],
);

const context = useMemo<IReactCodemirrorContext>(
Expand Down
15 changes: 15 additions & 0 deletions webapp/packages/plugin-codemirror6/src/validateCursorBoundaries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { ISelection } from './IReactCodemirrorProps';

export function validateCursorBoundaries(selection: ISelection, documentLength: number): ISelection {
return {
anchor: Math.min(selection.anchor, documentLength),
head: selection.head === undefined ? undefined : Math.min(selection.head, documentLength),
};
}
18 changes: 16 additions & 2 deletions webapp/packages/plugin-data-viewer/src/DataViewerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,33 @@
*/
import type { Connection } from '@cloudbeaver/core-connections';
import { injectable } from '@cloudbeaver/core-di';
import { EAdminPermission, SessionPermissionsResource } from '@cloudbeaver/core-root';

import { DataViewerSettingsService } from './DataViewerSettingsService';

@injectable()
export class DataViewerService {
get canCopyData() {
if (this.sessionPermissionsResource.has(EAdminPermission.admin)) {
return true;
}

return !this.dataViewerSettingsService.settings.getValue('disableCopyData');
}

constructor(private readonly dataViewerSettingsService: DataViewerSettingsService) {}
constructor(
private readonly dataViewerSettingsService: DataViewerSettingsService,
private readonly sessionPermissionsResource: SessionPermissionsResource,
) {}

isDataEditable(connection: Connection) {
if (connection.readOnly) {
return false;
}

const isAdmin = this.sessionPermissionsResource.has(EAdminPermission.admin);
const disabled = this.dataViewerSettingsService.settings.getValue('disableEdit');
return !disabled && !connection.readOnly;

return isAdmin || !disabled;
}
}
4 changes: 2 additions & 2 deletions webapp/packages/plugin-data-viewer/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ export default [
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
['settings_data_editor_disable_data_copy_name', 'Disable Copy'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer for non-admin users'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
Expand Down
4 changes: 2 additions & 2 deletions webapp/packages/plugin-data-viewer/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export default [
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
['settings_data_editor_disable_data_copy_name', 'Disable Copy'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer for non-admin users'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
Expand Down
4 changes: 2 additions & 2 deletions webapp/packages/plugin-data-viewer/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ export default [
['data_viewer_model_not_loaded', 'Не удалось загрузить модель таблицы'],
['settings_data_editor', 'Редактор данных'],
['settings_data_editor_disable_edit_name', 'Отключить редактирование'],
['settings_data_editor_disable_edit_description', 'Отключить редактирование данных'],
['settings_data_editor_disable_edit_description', 'Отключить редактирование данных для пользователей без прав администратора'],
['settings_data_editor_disable_data_copy_name', 'Отключить копирование'],
['settings_data_editor_disable_data_copy_description', 'Отключить копирование данных'],
['settings_data_editor_disable_data_copy_description', 'Отключить копирование данных для пользователей без прав администратора'],
['settings_data_editor_fetch_min_name', 'Минимальный размер выборки'],
['settings_data_editor_fetch_min_description', 'Минимальное количество строк для выборки'],
['settings_data_editor_fetch_max_name', 'Максимальный размер выборки'],
Expand Down
4 changes: 2 additions & 2 deletions webapp/packages/plugin-data-viewer/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ export default [
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
['settings_data_editor_disable_data_copy_name', 'Disable Copy'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer'],
['settings_data_editor_disable_data_copy_description', 'Disable copying of data in Data Viewer for non-admin users'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { computed, makeObservable, observable, untracked } from 'mobx';

import { ConfirmationDialog } from '@cloudbeaver/core-blocks';
import { ConfirmationDialog, importLazyComponent } from '@cloudbeaver/core-blocks';
import {
ConnectionExecutionContextResource,
ConnectionExecutionContextService,
Expand Down Expand Up @@ -40,16 +40,18 @@ import {
ESqlDataSourceFeatures,
ISQLDatasourceUpdateData,
ISqlEditorTabState,
SQL_EDITOR_TAB_STATE_SCHEMA,
SqlDataSourceService,
SqlEditorService,
SqlResultTabsService,
} from '@cloudbeaver/plugin-sql-editor';

import { isSQLEditorTab } from './isSQLEditorTab';
import { SqlEditorPanel } from './SqlEditorPanel';
import { SqlEditorTab } from './SqlEditorTab';
import { sqlEditorTabHandlerKey } from './sqlEditorTabHandlerKey';

const SqlEditorPanel = importLazyComponent(() => import('./SqlEditorPanel').then(m => m.SqlEditorPanel));
const SqlEditorTab = importLazyComponent(() => import('./SqlEditorTab').then(m => m.SqlEditorTab));

@injectable()
export class SqlEditorTabService extends Bootstrap {
get sqlEditorTabs(): ITab<ISqlEditorTabState>[] {
Expand Down Expand Up @@ -273,20 +275,7 @@ export class SqlEditorTabService extends Bootstrap {
}

private async handleTabRestore(tab: ITab<ISqlEditorTabState>): Promise<boolean> {
if (
typeof tab.handlerState.editorId !== 'string' ||
typeof tab.handlerState.editorId !== 'string' ||
typeof tab.handlerState.order !== 'number' ||
!['string', 'undefined'].includes(typeof tab.handlerState.currentTabId) ||
!['string', 'undefined'].includes(typeof tab.handlerState.source) ||
!['string', 'undefined'].includes(typeof tab.handlerState.currentModeId) ||
!Array.isArray(tab.handlerState.modeState) ||
!Array.isArray(tab.handlerState.tabs) ||
!Array.isArray(tab.handlerState.executionPlanTabs) ||
!Array.isArray(tab.handlerState.resultGroups) ||
!Array.isArray(tab.handlerState.resultTabs) ||
!Array.isArray(tab.handlerState.statisticsTabs)
) {
if (!SQL_EDITOR_TAB_STATE_SCHEMA.safeParse(tab.handlerState).success) {
await this.sqlDataSourceService.destroy(tab.handlerState.editorId);
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';
import { useState } from 'react';

import { MenuBarSmallItem, useExecutor, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { DATA_CONTEXT_NAV_NODE, getNodesFromContext, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
import { TabContainerPanelComponent, useDNDBox, useTabLocalState } from '@cloudbeaver/core-ui';
import { TabContainerPanelComponent, useDNDBox } from '@cloudbeaver/core-ui';
import { closeCompletion, IEditorRef, Prec, ReactCodemirrorPanel, useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import type { ISqlEditorModeProps } from '@cloudbeaver/plugin-sql-editor';

Expand All @@ -26,36 +26,16 @@ import style from './SQLCodeEditorPanel.m.css';
import { SqlEditorInfoBar } from './SqlEditorInfoBar';
import { useSQLCodeEditorPanel } from './useSQLCodeEditorPanel';

interface ILocalSQLCodeEditorPanelState {
selection: { from: number; to: number };
}

export const SQLCodeEditorPanel: TabContainerPanelComponent<ISqlEditorModeProps> = observer(function SQLCodeEditorPanel({ data }) {
const notificationService = useService(NotificationService);
const navNodeManagerService = useService(NavNodeManagerService);
const translate = useTranslate();
const localState = useTabLocalState<ILocalSQLCodeEditorPanelState>(() => ({ selection: { from: 0, to: 0 } }));

const styles = useS(style);
const [editorRef, setEditorRef] = useState<IEditorRef | null>(null);

const editor = useSQLCodeEditor(editorRef);

useEffect(() => {
editorRef?.view?.dispatch({
selection: { anchor: Math.min(localState.selection.to, data.value.length), head: Math.min(localState.selection.to, data.value.length) },
scrollIntoView: true,
});
}, [editorRef?.view, localState, data]);

useEffect(() => {
if (!editorRef?.selection) {
return;
}

localState.selection = { ...editorRef?.selection };
}, [editorRef?.selection]);

const panel = useSQLCodeEditorPanel(data, editor);
const extensions = useCodemirrorExtensions(undefined, [ACTIVE_QUERY_EXTENSION, Prec.lowest(QUERY_STATUS_GUTTER_EXTENSION)]);
const autocompletion = useSqlDialectAutocompletion(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import React from 'react';

import { importLazyComponent } from '@cloudbeaver/core-blocks';
import { injectable } from '@cloudbeaver/core-di';
import { ESqlDataSourceFeatures, SqlEditorModeService } from '@cloudbeaver/plugin-sql-editor';

const SQLCodeEditorPanel = React.lazy(async () => {
const { SQLCodeEditorPanel } = await import('./SQLCodeEditorPanel');
return { default: SQLCodeEditorPanel };
});
const SQLCodeEditorPanel = importLazyComponent(() => import('./SQLCodeEditorPanel').then(module => module.SQLCodeEditorPanel));

@injectable()
export class SQLCodeEditorPanelService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { useCallback } from 'react';

import { useExecutor, useObservableRef } from '@cloudbeaver/core-blocks';
import { throttle } from '@cloudbeaver/core-utils';
import type { Transaction, ViewUpdate } from '@cloudbeaver/plugin-codemirror6';
import type { ISQLEditorData } from '@cloudbeaver/plugin-sql-editor';

import type { IEditor } from '../SQLCodeEditor/useSQLCodeEditor';
Expand Down
Loading

0 comments on commit f318dff

Please sign in to comment.