Merge branch 'devel' of https://github.com/dbeaver/cloudbeaver into devel

This commit is contained in:
serge-rider
2025-08-20 15:14:28 +02:00
7 changed files with 23 additions and 6 deletions
@@ -37,6 +37,7 @@ public interface ApiCallInterceptor {
@NotNull HttpServletRequest request,
@Nullable Map<String, Object> variables,
@NotNull String apiCall,
@Nullable String userId,
@NotNull LocalDateTime startTime,
@Nullable String errorMessage,
@NotNull String apiProtocol
@@ -271,7 +271,7 @@ public class GraphQLEndpoint extends HttpServlet {
errorMessage = executionException.getMessage();
}
if (WebAppUtils.getWebApplication() instanceof ApiCallInterceptor apiCallInterceptor) {
apiCallInterceptor.onApiCallEvent(request, variables, operationName, startTime, errorMessage, API_PROTOCOL);
apiCallInterceptor.onApiCallEvent(request, variables, operationName, userId, startTime, errorMessage, API_PROTOCOL);
}
}
@@ -75,7 +75,7 @@ public abstract class WebServiceServletBase extends HttpServlet {
} finally {
if (WebAppUtils.getWebApplication() instanceof ApiCallInterceptor apiCallInterceptor) {
apiCallInterceptor.onApiCallEvent(
request, getVariables(request), request.getRequestURI(), startTime, errorMessage, API_PROTOCOL
request, getVariables(request), request.getRequestURI(), null, startTime, errorMessage, API_PROTOCOL
);
}
}
@@ -7,7 +7,7 @@
*/
import { observer } from 'mobx-react-lite';
import { getComputed, Loader, Pane, ResizerControls, s, Split, useS, useSplitUserState } from '@cloudbeaver/core-blocks';
import { getComputed, Loader, Pane, ResizerControls, s, Split, useExecutor, useS, useSplitUserState } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { LeftBarPanelService, SideBarPanel, SideBarPanelService } from '@cloudbeaver/core-ui';
@@ -25,6 +25,17 @@ export const Main = observer(function Main() {
const sideBarDisabled = getComputed(() => sideBarPanelService.tabsContainer.getDisplayed().length === 0);
const leftBarDisabled = getComputed(() => leftBarPanelService.tabsContainer.getDisplayed().length === 0);
useExecutor({
executor: sideBarPanelService.tabsContainer.onTabSelect,
handlers: [
function showPanel() {
if (splitRightState.mode === 'minimize' && !sideBarDisabled) {
splitRightState.onModeChange?.('resize');
}
},
],
});
return (
<Loader className={s(styles, { loader: true })} suspense>
<main className={s(styles, { space: true })}>
@@ -42,10 +42,9 @@ const sideBarPanelRegistry: StyleRegistry = [
export const SideBarPanel = observer<SideBarPanelProps>(function SideBarPanel({ container }) {
const style = useS(styles);
return (
<SContext registry={sideBarPanelRegistry}>
<TabsState container={container} lazy>
<TabsState container={container} currentTabId={container.selectedId} lazy onChange={tab => container.select(tab.tabId, tab.props)}>
<div className={s(style, { box: true })}>
<TabList className={s(style, { tabList: true })} underline />
<div className={s(style, { contentBox: true })}>
@@ -8,12 +8,14 @@
import { makeObservable, observable } from 'mobx';
import type { MetadataMap, MetadataValueGetter, schema } from '@cloudbeaver/core-utils';
import { SyncExecutor } from '@cloudbeaver/core-executor';
import type { ITabInfo, ITabInfoOptions, ITabsContainer } from './ITabsContainer.js';
export class TabsContainer<TProps = void, TOptions extends Record<string, any> | unknown = unknown> implements ITabsContainer<TProps, TOptions> {
readonly areaLabel: string;
readonly tabInfoMap: Map<string, ITabInfo<TProps, TOptions>>;
readonly onTabSelect: SyncExecutor<string>;
get tabInfoList(): Array<ITabInfo<TProps, TOptions>> {
return Array.from(this.tabInfoMap.values()).sort((a, b) => a.order - b.order);
@@ -29,6 +31,7 @@ export class TabsContainer<TProps = void, TOptions extends Record<string, any> |
this.tabInfoMap = new Map();
this.currentTabId = null;
this.areaLabel = areaLabel;
this.onTabSelect = new SyncExecutor();
makeObservable<TabsContainer<TProps, TOptions>, 'currentTabId'>(this, {
tabInfoMap: observable.shallow,
@@ -58,6 +61,7 @@ export class TabsContainer<TProps = void, TOptions extends Record<string, any> |
});
this.currentTabId = tabId;
this.onTabSelect.execute(tabId);
}
getTabInfo(tabId: string): ITabInfo<TProps, TOptions> | undefined {
@@ -42,6 +42,7 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
ref,
) {
value = value ?? getValue?.();
const isInitialScriptOpening = useRef(true);
const currentExtensions = useRef<Map<Compartment, Extension>>(new Map());
const readOnlyFacet = useMemo(() => {
if (readonly) {
@@ -214,7 +215,7 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
}
}
if (hasInsertProperty(transaction.changes) && !transaction.selection) {
if (hasInsertProperty(transaction.changes) && !transaction.selection && !isInitialScriptOpening.current) {
transaction.selection = {
anchor: transaction.changes.insert?.length ?? 0,
head: transaction.changes.insert?.length ?? 0,
@@ -223,6 +224,7 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
if (transaction.changes) {
view.dispatch({ changes: transaction.changes });
isInitialScriptOpening.current = false;
}
if (transaction.selection) {