Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CB-4841 fix: doesn't show database auth login popup when filters enabled #2510

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
325f364
CB-4841 fix: doesn't show database auth login popup when filters enabled
sergeyteleshev Mar 27, 2024
63f46f9
Revert "CB-4841 fix: doesn't show database auth login popup when filt…
sergeyteleshev Mar 28, 2024
b5e2975
Merge branch 'devel' into CB-4841-connection-auth-dialog-appears-and-…
sergeyteleshev Mar 28, 2024
1ac1b37
CB-4841 fix: do not open database when filter applied and relogin hap…
sergeyteleshev Mar 28, 2024
6deccf2
CB-4841 adds log for staging debug
sergeyteleshev Mar 29, 2024
82af8de
Revert "CB-4841 adds log for staging debug"
sergeyteleshev Mar 29, 2024
c1a5134
Merge branch 'devel' into CB-4841-connection-auth-dialog-appears-and-…
sergeyteleshev Mar 31, 2024
e2f4a68
CB-4841 fix: does not open auth dialog when relogin + filter mode
sergeyteleshev Apr 2, 2024
d3f1d61
CB-4841 fix: does not open auth dialog when relogin + filter mode [2]
sergeyteleshev Apr 2, 2024
6614168
CB-4841 fix: does not open auth dialog when relogin + filter mode [3]
sergeyteleshev Apr 2, 2024
3709424
CB-4841 cleanup
sergeyteleshev Apr 2, 2024
02dc1f3
Merge branch 'devel' into CB-4841-connection-auth-dialog-appears-and-…
sergeyteleshev Apr 5, 2024
0c638e8
CB-4841 pr fix
sergeyteleshev Apr 5, 2024
4ff0b21
Merge branch 'devel' into CB-4841-connection-auth-dialog-appears-and-…
sergeyteleshev Apr 8, 2024
166d7af
CB-4841 revert parent node fix
sergeyteleshev Apr 8, 2024
7622e01
Merge branch 'devel' into CB-4841-connection-auth-dialog-appears-and-…
sergeyteleshev Apr 9, 2024
3d2c398
CB-4841 adds loadingNodes state to track uneeded node loads
sergeyteleshev Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,10 @@ export class ConnectionAuthService extends Dependency {
return null;
}

let connection = this.connectionInfoResource.get(key);
let connection = await this.connectionInfoResource.load(key);
const isConnectedInitially = connection?.connected;

