mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge branch 'devel' into fix-execution-context-cache
This commit is contained in:
+1
-1
@@ -89,7 +89,7 @@ module.exports = {
|
||||
"@typescript-eslint/keyword-spacing": ["error"],
|
||||
"@typescript-eslint/no-duplicate-imports": ["error"],
|
||||
"@typescript-eslint/object-curly-spacing": ["error", 'always'],
|
||||
"@typescript-eslint/quotes": ["error", "single"],
|
||||
"@typescript-eslint/quotes": ["error", "single", { "avoidEscape": true }],
|
||||
"@typescript-eslint/space-before-function-paren": ["error" , {"anonymous": "always", "named": "never", "asyncArrow": "always"}],
|
||||
"@typescript-eslint/space-infix-ops": ["error", { "int32Hint": false }],
|
||||
"@typescript-eslint/no-confusing-non-null-assertion": ["warn"],
|
||||
|
||||
@@ -19,17 +19,22 @@ export const SlideBox: React.FC<Props> = function SlideBox({ children, className
|
||||
useEffect(() => {
|
||||
const div = divRef.current;
|
||||
|
||||
if (div) {
|
||||
function handleScroll() {
|
||||
if (div) {
|
||||
div.scrollLeft = 0;
|
||||
div.scrollTop = 0;
|
||||
}
|
||||
function handleScroll() {
|
||||
if (div) {
|
||||
div.scrollLeft = 0;
|
||||
div.scrollTop = 0;
|
||||
}
|
||||
div.addEventListener('scroll', handleScroll);
|
||||
|
||||
return () => { div.removeEventListener('scroll', handleScroll); };
|
||||
}
|
||||
|
||||
if (div) {
|
||||
div.addEventListener('scroll', handleScroll);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (div) {
|
||||
div.removeEventListener('scroll', handleScroll);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -24,7 +24,7 @@ export type DBDriver = DatabaseDriverFragment;
|
||||
@injectable()
|
||||
export class DBDriverResource extends CachedMapResource<string, DBDriver, DriverListQueryVariables> {
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private readonly graphQLService: GraphQLService,
|
||||
permissionsResource: PermissionsResource,
|
||||
) {
|
||||
super();
|
||||
@@ -64,6 +64,10 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, Driver
|
||||
this.data.clear();
|
||||
}
|
||||
|
||||
if (driverId && !drivers.some(driver => driver.id === driverId)) {
|
||||
throw new Error('Driver is not found');
|
||||
}
|
||||
|
||||
this.updateDriver(...drivers);
|
||||
});
|
||||
|
||||
|
||||
@@ -126,14 +126,14 @@ export const AuthDialog: DialogComponent<IAuthPayload, null> = observer(function
|
||||
|
||||
if (state.configure) {
|
||||
return (
|
||||
<TextPlaceholder>
|
||||
{translate('authentication_provider_disabled')}
|
||||
{authenticationService.configureAuthProvider && (
|
||||
<Link onClick={() => navToSettings()}>
|
||||
<Translate token="ui_configure" />
|
||||
</Link>
|
||||
)}
|
||||
</TextPlaceholder>
|
||||
<TextPlaceholder>
|
||||
{translate('authentication_provider_disabled')}
|
||||
{authenticationService.configureAuthProvider && (
|
||||
<Link onClick={() => { navToSettings(); }}>
|
||||
<Translate token="ui_configure" />
|
||||
</Link>
|
||||
)}
|
||||
</TextPlaceholder>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ export const AuthDialog: DialogComponent<IAuthPayload, null> = observer(function
|
||||
}
|
||||
|
||||
return styled(useStyles(styles, UNDERLINE_TAB_STYLES))(
|
||||
<TabsState currentTabId={state.tabId} onChange={tabData => state.setTabId(tabData.tabId)}>
|
||||
<TabsState currentTabId={state.tabId} onChange={tabData => { state.setTabId(tabData.tabId); }}>
|
||||
<CommonDialogWrapper
|
||||
size='large'
|
||||
title={dialogTitle}
|
||||
@@ -179,7 +179,7 @@ export const AuthDialog: DialogComponent<IAuthPayload, null> = observer(function
|
||||
tabId={provider.id}
|
||||
title={provider.description || provider.label}
|
||||
disabled={state.authenticating}
|
||||
onClick={() => state.setActiveProvider(provider)}
|
||||
onClick={() => { state.setActiveProvider(provider); }}
|
||||
>
|
||||
<TabTitle>{provider.label}</TabTitle>
|
||||
</Tab>
|
||||
@@ -190,7 +190,7 @@ export const AuthDialog: DialogComponent<IAuthPayload, null> = observer(function
|
||||
tabId={FEDERATED_AUTH}
|
||||
title={translate('authentication_auth_federated')}
|
||||
disabled={state.authenticating}
|
||||
onClick={() => state.setActiveProvider(null)}
|
||||
onClick={() => { state.setActiveProvider(null); }}
|
||||
>
|
||||
<TabTitle>{translate('authentication_auth_federated')}</TabTitle>
|
||||
</Tab>
|
||||
@@ -201,8 +201,8 @@ export const AuthDialog: DialogComponent<IAuthPayload, null> = observer(function
|
||||
<Loader state={state.loadingState}>
|
||||
{() => federate
|
||||
? (
|
||||
<ConfigurationsList providers={state.configurations} onClose={rejectDialog} />
|
||||
)
|
||||
<ConfigurationsList providers={state.configurations} onClose={rejectDialog} />
|
||||
)
|
||||
: renderForm(state.activeProvider)}
|
||||
</Loader>
|
||||
</SubmittingForm>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { observer } from 'mobx-react-lite';
|
||||
import { useEffect } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { TabsState, TabList, UNDERLINE_TAB_STYLES, TabPanelList, Placeholder, useObjectRef, useExecutor, BASE_CONTAINERS_STYLES, IconOrImage, Loader } from '@cloudbeaver/core-blocks';
|
||||
import { TabsState, TabList, UNDERLINE_TAB_STYLES, TabPanelList, Placeholder, useObjectRef, useExecutor, BASE_CONTAINERS_STYLES, IconOrImage, Loader, ErrorMessage, useErrorDetails } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
|
||||
@@ -131,6 +131,7 @@ export const ConnectionForm = observer<Props>(function ConnectionForm({
|
||||
const style = [tabsStyles, UNDERLINE_TAB_STYLES];
|
||||
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
|
||||
const service = useService(ConnectionFormService);
|
||||
const error = useErrorDetails(state.initError);
|
||||
|
||||
useExecutor({
|
||||
executor: state.submittingTask,
|
||||
@@ -149,6 +150,16 @@ export const ConnectionForm = observer<Props>(function ConnectionForm({
|
||||
state.loadConnectionInfo();
|
||||
}, []);
|
||||
|
||||
if (state.initError) {
|
||||
return styled(styles)(
|
||||
<ErrorMessage
|
||||
text={error.details?.message || ''}
|
||||
hasDetails={error.details?.hasDetails}
|
||||
onShowDetails={error.open}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!state.configured) {
|
||||
return styled(styles)(
|
||||
<box className={className}>
|
||||
|
||||
@@ -29,6 +29,7 @@ export class ConnectionFormState implements IConnectionFormState {
|
||||
|
||||
statusMessage: string | null;
|
||||
configured: boolean;
|
||||
initError: Error | null;
|
||||
|
||||
get loading(): boolean {
|
||||
return this.loadConnectionTask.executing || this.submittingTask.executing;
|
||||
@@ -75,14 +76,16 @@ export class ConnectionFormState implements IConnectionFormState {
|
||||
readonly submittingTask: IExecutor<IConnectionFormSubmitData>;
|
||||
|
||||
private stateInfo: IFormStateInfo | null;
|
||||
private loadConnectionTask: IExecutor<IConnectionFormState>;
|
||||
private formStateTask: IExecutor<IConnectionFormState>;
|
||||
private readonly loadConnectionTask: IExecutor<IConnectionFormState>;
|
||||
private readonly formStateTask: IExecutor<IConnectionFormState>;
|
||||
private _availableDrivers: string[];
|
||||
|
||||
constructor(
|
||||
service: ConnectionFormService,
|
||||
resource: IConnectionsResource
|
||||
) {
|
||||
this.initError = null;
|
||||
|
||||
makeObservable<IConnectionFormState, '_availableDrivers' | 'stateInfo'>(this, {
|
||||
mode: observable,
|
||||
type: observable,
|
||||
@@ -94,6 +97,7 @@ export class ConnectionFormState implements IConnectionFormState {
|
||||
configured: observable,
|
||||
readonly: computed,
|
||||
stateInfo: observable,
|
||||
initError: observable.ref,
|
||||
});
|
||||
|
||||
this.resource = resource;
|
||||
@@ -141,9 +145,15 @@ export class ConnectionFormState implements IConnectionFormState {
|
||||
}
|
||||
|
||||
async loadConnectionInfo(): Promise<DatabaseConnection | undefined> {
|
||||
await this.loadConnectionTask.execute(this);
|
||||
try {
|
||||
await this.loadConnectionTask.execute(this);
|
||||
this.initError = null;
|
||||
|
||||
return this.info;
|
||||
return this.info;
|
||||
} catch (exception) {
|
||||
this.initError = exception;
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
async load(): Promise<void> {
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface IConnectionFormState {
|
||||
|
||||
partsState: MetadataMap<string, any>;
|
||||
|
||||
readonly initError: Error | null;
|
||||
readonly statusMessage: string | null;
|
||||
readonly disabled: boolean;
|
||||
readonly loading: boolean;
|
||||
|
||||
Reference in New Issue
Block a user