mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
* CB-4541 feat: tree filter * CB-4541 feat: tree empty placeholders * CB-4541 fix: settings overflow scroll effect * CB-4541 fix: settings groups size * CB-4541 fix: sync groups when filtering * CB-4541 chore: performance optimization * chore: review fixes * chore: replace inline styles * chore: replace inline styles * chore: hide extra settings from UI * chore: hide groups view from settings * fix: add override options to devtools * fix: trim filter in settings search * chore: localization --------- Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com> Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
/*
|
|
* CloudBeaver - Cloud Database Manager
|
|
* Copyright (C) 2020-2024 DBeaver Corp and others
|
|
*
|
|
* Licensed under the Apache License, Version 2.0.
|
|
* you may not use this file except in compliance with the License.
|
|
*/
|
|
import { observable } from 'mobx';
|
|
|
|
import { useObservableRef } from '@cloudbeaver/core-blocks';
|
|
|
|
import type { INodeRenderer, NodeComponent } from './INodeRenderer.js';
|
|
import type { ITreeData } from './ITreeData.js';
|
|
|
|
interface IOptions {
|
|
data: ITreeData;
|
|
nodeRenderers?: INodeRenderer[];
|
|
onNodeClick?(id: string): void | Promise<void>;
|
|
onNodeDoubleClick?(id: string): void | Promise<void>;
|
|
getNodeHeight(id: string): number;
|
|
}
|
|
|
|
export interface ITree {
|
|
getNodeComponent(id: string): NodeComponent | null;
|
|
getNodeHeight(id: string): number;
|
|
|
|
openNode(id: string): Promise<void>;
|
|
clickNode(id: string): Promise<void>;
|
|
expandNode(id: string, state: boolean): Promise<void>;
|
|
selectNode(id: string, state: boolean): void;
|
|
}
|
|
|
|
export function useTree(options: IOptions): ITree {
|
|
options = useObservableRef(options, {
|
|
data: observable.ref,
|
|
nodeRenderers: observable.ref,
|
|
onNodeClick: observable.ref,
|
|
onNodeDoubleClick: observable.ref,
|
|
getNodeHeight: observable.ref,
|
|
});
|
|
|
|
const data = useObservableRef(
|
|
() => ({
|
|
getNodeComponent(id: string): NodeComponent | null {
|
|
if (!options.nodeRenderers) {
|
|
return null;
|
|
}
|
|
|
|
for (const renderer of options.nodeRenderers) {
|
|
const component = renderer(id);
|
|
|
|
if (component) {
|
|
return component;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
},
|
|
getNodeHeight(id: string): number {
|
|
return options.getNodeHeight(id);
|
|
},
|
|
async clickNode(id: string) {
|
|
await options.onNodeClick?.(id);
|
|
},
|
|
async openNode(id: string) {
|
|
await options.onNodeDoubleClick?.(id);
|
|
},
|
|
async expandNode(id: string, state: boolean) {
|
|
try {
|
|
options.data.updateState(id, { expanded: state });
|
|
if (state) {
|
|
await options.data.load(id, true);
|
|
const children = options.data.getChildren(id);
|
|
|
|
if (children.length === 0) {
|
|
options.data.updateState(id, { expanded: false });
|
|
}
|
|
}
|
|
} catch (exception) {}
|
|
},
|
|
selectNode(id: string, state: boolean) {
|
|
options.data.updateState(id, { selected: state });
|
|
},
|
|
}),
|
|
{},
|
|
{},
|
|
);
|
|
|
|
return data;
|
|
}
|