Skip to content

Commit

Permalink
CB-4018 fix: isolate contexts in data viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
Wroud committed Jun 18, 2024
1 parent 64f89a0 commit afb44cd
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 119 deletions.
20 changes: 20 additions & 0 deletions webapp/packages/core-view/src/View/CaptureViewScope.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { type PropsWithChildren, useContext } from 'react';

import { useDataContext } from '@cloudbeaver/core-data-context';

import { CaptureViewContext } from './CaptureViewContext';

export const CaptureViewScope = observer<PropsWithChildren>(function CaptureViewScope({ children }) {
const context = useContext(CaptureViewContext);
const viewContext = useDataContext(context);

return <CaptureViewContext.Provider value={viewContext}>{children}</CaptureViewContext.Provider>;
});
10 changes: 10 additions & 0 deletions webapp/packages/core-view/src/View/CaptureViewScopeLazy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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 { importLazyComponent } from '@cloudbeaver/core-blocks';

export const CaptureViewScope = importLazyComponent(() => import('./CaptureViewScope').then(m => m.CaptureViewScope));
1 change: 1 addition & 0 deletions webapp/packages/core-view/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export * from './Menu/MenuService';
export * from './Menu/useMenu';
export * from './Menu/useMenuContext';
export * from './View/AppView';
export * from './View/CaptureViewScopeLazy';
export * from './View/CaptureViewLazy';
export * from './View/CaptureViewContext';
export * from './View/IActiveView';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import { useService } from '@cloudbeaver/core-di';
import { EventContext, EventStopPropagationFlag } from '@cloudbeaver/core-events';
import { Executor } from '@cloudbeaver/core-executor';
import { ClipboardService } from '@cloudbeaver/core-ui';
import { useCaptureViewContext } from '@cloudbeaver/core-view';
import {
DATA_CONTEXT_DV_PRESENTATION,
DatabaseDataSelectActionsData,
DatabaseEditChangeType,
DataViewerPresentationType,
IDatabaseResultSet,
IDataPresentationProps,
IResultSetEditActionData,
Expand Down Expand Up @@ -187,6 +190,10 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
},
});

useCaptureViewContext((context, id) => {
context.set(DATA_CONTEXT_DV_PRESENTATION, { type: DataViewerPresentationType.Data }, id);
});

function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
gridSelectedCellCopy.onKeydownHandler(event);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,20 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { useContext, useState } from 'react';
import { useState } from 'react';