if (!connection?.connected) {
connection = await this.connectionInfoResource.refresh(key);
} else {
if (connection?.connected) {
if (resetCredentials) {
this.connectionInfoResource.close(key);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { type NavNode, NavNodeInfoResource, NavTreeResource, ROOT_NODE_PATH } fr
import { ProjectInfoResource, ProjectsService } from '@cloudbeaver/core-projects';
import { CachedMapAllKey, CachedResourceOffsetPageKey, getNextPageOffset, ResourceKeyUtils } from '@cloudbeaver/core-resource';
import type { IDNDData } from '@cloudbeaver/core-ui';
import { ILoadableState, MetadataMap, throttle } from '@cloudbeaver/core-utils';
import { debounce, ILoadableState, MetadataMap } from '@cloudbeaver/core-utils';

import { ElementsTreeService } from './ElementsTreeService';
import type { IElementsTreeAction } from './IElementsTreeAction';
Expand Down Expand Up @@ -93,7 +93,16 @@ interface IOptions extends IElementsTreeOptions {
folderExplorer: IFolderExplorerContext;
}

interface ILoadingNodesState {
state: Map<string, Set<number>>;
add: (nodeId: string, timestamp: number) => void;
reset: (nodeId: string) => void;
remove: (nodeId: string, timestamp: number) => void;
isFirstLoadingNode: (nodeId: string, timestamp: number) => boolean;
}

export interface IElementsTree extends ILoadableState {
loadingNodesState: ILoadingNodesState;
actions: ISyncExecutor<IElementsTreeAction>;
settings?: IElementsTreeSettings;
baseRoot: string;
Expand Down Expand Up @@ -140,6 +149,42 @@ export function useElementsTree(options: IOptions): IElementsTree {
const connectionInfoResource = useService(ConnectionInfoResource);
const elementsTreeService = useService(ElementsTreeService);

const loadingNodesState = useObjectRef<ILoadingNodesState>({
state: new Map<string, Set<number>>(), // nodeId -> Set<timestamp>
add: (nodeId: string, timestamp: number) => {
let nodes = loadingNodesState.state.get(nodeId);

if (!nodes) {
nodes = new Set();
}

nodes.add(timestamp);
loadingNodesState.state.set(nodeId, nodes);
},
reset(nodeId: string) {
loadingNodesState.state.delete(nodeId);
},
remove(nodeId: string, timestamp: number) {
const nodes = loadingNodesState.state.get(nodeId);

if (!nodes) {
return;
}

nodes.delete(timestamp);
this.state.set(nodeId, nodes);
},
isFirstLoadingNode(nodeId: string, timestamp: number) {
const nodes = this.state.get(nodeId);

if (!nodes) {
return true;
}

return nodes.size === 0 || (nodes.size === 1 && nodes.has(timestamp));
},
});

const [localTreeNodesState] = useState(
() =>
new MetadataMap<string, ITreeNodeState>(() => ({
Expand Down Expand Up @@ -184,83 +229,108 @@ export function useElementsTree(options: IOptions): IElementsTree {
options.folderExplorer.open([], options.baseRoot);
} else {
this.exitNodeFolder(preloadedRoot);
loadingNodesState.reset(preloadedRoot);
}
return;
}

let children = [nodeId];
let children: Set<string> = new Set([nodeId]);

while (children.length > 0) {
const nextChildren: string[] = [];
while (children.size > 0) {
const nextChildren: Set<string> = new Set();

await Promise.all(
children.map(async child => {
await projectInfoResource.waitLoad();
await connectionInfoResource.waitLoad();
await navTreeResource.waitLoad();
await navNodeInfoResource.waitLoad();

const expanded = elementsTree.isNodeExpanded(child, true);
if (!expanded && child !== options.root) {
if (navNodeInfoResource.isOutdated(child)) {
const node = navNodeInfoResource.get(child);
Array.from(children).map(async child => {
const loadingNodeChildrenTimestamp = Date.now();
loadingNodesState.add(child, loadingNodeChildrenTimestamp);

if (node?.parentId !== undefined && !navTreeResource.isOutdated(node.parentId)) {
await navNodeInfoResource.load(child);
}
}
if (!loadingNodesState.isFirstLoadingNode(child, loadingNodeChildrenTimestamp)) {
return;
}

const loaded = await handleLoadChildren(child, false);
try {
await projectInfoResource.waitLoad();
await connectionInfoResource.waitLoad();
await navTreeResource.waitLoad();
await navNodeInfoResource.waitLoad();

if (!loaded) {
const node = navNodeInfoResource.get(child);
const expanded = elementsTree.isNodeExpanded(child, true);

if (node && expanded && elementsTree.isNodeExpandable(child)) {
await elementsTree.expand(node, false);
if (!expanded && child !== options.root) {
if (navNodeInfoResource.isOutdated(child)) {
const node = navNodeInfoResource.get(child);

if (node?.parentId !== undefined && !navTreeResource.isOutdated(node.parentId)) {
await navNodeInfoResource.load(child);
}
}

loadingNodesState.remove(child, loadingNodeChildrenTimestamp);
return;
}
return;
}

const pageInfo = navTreeResource.offsetPagination.getPageInfo(CachedResourceOffsetPageKey(0, 0).setTarget(child));
const loaded = await handleLoadChildren(child, false);

if (!loaded) {
const node = navNodeInfoResource.get(child);

if (node && expanded && elementsTree.isNodeExpandable(child)) {
await elementsTree.expand(node, false);
}

if (pageInfo) {
const lastOffset = getNextPageOffset(pageInfo);
for (let offset = 0; offset < lastOffset; offset += navTreeResource.childrenLimit) {
await navTreeResource.load(CachedResourceOffsetPageKey(offset, navTreeResource.childrenLimit).setTarget(child));
loadingNodesState.remove(child, loadingNodeChildrenTimestamp);
return;
}
}

if (elementsTree.isNodeExpandable(child) && expanded && elementsTree.getNodeChildren(child).length === 0) {
const node = navNodeInfoResource.get(child);
const pageInfo = navTreeResource.offsetPagination.getPageInfo(CachedResourceOffsetPageKey(0, 0).setTarget(child));

if (node) {
await elementsTree.expand(node, false);
if (pageInfo) {
const lastOffset = getNextPageOffset(pageInfo);
for (let offset = 0; offset < lastOffset; offset += navTreeResource.childrenLimit) {
await navTreeResource.load(CachedResourceOffsetPageKey(offset, navTreeResource.childrenLimit).setTarget(child));
}
}
return;
}

if (
elementsTree.settings?.foldersTree &&
options.folderExplorer.options.expandFoldersWithSingleElement &&
child === options.root &&
elementsTree.getNodeChildren(child).length === 1
) {
const nextNode = elementsTree.getNodeChildren(child)[0];
if (elementsTree.isNodeExpandable(child) && expanded && elementsTree.getNodeChildren(child).length === 0) {
const node = navNodeInfoResource.get(child);

if (elementsTree.isNodeExpandable(nextNode) || elementsTree.isNodeExpanded(nextNode)) {
options.folderExplorer.open(navNodeInfoResource.getParents(nextNode), nextNode);
if (node) {
await elementsTree.expand(node, false);
}

loadingNodesState.remove(child, loadingNodeChildrenTimestamp);
return;
}

if (
elementsTree.settings?.foldersTree &&
options.folderExplorer.options.expandFoldersWithSingleElement &&
child === options.root &&
elementsTree.getNodeChildren(child).length === 1
) {
const nextNode = elementsTree.getNodeChildren(child)[0];

if (elementsTree.isNodeExpandable(nextNode) || elementsTree.isNodeExpanded(nextNode)) {
options.folderExplorer.open(navNodeInfoResource.getParents(nextNode), nextNode);
}
}

new Set(navTreeResource.get(child) || []).forEach(candidate => {
nextChildren.add(candidate);
});

loadingNodesState.remove(child, loadingNodeChildrenTimestamp);
} finally {
loadingNodesState.remove(child, loadingNodeChildrenTimestamp);
}
nextChildren.push(...(navTreeResource.get(child) || []));
}),
);

children = nextChildren;
children = new Set(nextChildren);
}
} finally {
elementsTree.loading = false;
loadingNodesState.reset(nodeId);
}
},

Expand Down Expand Up @@ -370,18 +440,20 @@ export function useElementsTree(options: IOptions): IElementsTree {
filter: '',
}),
async data => {
if (!options.settings?.saveFilter) {
data.filter = '';
}
runInAction(() => {
if (!options.settings?.saveFilter) {
data.filter = '';
}

if (!options.settings?.saveExpanded) {
data.nodeState = [];
}
if (!options.settings?.saveExpanded) {
data.nodeState = [];
}

state.sync(data.nodeState);
state.sync(data.nodeState);
});

try {
await functionsRef.loadTree(options.root);
loadTreeThreshold();
} catch {}
},
data => typeof data === 'object' && typeof data.filter === 'string' && Array.isArray(data.nodeState),
Expand All @@ -391,7 +463,7 @@ export function useElementsTree(options: IOptions): IElementsTree {
() => ({
actions: new SyncExecutor(),
activeDnDData: [],
loading: options.settings?.saveExpanded || false,
loading: options.settings?.saveExpanded || Array.from(loadingNodesState.state.values()).some(timestamps => timestamps.size > 0) || false,
get filter(): string {
return this.userData.filter;
},
Expand Down Expand Up @@ -555,19 +627,24 @@ export function useElementsTree(options: IOptions): IElementsTree {
await options.onClick?.(node);
},
async open(node: NavNode, path: string[], leaf: boolean) {
const expandableOrExpanded = this.isNodeExpandable(node.id) || this.isNodeExpanded(node.id);
if (!leaf && this.settings?.foldersTree && expandableOrExpanded) {
const nodeId = node.id;

const loaded = await handleLoadChildren(node.id, false);
if (loaded) {
this.setFilter('');
options.folderExplorer.open(path, nodeId);
try {
const expandableOrExpanded = this.isNodeExpandable(node.id) || this.isNodeExpanded(node.id);

loadingNodesState.add(node.id, Date.now());

if (!leaf && this.settings?.foldersTree && expandableOrExpanded) {
const loaded = await handleLoadChildren(node.id, false);
if (loaded) {
this.setFilter('');
options.folderExplorer.open(path, node.id);
}
}
}

const folder = (!leaf && this.settings?.foldersTree) || false;
await options.onOpen?.(node, folder);
const folder = (!leaf && this.settings?.foldersTree) || false;
await options.onOpen?.(node, folder);
} finally {
loadingNodesState.reset(node.id);
}
},
async expand(node: NavNode, state: boolean) {
if (!this.isNodeExpandable(node.id)) {
Expand All @@ -594,9 +671,10 @@ export function useElementsTree(options: IOptions): IElementsTree {
}
} else {
await options.onExpand?.(node, state);
treeNodeState.expanded = state && this.getNodeChildren(node.id).length > 0;
}

treeNodeState.expanded = state && this.getNodeChildren(node.id).length > 0;

if (state) {
await functionsRef.loadTree(node.id);
}
Expand Down Expand Up @@ -640,12 +718,17 @@ export function useElementsTree(options: IOptions): IElementsTree {
async loadPath(path: string[], lastNode?: string): Promise<string | undefined> {
let lastLoadedNode: string | undefined;
for (const nodeId of path) {
const loaded = await handleLoadChildren(nodeId, false);
try {
loadingNodesState.add(nodeId, Date.now());
const loaded = await handleLoadChildren(nodeId, false);

if (!loaded) {
return lastLoadedNode;
if (!loaded) {
return lastLoadedNode;
}
lastLoadedNode = nodeId;
} finally {
loadingNodesState.reset(nodeId);
}
lastLoadedNode = nodeId;
}

if (lastNode !== undefined && lastLoadedNode !== undefined && options.getChildren(lastLoadedNode)?.includes(lastNode)) {
Expand Down Expand Up @@ -682,6 +765,7 @@ export function useElementsTree(options: IOptions): IElementsTree {
},
{
state,
loadingNodesState,
isGroup: options.isGroup,
disabled: options.disabled,
root: options.root,
Expand All @@ -695,14 +779,14 @@ export function useElementsTree(options: IOptions): IElementsTree {
);

useEffect(() => {
functionsRef.loadTree(options.root).catch(() => ({}));
loadTreeThreshold();
}, [options.root]);

const loadTreeThreshold = useCallback(
throttle(function refreshRoot() {
debounce(function refreshRoot() {
functionsRef.loadTree(options.root).catch(() => ({}));
}, 100),
[],
[options.root],
);

useResource(useElementsTree, navTreeResource, options.baseRoot, {
Expand Down
Loading