fix(core-app): CB-1260 CB-1239 nav tree refresh behaviour

This commit is contained in:
Wroud
2021-09-14 19:13:31 +03:00
parent 28a6901480
commit 10d6401686
6 changed files with 102 additions and 34 deletions
@@ -16,7 +16,8 @@ import {
isResourceKeyList,
NavNodeInfoFragment,
ResourceKeyUtils,
ICachedMapResourceMetadata
ICachedMapResourceMetadata,
ResourceKeyList
} from '@cloudbeaver/core-sdk';
import { MetadataMap } from '@cloudbeaver/core-utils';
@@ -60,6 +61,19 @@ export class NavNodeInfoResource extends CachedMapResource<string, NavNode> {
});
}
setParent(key: string, parentId: string): void;
setParent(key: ResourceKeyList<string>, parentId: string): void;
setParent(key: ResourceKey<string>, parentId: string): void;
setParent(key: ResourceKey<string>, parentId: string): void {
ResourceKeyUtils.forEach(key, key => {
const node = this.get(key);
if (node) {
node.parentId = parentId;
}
});
}
protected async loader(key: ResourceKey<string>): Promise<Map<string, NavNode>> {
if (isResourceKeyList(key)) {
const values: NavNode[] = [];
@@ -140,14 +140,19 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
}
async changeName(node: NavNode, name: string): Promise<void> {
await this.performUpdate(resourceKeyList([node.id, node.parentId]), [], async () => {
await this.graphQLService.sdk.navRenameNode({
nodePath: node.id,
newName: name,
});
await this.performUpdate(node.parentId, [], async () => {
this.markDataLoading(node.id);
try {
await this.graphQLService.sdk.navRenameNode({
nodePath: node.id,
newName: name,
});
} finally {
this.markDataLoaded(node.id);
}
});
await this.refreshTree(node.parentId);
await this.markOutdated(node.parentId);
}
deleteInNode(key: string, value: string[]): void;
@@ -274,47 +279,88 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
}
private async connectionUpdateHandler(key: ResourceKey<string>) {
const outdatedTrees: string[] = [];
const outdatedFolders: string[] = [];
const closedConnections: string[] = [];
await ResourceKeyUtils.forEachAsync(key, async key => {
const nodeId = NodeManagerUtils.connectionIdToConnectionNodeId(key);
ResourceKeyUtils.forEach(key, key => {
const connectionInfo = this.connectionInfo.get(key);
if (this.has(nodeId)) {
const connectionInfo = this.connectionInfo.get(key);
if (!connectionInfo?.nodePath) {
return;
}
if (!connectionInfo?.connected) {
closedConnections.push(nodeId);
} else {
await this.markOutdated(nodeId);
if (!this.has(connectionInfo.nodePath)) {
return;
}
if (!connectionInfo.connected) {
closedConnections.push(connectionInfo.nodePath);
const folder = /* connectionInfo.folder || */ ROOT_NODE_PATH;
if (!outdatedFolders.includes(folder)) {
outdatedFolders.push(folder);
}
} else {
outdatedTrees.push(connectionInfo.nodePath);
}
});
if (closedConnections.length > 0) {
const key = resourceKeyList(closedConnections);
this.set(key, closedConnections.map(() => []));
await this.markOutdated(ROOT_NODE_PATH);
}
if (outdatedTrees.length > 0 || outdatedFolders.length > 0) {
const key = resourceKeyList([...outdatedTrees, ...outdatedFolders]);
await this.markOutdated(key);
}
}
private connectionRemoveHandler(key: ResourceKey<string>) {
runInAction(() => {
ResourceKeyUtils.forEach(key, key => {
const nodeId = NodeManagerUtils.connectionIdToConnectionNodeId(key);
ResourceKeyUtils.forEach(key, key => {
const connectionInfo = this.connectionInfo.get(key);
const node = this.navNodeInfoResource.get(nodeId);
if (!connectionInfo?.nodePath) {
return;
}
if (node) {
this.deleteInNode(node.parentId, [nodeId]);
}
});
const folder = /* connectionInfo.folder || */ ROOT_NODE_PATH;
if (connectionInfo) {
this.deleteInNode(folder, [connectionInfo.nodePath]);
}
});
}
private async connectionCreateHandler(connection: Connection) {
const nodeId = NodeManagerUtils.connectionIdToConnectionNodeId(connection.id);
await this.markOutdated(ROOT_NODE_PATH);
await this.markTreeOutdated(nodeId);
if (!connection.nodePath) {
return;
}
const folder = /* connection.folder || */ ROOT_NODE_PATH;
const children = this.get(folder);
if (!children) {
return;
}
const connectionNode = await this.navNodeInfoResource.load(connection.nodePath);
this.navNodeInfoResource.setParent(connection.nodePath, folder);
let insertIndex = 0;
const nodes = this.navNodeInfoResource.get(resourceKeyList(children));
for (const node of nodes) {
if (!node?.folder && node?.name?.localeCompare(connectionNode.name!) === 1) {
break;
}
insertIndex++;
}
children.splice(insertIndex, 0, connection.nodePath);
}
private setNavObject(data: NavNodeChildrenQuery | NavNodeChildrenQuery[]) {
@@ -12,6 +12,7 @@ import { IServiceConstructor, useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { CachedDataResource, CachedResourceData, CachedResourceParam, isResourceKeyList, ResourceKey } from '@cloudbeaver/core-sdk';
import { getComputed } from './getComputed';
import type { ILoadableState } from './Loader/Loader';
import { useObjectRef } from './useObjectRef';
@@ -47,7 +48,7 @@ export function useDataResource<
const key = keyObj && typeof keyObj === 'object' && 'includes' in keyObj ? keyObj.key : keyObj;
const includes = keyObj && typeof keyObj === 'object' && 'includes' in keyObj ? keyObj.includes : [];
const outdated = resource.isOutdated(key);
const outdated = getComputed(() => resource.isOutdated(key) && !resource.isDataLoading(key));
const refObj = useObjectRef(() => ({
loading: false,
@@ -13,6 +13,7 @@ import { IServiceConstructor, useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { CachedResourceIncludeArgs, CachedMapResource, CachedMapResourceGetter, ResourceKey, CachedMapResourceValue, CachedMapResourceKey, CachedMapResourceArguments, CachedMapResourceLoader, ResourceKeyList, CachedMapResourceListGetter } from '@cloudbeaver/core-sdk';
import { getComputed } from './getComputed';
import type { ILoadableState } from './Loader/Loader';
import { useObservableRef } from './useObservableRef';
@@ -192,7 +193,7 @@ export function useMapResource<
actions,
});
const outdated = resource.isOutdated(key);
const outdated = getComputed(() => resource.isOutdated(key) && !resource.isDataLoading(key));
const [result] = useState<
IMapResourceResult<TResource, TIncludes>
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { action, computed, makeObservable } from 'mobx';
import { action, computed, makeObservable, runInAction } from 'mobx';
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { MetadataMap } from '@cloudbeaver/core-utils';
@@ -237,9 +237,15 @@ export abstract class CachedMapResource<
delete(key: ResourceKey<TKey>): void;
delete(key: ResourceKey<TKey>): void {
key = this.transformParam(key);
ResourceKeyUtils.forEach(key, key => this.data.delete(key));
this.markUpdated(key);
this.onItemDelete.execute(key);
this.onItemDelete
.execute(key)
.finally(() => {
runInAction(() => {
ResourceKeyUtils.forEach(key, key => this.data.delete(key));
this.markUpdated(key);
});
});
}
clear(): void {
@@ -64,7 +64,7 @@ export class ObjectViewerTabService {
this.connectionInfo.onItemAdd.addHandler(this.updateConnectionTabs.bind(this));
this.connectionInfo.onItemDelete.addHandler(this.closeConnectionTabs.bind(this));
this.navNodeManagerService.navNodeInfoResource.onItemAdd.addHandler(this.updateTabs.bind(this));
this.navNodeManagerService.navNodeInfoResource.onItemDelete.addHandler(this.removeTabs.bind(this));
this.navNodeManagerService.navTree.onItemDelete.addHandler(this.removeTabs.bind(this));
}
isPageActive(tab: ITab<IObjectViewerTabState>, page: ObjectPage): boolean {