import { s, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { useDataContext, useDataContextLink } from '@cloudbeaver/core-data-context';
import { useTabLocalState } from '@cloudbeaver/core-ui';
import { CaptureViewContext } from '@cloudbeaver/core-view';
import { CaptureViewScope } from '@cloudbeaver/core-view';
import { DataPresentationComponent, IDatabaseResultSet, TableViewerLoader } from '@cloudbeaver/plugin-data-viewer';

import { DATA_CONTEXT_DV_DDM_RS_GROUPING } from './DataContext/DATA_CONTEXT_DV_DDM_RS_GROUPING';
import { DEFAULT_GROUPING_QUERY_OPERATION } from './DEFAULT_GROUPING_QUERY_OPERATION';
import styles from './DVResultSetGroupingPresentation.module.css';
import type { IGroupingQueryState } from './IGroupingQueryState';
import { useGroupingData } from './useGroupingData';
import { DVResultSetGroupingPresentationContext } from './DVResultSetGroupingPresentationContext';
import type { IDVResultSetGroupingPresentationState } from './IDVResultSetGroupingPresentationState';
import { useGroupingDataModel } from './useGroupingDataModel';
import { useGroupingDnDColumns } from './useGroupingDnDColumns';

export interface IDVResultSetGroupingPresentationState extends IGroupingQueryState {
presentationId: string;
}

export const DVResultSetGroupingPresentation: DataPresentationComponent<any, IDatabaseResultSet> = observer(function DVResultSetGroupingPresentation({
model: originalModel,
resultIndex,
Expand All @@ -38,22 +32,15 @@ export const DVResultSetGroupingPresentation: DataPresentationComponent<any, IDa
}));
const style = useS(styles);

const viewContext = useContext(CaptureViewContext);
const context = useDataContext(viewContext);
const translate = useTranslate();
const [presentationId, setPresentation] = useState('');
const [valuePresentationId, setValuePresentation] = useState<string | null>(null);
const model = useGroupingDataModel(originalModel, resultIndex, state);
const dnd = useGroupingDnDColumns(state, originalModel, model);

const grouping = useGroupingData(state);

useDataContextLink(context, (context, id) => {
context.set(DATA_CONTEXT_DV_DDM_RS_GROUPING, grouping, id);
});

return (
<>
<CaptureViewScope>
<DVResultSetGroupingPresentationContext state={state} />
<div
ref={dnd.dndThrowBox.setRef}
className={s(style, {
Expand Down Expand Up @@ -81,13 +68,12 @@ export const DVResultSetGroupingPresentation: DataPresentationComponent<any, IDa
resultIndex={resultIndex}
presentationId={presentationId}
valuePresentationId={valuePresentationId}
context={context}
simple
onPresentationChange={setPresentation}
onValuePresentationChange={setValuePresentation}
/>
)}
</div>
</>
</CaptureViewScope>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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 { useCaptureViewContext } from '@cloudbeaver/core-view';

import { DATA_CONTEXT_DV_DDM_RS_GROUPING } from './DataContext/DATA_CONTEXT_DV_DDM_RS_GROUPING';
import type { IDVResultSetGroupingPresentationState } from './IDVResultSetGroupingPresentationState';
import { useGroupingData } from './useGroupingData';

interface Props {
state: IDVResultSetGroupingPresentationState;
}

export const DVResultSetGroupingPresentationContext = observer<Props>(function DVResultSetGroupingPresentationContext({ state }) {
const grouping = useGroupingData(state);

useCaptureViewContext((context, id) => {
context.set(DATA_CONTEXT_DV_DDM_RS_GROUPING, grouping, id);
});

return null;
});
Original file line number Diff line number Diff line change
@@ -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.
*/
import type { IGroupingQueryState } from './IGroupingQueryState';

export interface IDVResultSetGroupingPresentationState extends IGroupingQueryState {
presentationId: string;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
/*
* 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 { action } from 'mobx';

import { useObservableRef } from '@cloudbeaver/core-blocks';

import type { IResultSetGroupingData } from './DataContext/DATA_CONTEXT_DV_DDM_RS_GROUPING';
import type { IDVResultSetGroupingPresentationState } from './DVResultSetGroupingPresentation';
import { DEFAULT_GROUPING_QUERY_OPERATION } from './DEFAULT_GROUPING_QUERY_OPERATION';
import type { IDVResultSetGroupingPresentationState } from './IDVResultSetGroupingPresentationState';

export interface IPrivateGroupingData extends IResultSetGroupingData {
state: IDVResultSetGroupingPresentationState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type { ResultDataFormat } from '@cloudbeaver/core-sdk';

import type { IDatabaseDataModel } from '../DatabaseDataModel/IDatabaseDataModel';
import type { IDataPresentationOptions } from '../DataPresentationService';
import styles from './DataPresentation.module.css';
import type { IDataTableActions } from './IDataTableActions';
import styles from './TableGrid.module.css';
import { TableStatistics } from './TableStatistics';

interface Props {
Expand All @@ -26,7 +26,15 @@ interface Props {
isStatistics: boolean;
}

export const TableGrid = observer<Props>(function TableGrid({ model, actions, dataFormat, presentation, resultIndex, simple, isStatistics }) {
export const DataPresentation = observer<Props>(function DataPresentation({
model,
actions,
dataFormat,
presentation,
resultIndex,
simple,
isStatistics,
}) {
if ((presentation.dataFormat !== undefined && dataFormat !== presentation.dataFormat) || !model.source.hasResult(resultIndex)) {
if (model.isLoading()) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { injectable } from '@cloudbeaver/core-di';
import { ACTION_REDO, ACTION_SAVE, ACTION_UNDO, IActiveView, View } from '@cloudbeaver/core-view';
import { ITab, NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs';

@injectable()
export class DataViewerViewService extends View<ITab> {
constructor(private readonly navigationTabsService: NavigationTabsService) {
super();
this.registerAction(ACTION_UNDO, ACTION_REDO, ACTION_SAVE);
}

getView(): IActiveView<ITab> | null {
return this.navigationTabsService.getView();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { observer } from 'mobx-react-lite';
import { useCallback, useEffect, useRef, useState } from 'react';

import { Form, getComputed, s, ToolsPanel, useS } from '@cloudbeaver/core-blocks';
import type { IDataContext } from '@cloudbeaver/core-data-context';
import { useService } from '@cloudbeaver/core-di';

import type { IDatabaseDataModel } from '../../DatabaseDataModel/IDatabaseDataModel';
Expand All @@ -22,10 +21,9 @@ interface Props {
resultIndex: number;
model: IDatabaseDataModel<any, any>;
simple: boolean;
context?: IDataContext;
}

export const TableFooter = observer<Props>(function TableFooter({ resultIndex, model, simple, context }) {
export const TableFooter = observer<Props>(function TableFooter({ resultIndex, model, simple }) {
const ref = useRef<HTMLInputElement>(null);
const [limit, setLimit] = useState(model.countGain + '');
const dataViewerSettingsService = useService(DataViewerSettingsService);
Expand Down Expand Up @@ -70,7 +68,7 @@ export const TableFooter = observer<Props>(function TableFooter({ resultIndex, m
/>
</Form>
</div>
<TableFooterMenu model={model} resultIndex={resultIndex} simple={simple} context={context} />
<TableFooterMenu model={model} resultIndex={resultIndex} simple={simple} />
{model.source.requestInfo.requestMessage.length > 0 && (
<div className={s(style, { time: true })}>
{model.source.requestInfo.requestMessage} - {model.source.requestInfo.requestDuration}ms
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';

import { s, SContext, StyleRegistry, useS } from '@cloudbeaver/core-blocks';
import { type IDataContext, useDataContextLink } from '@cloudbeaver/core-data-context';
import { useDataContextLink } from '@cloudbeaver/core-data-context';
import { MenuBar, MenuBarItemStyles } from '@cloudbeaver/core-ui';
import { useMenu } from '@cloudbeaver/core-view';

Expand All @@ -24,15 +24,14 @@ interface Props {
resultIndex: number;
model: IDatabaseDataModel<any, any>;
simple: boolean;
context?: IDataContext;
className?: string;
}

const registry: StyleRegistry = [[MenuBarItemStyles, { mode: 'append', styles: [tableFooterMenuBarItemStyles] }]];

export const TableFooterMenu = observer<Props>(function TableFooterMenu({ resultIndex, model, simple, context, className }) {
export const TableFooterMenu = observer<Props>(function TableFooterMenu({ resultIndex, model, simple, className }) {
const styles = useS(style, tableFooterMenuBarItemStyles);
const menu = useMenu({ menu: DATA_VIEWER_DATA_MODEL_ACTIONS_MENU, context });
const menu = useMenu({ menu: DATA_VIEWER_DATA_MODEL_ACTIONS_MENU });

useDataContextLink(menu.context, (context, id) => {
context.set(DATA_CONTEXT_DV_DDM, model, id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
border-radius: var(--theme-group-element-radius);
}
}

.captureView {
flex: 1;
display: flex;
overflow: auto;
position: relative;
}

.tableViewer {
composes: theme-background-secondary theme-text-on-secondary from global;
position: relative;
Expand Down
Loading

0 comments on commit afb44cd

Please sign in to comment.