mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Lazy load database offer in data explorer (#208)
Co-authored-by: zfoster <notzachfoster@gmail.com>
This commit is contained in:
@@ -159,4 +159,20 @@ describe("TreeNodeComponent", () => {
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders loading icon", () => {
|
||||
const node: TreeNode = {
|
||||
label: "label",
|
||||
children: [],
|
||||
isExpanded: true
|
||||
};
|
||||
|
||||
const props = {
|
||||
node,
|
||||
generation: 2,
|
||||
paddingLeft: 9
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,12 +17,14 @@ import {
|
||||
|
||||
import TriangleDownIcon from "../../../../images/Triangle-down.svg";
|
||||
import TriangleRightIcon from "../../../../images/Triangle-right.svg";
|
||||
import LoadingIndicator_3Squares from "../../../../images/LoadingIndicator_3Squares.gif";
|
||||
|
||||
export interface TreeNodeMenuItem {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
iconSrc?: string;
|
||||
isDisabled?: boolean;
|
||||
styleClass?: string;
|
||||
}
|
||||
|
||||
export interface TreeNode {
|
||||
@@ -37,6 +39,7 @@ export interface TreeNode {
|
||||
data?: any; // Piece of data corresponding to this node
|
||||
timestamp?: number;
|
||||
isLeavesParentsSeparate?: boolean; // Display parents together first, then leaves
|
||||
isLoading?: boolean;
|
||||
isSelected?: () => boolean;
|
||||
onClick?: (isExpanded: boolean) => void; // Only if a leaf, other click will expand/collapse
|
||||
onExpanded?: () => void;
|
||||
@@ -183,6 +186,9 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
)}
|
||||
{node.contextMenu && this.renderContextMenuButton(node)}
|
||||
</div>
|
||||
<div className="loadingIconContainer">
|
||||
<img className="loadingIcon" src={LoadingIndicator_3Squares} hidden={!this.props.node.isLoading} />
|
||||
</div>
|
||||
{node.children && (
|
||||
<AnimateHeight duration={TreeNodeComponent.transitionDurationMS} height={this.state.isExpanded ? "auto" : 0}>
|
||||
<div className="nodeChildren" data-test={node.label}>
|
||||
@@ -256,13 +262,20 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
onContextMenu={e => e.target.dispatchEvent(TreeNodeComponent.createClickEvent())}
|
||||
>
|
||||
{props.item.onRenderIcon()}
|
||||
<span className="treeComponentMenuItemLabel">{props.item.text}</span>
|
||||
<span
|
||||
className={
|
||||
"treeComponentMenuItemLabel" + (props.item.className ? ` ${props.item.className}Label` : "")
|
||||
}
|
||||
>
|
||||
{props.item.text}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
items: node.contextMenu.map((menuItem: TreeNodeMenuItem) => ({
|
||||
key: menuItem.label,
|
||||
text: menuItem.label,
|
||||
disabled: menuItem.isDisabled,
|
||||
className: menuItem.styleClass,
|
||||
onClick: menuItem.onClick,
|
||||
onRenderIcon: (props: any) => <img src={menuItem.iconSrc} alt="" />
|
||||
}))
|
||||
|
||||
@@ -63,6 +63,15 @@ exports[`TreeNodeComponent does not render children by default 1`] = `
|
||||
label
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="loadingIconContainer"
|
||||
>
|
||||
<img
|
||||
className="loadingIcon"
|
||||
hidden={true}
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<AnimateHeight
|
||||
animateOpacity={false}
|
||||
animationStateClasses={
|
||||
@@ -179,6 +188,7 @@ exports[`TreeNodeComponent renders a simple node (sorted children, expanded) 1`]
|
||||
"isBeakVisible": false,
|
||||
"items": Array [
|
||||
Object {
|
||||
"className": undefined,
|
||||
"disabled": true,
|
||||
"key": "menuLabel",
|
||||
"onClick": undefined,
|
||||
@@ -201,6 +211,15 @@ exports[`TreeNodeComponent renders a simple node (sorted children, expanded) 1`]
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="loadingIconContainer"
|
||||
>
|
||||
<img
|
||||
className="loadingIcon"
|
||||
hidden={true}
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<AnimateHeight
|
||||
animateOpacity={false}
|
||||
animationStateClasses={
|
||||
@@ -261,6 +280,77 @@ exports[`TreeNodeComponent renders a simple node (sorted children, expanded) 1`]
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`TreeNodeComponent renders loading icon 1`] = `
|
||||
<div
|
||||
className=" main2 nodeItem "
|
||||
onClick={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
>
|
||||
<div
|
||||
className="treeNodeHeader "
|
||||
data-test="label"
|
||||
style={
|
||||
Object {
|
||||
"paddingLeft": 9,
|
||||
}
|
||||
}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<img
|
||||
alt="label branch is expanded"
|
||||
className="expandCollapseIcon"
|
||||
onKeyPress={[Function]}
|
||||
role="button"
|
||||
src=""
|
||||
tabIndex={0}
|
||||
/>
|
||||
<span
|
||||
className="nodeLabel"
|
||||
title="label"
|
||||
>
|
||||
label
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="loadingIconContainer"
|
||||
>
|
||||
<img
|
||||
className="loadingIcon"
|
||||
hidden={true}
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<AnimateHeight
|
||||
animateOpacity={false}
|
||||
animationStateClasses={
|
||||
Object {
|
||||
"animating": "rah-animating",
|
||||
"animatingDown": "rah-animating--down",
|
||||
"animatingToHeightAuto": "rah-animating--to-height-auto",
|
||||
"animatingToHeightSpecific": "rah-animating--to-height-specific",
|
||||
"animatingToHeightZero": "rah-animating--to-height-zero",
|
||||
"animatingUp": "rah-animating--up",
|
||||
"static": "rah-static",
|
||||
"staticHeightAuto": "rah-static--height-auto",
|
||||
"staticHeightSpecific": "rah-static--height-specific",
|
||||
"staticHeightZero": "rah-static--height-zero",
|
||||
}
|
||||
}
|
||||
applyInlineTransitions={true}
|
||||
delay={0}
|
||||
duration={200}
|
||||
easing="ease"
|
||||
height="auto"
|
||||
style={Object {}}
|
||||
>
|
||||
<div
|
||||
className="nodeChildren"
|
||||
data-test="label"
|
||||
/>
|
||||
</AnimateHeight>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`TreeNodeComponent renders sorted children, expanded, leaves and parents separated 1`] = `
|
||||
<div
|
||||
className="nodeClassname main12 nodeItem "
|
||||
@@ -331,6 +421,15 @@ exports[`TreeNodeComponent renders sorted children, expanded, leaves and parents
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="loadingIconContainer"
|
||||
>
|
||||
<img
|
||||
className="loadingIcon"
|
||||
hidden={true}
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<AnimateHeight
|
||||
animateOpacity={false}
|
||||
animationStateClasses={
|
||||
@@ -450,6 +549,15 @@ exports[`TreeNodeComponent renders unsorted children by default 1`] = `
|
||||
label
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="loadingIconContainer"
|
||||
>
|
||||
<img
|
||||
className="loadingIcon"
|
||||
hidden={true}
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<AnimateHeight
|
||||
animateOpacity={false}
|
||||
animationStateClasses={
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
&.showingMenu {
|
||||
background-color: #EEE;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.treeMenuEllipsis {
|
||||
@@ -78,3 +78,12 @@
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.loadingIconContainer {
|
||||
width: 100%;
|
||||
|
||||
.loadingIcon {
|
||||
height: 6px;
|
||||
margin-left: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user