mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core-blocks): CB-1405 folders automatic opening
This commit is contained in:
@@ -89,8 +89,45 @@ export const ElementsTree = observer<Props>(function ElementsTree({
|
||||
const navNodeInfoResource = useService(NavNodeInfoResource);
|
||||
const navigationTreeService = useService(NavigationTreeService);
|
||||
|
||||
const autoOpenFolders = useCallback(async function autoOpenFolders(nodeId: string, path: string[]) {
|
||||
path = [...path];
|
||||
|
||||
if (!tree.foldersTree) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (folderExplorer.options.expandFoldersWithSingleElement) {
|
||||
const children = navigationTreeService.getChildren(nodeId);
|
||||
|
||||
if (children?.length === 1) {
|
||||
const nextNodeId = children[0];
|
||||
const loaded = await navigationTreeService.loadNestedNodes(nextNodeId, false);
|
||||
|
||||
if (!loaded) {
|
||||
break;
|
||||
}
|
||||
|
||||
path.push(nodeId);
|
||||
nodeId = nextNodeId;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
folderExplorer.open(path, nodeId);
|
||||
|
||||
}, []);
|
||||
|
||||
const children = useMapResource(ElementsTree, NavTreeResource, root, {
|
||||
onLoad: async resource => !(await resource.preloadNodeParents(fullPath)),
|
||||
onLoad: async resource => {
|
||||
const preload = await resource.preloadNodeParents(fullPath);
|
||||
|
||||
if (!preload) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await autoOpenFolders(root, folderExplorer.path);
|
||||
},
|
||||
});
|
||||
|
||||
const nameFilter = useMemo(() => elementsTreeNameFilter(navNodeInfoResource), [navNodeInfoResource]);
|
||||
@@ -125,10 +162,11 @@ export const ElementsTree = observer<Props>(function ElementsTree({
|
||||
await onClick?.(node);
|
||||
|
||||
if (!leaf && tree.foldersTree) {
|
||||
const loaded = await navigationTreeService.loadNestedNodes(node.id, true);
|
||||
const nodeId = node.id;
|
||||
const loaded = await navigationTreeService.loadNestedNodes(nodeId, true);
|
||||
|
||||
if (loaded) {
|
||||
folderExplorer.open(path, node.id);
|
||||
await autoOpenFolders(nodeId, path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,8 +36,6 @@ export interface ITreeNodeState {
|
||||
}
|
||||
|
||||
interface IElementsTreeUserState {
|
||||
foldersTree: boolean;
|
||||
showFolderExplorerPath: boolean;
|
||||
nodeState: Array<[string, ITreeNodeState]>;
|
||||
}
|
||||
|
||||
@@ -90,14 +88,12 @@ export function useElementsTree(options: IOptions): IElementsTree {
|
||||
expanded: false,
|
||||
})));
|
||||
const state = options.localState || localTreeNodesState;
|
||||
let foldersTree = options.foldersTree;
|
||||
let showFolderExplorerPath = options.showFolderExplorerPath;
|
||||
const foldersTree = options.foldersTree;
|
||||
const showFolderExplorerPath = options.showFolderExplorerPath;
|
||||
|
||||
const userState = useUserData<IElementsTreeUserState>(
|
||||
useUserData<IElementsTreeUserState>(
|
||||
`elements-tree-${options.baseRoot}`,
|
||||
() => observable<IElementsTreeUserState>({
|
||||
foldersTree,
|
||||
showFolderExplorerPath,
|
||||
nodeState: [],
|
||||
}),
|
||||
async data => {
|
||||
@@ -115,14 +111,9 @@ export function useElementsTree(options: IOptions): IElementsTree {
|
||||
data => (
|
||||
typeof data === 'object'
|
||||
&& Array.isArray(data.nodeState)
|
||||
&& typeof data.foldersTree === 'boolean'
|
||||
&& typeof data.showFolderExplorerPath === 'boolean'
|
||||
)
|
||||
);
|
||||
|
||||
foldersTree = userState.foldersTree;
|
||||
showFolderExplorerPath = userState.showFolderExplorerPath;
|
||||
|
||||
async function loadTree(nodeId: string) {
|
||||
const preloaded = await navTreeResource.preloadNodeParents(options.folderExplorer.fullPath);
|
||||
|
||||
|
||||
@@ -8,11 +8,16 @@
|
||||
|
||||
import { createContext } from 'react';
|
||||
|
||||
export interface IFolderExplorerOptions {
|
||||
expandFoldersWithSingleElement?: boolean;
|
||||
}
|
||||
|
||||
export interface IFolderExplorerContext {
|
||||
root: string;
|
||||
path: string[];
|
||||
fullPath: string[];
|
||||
folder: string;
|
||||
options: IFolderExplorerOptions;
|
||||
|
||||
open: (path: string[], folder: string) => void;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import { action, observable } from 'mobx';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { useObservableRef } from '../useObservableRef';
|
||||
import { FolderExplorerContext, IFolderExplorerContext } from './FolderExplorerContext';
|
||||
import { FolderExplorerContext, IFolderExplorerContext, IFolderExplorerOptions } from './FolderExplorerContext';
|
||||
|
||||
export function useFolderExplorer(root: string): IFolderExplorerContext {
|
||||
export function useFolderExplorer(root: string, options: IFolderExplorerOptions = {}): IFolderExplorerContext {
|
||||
const context = useContext(FolderExplorerContext);
|
||||
|
||||
const state = useObservableRef<IFolderExplorerContext>(() => ({
|
||||
@@ -20,6 +20,7 @@ export function useFolderExplorer(root: string): IFolderExplorerContext {
|
||||
path: [],
|
||||
fullPath: [root],
|
||||
folder: root,
|
||||
options,
|
||||
open(path: string[], folder: string) {
|
||||
this.path = path.slice();
|
||||
this.fullPath = [...path, folder];
|
||||
@@ -30,6 +31,7 @@ export function useFolderExplorer(root: string): IFolderExplorerContext {
|
||||
path: observable,
|
||||
fullPath: observable,
|
||||
folder: observable,
|
||||
options: observable.ref,
|
||||
open: action.bound,
|
||||
}, false);
|
||||
|
||||
|
||||
@@ -64,8 +64,11 @@ export const TreeNodeExpand = observer<Props>(function TreeNodeExpand({
|
||||
return styled(styles)(
|
||||
<arrow className={className} onClick={handleExpand} onDoubleClick={handleDbClick}>
|
||||
{loading && <Loader small fullSize />}
|
||||
{!loading && (!leaf || context.externalExpanded) && big && <Icon name="angle" viewBox="0 0 15 8" />}
|
||||
{!loading && (!leaf || context.externalExpanded) && !big && <Icon name="arrow" viewBox="0 0 16 16" />}
|
||||
{!loading && (!leaf || context.externalExpanded) && (
|
||||
big
|
||||
? <Icon name="angle" viewBox="0 0 15 8" />
|
||||
: <Icon name="arrow" viewBox="0 0 16 16" />
|
||||
)}
|
||||
</arrow>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user