mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
fix: CB-591 updating tabs after changing connections
This commit is contained in:
+1
-4
@@ -51,10 +51,7 @@ export class ConnectionsAdministrationService extends Bootstrap {
|
||||
onActivate: this.loadConnections.bind(this),
|
||||
onDeActivate: async (configuration: boolean, outside: boolean) => {
|
||||
if (outside) {
|
||||
const updated = await this.connectionsResource.updateSessionConnections();
|
||||
if (updated) {
|
||||
await this.connectionInfoResource.refreshSession();
|
||||
}
|
||||
await this.connectionInfoResource.refreshSession();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,9 +17,12 @@ import {
|
||||
GraphQLService,
|
||||
CachedMapResource,
|
||||
ConnectionConfig,
|
||||
UserConnectionAuthPropertiesFragment
|
||||
UserConnectionAuthPropertiesFragment,
|
||||
resourceKeyList
|
||||
} from '@cloudbeaver/core-sdk';
|
||||
|
||||
import { ConnectionsResource } from './Administration/ConnectionsResource';
|
||||
|
||||
export type Connection = UserConnectionFragment & { authProperties?: UserConnectionAuthPropertiesFragment[] };
|
||||
|
||||
@injectable()
|
||||
@@ -29,6 +32,7 @@ export class ConnectionInfoResource extends CachedMapResource<string, Connection
|
||||
private sessionUpdate: boolean;
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private connectionsResource: ConnectionsResource,
|
||||
appAuthService: AppAuthService,
|
||||
sessionResource: SessionResource
|
||||
) {
|
||||
@@ -42,28 +46,39 @@ export class ConnectionInfoResource extends CachedMapResource<string, Connection
|
||||
// it's prevents double nav tree refresh
|
||||
this.onItemAdd.addHandler(() => !this.sessionUpdate);
|
||||
this.onItemDelete.addHandler(() => !this.sessionUpdate);
|
||||
this.onConnectionCreate.addHandler(() => !this.sessionUpdate);
|
||||
sessionResource.onDataOutdated.addHandler(() => this.markOutdated());
|
||||
appAuthService.auth.addHandler(() => this.refreshSession(true));
|
||||
}
|
||||
|
||||
@action async refreshSession(sessionUpdate?: boolean): Promise<void> {
|
||||
this.sessionUpdate = true;
|
||||
this.sessionUpdate = sessionUpdate === true;
|
||||
try {
|
||||
const { state: { connections } } = await this.graphQLService.sdk.getSessionConnections();
|
||||
const connectionsList = resourceKeyList(Array.from(this.data.keys()));
|
||||
await this.performUpdate(connectionsList, async () => {
|
||||
if (!sessionUpdate) {
|
||||
const updated = await this.connectionsResource.updateSessionConnections();
|
||||
|
||||
const restoredConnections = new Set<string>();
|
||||
for (const connection of connections) {
|
||||
await this.add(connection, sessionUpdate);
|
||||
restoredConnections.add(connection.id);
|
||||
}
|
||||
if (!updated) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const unrestoredConnectionIdList = Array.from(this.data.values())
|
||||
.map(connection => connection.id)
|
||||
.filter(connectionId => !restoredConnections.has(connectionId));
|
||||
const { state: { connections } } = await this.graphQLService.sdk.getSessionConnections();
|
||||
|
||||
for (const connectionId of unrestoredConnectionIdList) {
|
||||
this.delete(connectionId);
|
||||
}
|
||||
const restoredConnections = new Set<string>();
|
||||
|
||||
for (const connection of connections) {
|
||||
await this.add(connection);
|
||||
restoredConnections.add(connection.id);
|
||||
}
|
||||
|
||||
const unrestoredConnectionIdList = Array.from(this.data.values())
|
||||
.map(connection => connection.id)
|
||||
.filter(connectionId => !restoredConnections.has(connectionId));
|
||||
|
||||
this.delete(resourceKeyList(unrestoredConnectionIdList));
|
||||
});
|
||||
} finally {
|
||||
this.sessionUpdate = false;
|
||||
}
|
||||
@@ -87,13 +102,13 @@ export class ConnectionInfoResource extends CachedMapResource<string, Connection
|
||||
return this.add(connection);
|
||||
}
|
||||
|
||||
@action async add(connection: Connection, update?: boolean): Promise<Connection> {
|
||||
@action async add(connection: Connection): Promise<Connection> {
|
||||
const exists = this.data.has(connection.id);
|
||||
this.set(connection.id, connection);
|
||||
|
||||
const observedConnection = this.get(connection.id)!;
|
||||
|
||||
if (!update && !exists) {
|
||||
if (!exists) {
|
||||
await this.onConnectionCreate.execute(observedConnection);
|
||||
}
|
||||
|
||||
@@ -104,7 +119,6 @@ export class ConnectionInfoResource extends CachedMapResource<string, Connection
|
||||
await this.performUpdate(id, async () => {
|
||||
const connection = await this.initConnection(id, credentials, saveCredentials);
|
||||
this.set(id, connection);
|
||||
return connection;
|
||||
});
|
||||
|
||||
return this.get(id)!;
|
||||
|
||||
@@ -22,12 +22,14 @@ export function useConnectionInfo(connectionId: string) {
|
||||
const refresh = useCallback(() => service.refresh(connectionId), [service, connectionId]);
|
||||
const isLoading = useCallback(() => service.isDataLoading(connectionId), [service, connectionId]);
|
||||
const isLoaded = useCallback(() => service.isLoaded(connectionId), [service, connectionId]);
|
||||
const isOutdated = useCallback(() => service.isOutdated(connectionId), [service, connectionId]);
|
||||
const connect = useCallback(() => manager.requireConnection(connectionId), [manager, connectionId]);
|
||||
|
||||
return {
|
||||
connectionInfo,
|
||||
isLoading,
|
||||
isLoaded,
|
||||
isOutdated,
|
||||
load,
|
||||
refresh,
|
||||
connect,
|
||||
|
||||
@@ -47,6 +47,16 @@ export class TaskScheduler<TIdentifier> {
|
||||
}
|
||||
}
|
||||
|
||||
async wait(): Promise<void> {
|
||||
const queueList = this.queue.slice();
|
||||
|
||||
for (const task of queueList) {
|
||||
try {
|
||||
await task.task;
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
private async scheduler<T>(id: TIdentifier, promise: () => Promise<T>) {
|
||||
if (!this.isBlocked) {
|
||||
return promise();
|
||||
|
||||
@@ -49,6 +49,10 @@ export abstract class CachedResource<
|
||||
|
||||
abstract isLoaded(param: TParam): boolean;
|
||||
|
||||
waitLoad(): Promise<void> {
|
||||
return this.scheduler.wait();
|
||||
}
|
||||
|
||||
isLoading(): boolean {
|
||||
return this.loading;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,6 @@ export class ResourceKeyList<TKey> {
|
||||
}
|
||||
}
|
||||
|
||||
interface ForeachFnc {
|
||||
<TKey>(key: ResourceKey<TKey>, action: (key: TKey, index: number) => any): any;
|
||||
<TKey>(key: ResourceKey<TKey>, action: (key: TKey, index: number) => Promise<any>): Promise<any>;
|
||||
}
|
||||
|
||||
interface MapFnc {
|
||||
<TKey, TValue>(key: ResourceKeyList<TKey>, selector: (key: TKey, index: number) => TValue): TValue[];
|
||||
<TKey, TValue>(
|
||||
|
||||
@@ -59,12 +59,18 @@ export const ObjectViewerPanel = observer(function ObjectViewerPanel({
|
||||
navigation.selectTab(tab.id);
|
||||
}, [navigation, connection, tab]);
|
||||
|
||||
if (connection.connectionInfo && !connection.connectionInfo.connected && !connection.isLoading()) {
|
||||
return (
|
||||
<TextPlaceholder>
|
||||
<Button type="button" mod={['unelevated']} onClick={handleConnect}>{translate('connections_connection_connect')}</Button>
|
||||
</TextPlaceholder>
|
||||
);
|
||||
if (connection.connectionInfo) {
|
||||
if (connection.isLoading()) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
if (!connection.connectionInfo.connected) {
|
||||
return (
|
||||
<TextPlaceholder>
|
||||
<Button type="button" mod={['unelevated']} onClick={handleConnect}>{translate('connections_connection_connect')}</Button>
|
||||
</TextPlaceholder>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLoaded() || (!isOutdated() && isLoading())) {
|
||||
|
||||
@@ -190,7 +190,7 @@ export class ObjectViewerTabService {
|
||||
);
|
||||
|
||||
if (tab) {
|
||||
if (tab.handlerState.connectionId) {
|
||||
if (tab.handlerState.connectionId && this.connectionInfo.has(tab.handlerState.connectionId)) {
|
||||
const connection = await this.connectionInfo.load(tab.handlerState.connectionId);
|
||||
|
||||
if (!connection.connected) {
|
||||
@@ -229,6 +229,13 @@ export class ObjectViewerTabService {
|
||||
private async selectObjectTab(tab: ITab<IObjectViewerTabState>) {
|
||||
try {
|
||||
if (tab.handlerState.connectionId) {
|
||||
// here we wait when connections info will be updated and then check is connections is steel available
|
||||
await this.connectionInfo.waitLoad();
|
||||
|
||||
if (!this.connectionInfo.has(tab.handlerState.connectionId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const connection = await this.connectionInfo.load(tab.handlerState.connectionId);
|
||||
|
||||
if (!connection.connected) {
|
||||
|
||||
Reference in New Issue
Block a user