mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-17 09:47:06 +00:00
Refactor ResourceTree to use FluentUI 9 Tree component
This commit is contained in:
parent
f8ff0626d9
commit
fa865f99c8
33018
package-lock.json
generated
33018
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@
|
||||
"@babel/plugin-proposal-class-properties": "7.12.1",
|
||||
"@babel/plugin-proposal-decorators": "7.12.12",
|
||||
"@fluentui/react": "8.14.3",
|
||||
"@fluentui/react-components": "9.30.1",
|
||||
"@jupyterlab/services": "6.0.2",
|
||||
"@jupyterlab/terminal": "3.0.3",
|
||||
"@microsoft/applicationinsights-web": "2.6.1",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import { TreeComponent, TreeNode, TreeNodeComponent } from "./TreeComponent";
|
||||
import React from "react";
|
||||
import { TreeComponent, TreeNode, TreeNodeComponent_old } from "./TreeComponent";
|
||||
|
||||
const buildChildren = (): TreeNode[] => {
|
||||
const grandChild11: TreeNode = {
|
||||
@ -98,7 +98,7 @@ describe("TreeNodeComponent", () => {
|
||||
generation: 12,
|
||||
paddingLeft: 23,
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
const wrapper = shallow(<TreeNodeComponent_old {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@ -113,7 +113,7 @@ describe("TreeNodeComponent", () => {
|
||||
generation: 2,
|
||||
paddingLeft: 9,
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
const wrapper = shallow(<TreeNodeComponent_old {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@ -128,7 +128,7 @@ describe("TreeNodeComponent", () => {
|
||||
generation: 2,
|
||||
paddingLeft: 9,
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
const wrapper = shallow(<TreeNodeComponent_old {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@ -156,7 +156,7 @@ describe("TreeNodeComponent", () => {
|
||||
generation: 12,
|
||||
paddingLeft: 23,
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
const wrapper = shallow(<TreeNodeComponent_old {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@ -172,7 +172,7 @@ describe("TreeNodeComponent", () => {
|
||||
generation: 2,
|
||||
paddingLeft: 9,
|
||||
};
|
||||
const wrapper = shallow(<TreeNodeComponent {...props} />);
|
||||
const wrapper = shallow(<TreeNodeComponent_old {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -12,6 +12,8 @@ import {
|
||||
IContextualMenuItemProps,
|
||||
IContextualMenuProps,
|
||||
} from "@fluentui/react";
|
||||
import { Button, Menu, MenuItem, MenuList, MenuPopover, MenuTrigger, Spinner, Tree, TreeItem, TreeItemLayout } from "@fluentui/react-components";
|
||||
import { MoreHorizontal20Regular } from "@fluentui/react-icons";
|
||||
import * as React from "react";
|
||||
import AnimateHeight from "react-animate-height";
|
||||
import LoadingIndicator_3Squares from "../../../../images/LoadingIndicator_3Squares.gif";
|
||||
@ -20,7 +22,6 @@ import TriangleRightIcon from "../../../../images/Triangle-right.svg";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
export interface TreeNodeMenuItem {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
@ -58,13 +59,90 @@ export interface TreeComponentProps {
|
||||
export class TreeComponent extends React.Component<TreeComponentProps> {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div style={this.props.style} className={`treeComponent ${this.props.className}`} role="tree">
|
||||
<TreeNodeComponent paddingLeft={0} node={this.props.rootNode} generation={0} />
|
||||
</div>
|
||||
|
||||
<Tree>
|
||||
<TreeNodeComponent node={this.props.rootNode} />
|
||||
</Tree>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const TreeNodeComponent: React.FC<{ node: TreeNode, className?: string }> = ({ node }): JSX.Element => {
|
||||
const { children } = node;
|
||||
const defaultOpenItems = node.isExpanded ? children?.map((child: TreeNode) => child.label) : undefined;
|
||||
|
||||
const getSortedChildren = (treeNode: TreeNode): TreeNode[] => {
|
||||
if (!treeNode || !treeNode.children) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const compareFct = (a: TreeNode, b: TreeNode) => a.label.localeCompare(b.label);
|
||||
|
||||
let unsortedChildren;
|
||||
if (treeNode.isLeavesParentsSeparate) {
|
||||
// Separate parents and leave
|
||||
const parents: TreeNode[] = treeNode.children.filter((node) => node.children);
|
||||
const leaves: TreeNode[] = treeNode.children.filter((node) => !node.children);
|
||||
|
||||
if (treeNode.isAlphaSorted) {
|
||||
parents.sort(compareFct);
|
||||
leaves.sort(compareFct);
|
||||
}
|
||||
|
||||
unsortedChildren = parents.concat(leaves);
|
||||
} else {
|
||||
unsortedChildren = treeNode.isAlphaSorted ? treeNode.children.sort(compareFct) : treeNode.children;
|
||||
}
|
||||
|
||||
return unsortedChildren;
|
||||
};
|
||||
|
||||
return (
|
||||
<TreeItem key={node.label} value={node.label} itemType={node.children?.length > 0 || node.isLoading ? "branch" : "leaf"}>
|
||||
<TreeItemLayout
|
||||
className={node.className}
|
||||
onClick={() => node.onClick && node.onClick(false)}
|
||||
actions={node.contextMenu &&
|
||||
<Menu>
|
||||
<MenuTrigger disableButtonEnhancement>
|
||||
<Button aria-label="More options" appearance="subtle" icon={<MoreHorizontal20Regular />} />
|
||||
</MenuTrigger>
|
||||
<MenuPopover>
|
||||
<MenuList>{node.contextMenu.map(menuItem => (
|
||||
<MenuItem disabled={menuItem.isDisabled} key={menuItem.label} onClick={menuItem.onClick}>{menuItem.label}</MenuItem>
|
||||
))}</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
}
|
||||
expandIcon={node.isLoading ? <Spinner size="tiny" /> : undefined}
|
||||
>{node.label}</TreeItemLayout>
|
||||
{!node.isLoading && node.children?.length > 0 && <Tree defaultOpenItems={defaultOpenItems}>
|
||||
{getSortedChildren(node).map((childNode: TreeNode) => (
|
||||
<TreeNodeComponent key={childNode.id} node={childNode} />
|
||||
))}
|
||||
</Tree>}
|
||||
</TreeItem>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/* Tree node is a react component */
|
||||
interface TreeNodeComponentProps {
|
||||
node: TreeNode;
|
||||
@ -76,7 +154,7 @@ interface TreeNodeComponentState {
|
||||
isExpanded: boolean;
|
||||
isMenuShowing: boolean;
|
||||
}
|
||||
export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, TreeNodeComponentState> {
|
||||
export class TreeNodeComponent_old extends React.Component<TreeNodeComponentProps, TreeNodeComponentState> {
|
||||
private static readonly paddingPerGenerationPx = 16;
|
||||
private static readonly iconOffset = 22;
|
||||
private static readonly transitionDurationMS = 200;
|
||||
@ -97,9 +175,9 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
// Only call when expand has actually changed
|
||||
if (this.state.isExpanded !== prevState.isExpanded) {
|
||||
if (this.state.isExpanded) {
|
||||
this.props.node.onExpanded && setTimeout(this.props.node.onExpanded, TreeNodeComponent.callbackDelayMS);
|
||||
this.props.node.onExpanded && setTimeout(this.props.node.onExpanded, TreeNodeComponent_old.callbackDelayMS);
|
||||
} else {
|
||||
this.props.node.onCollapsed && setTimeout(this.props.node.onCollapsed, TreeNodeComponent.callbackDelayMS);
|
||||
this.props.node.onCollapsed && setTimeout(this.props.node.onCollapsed, TreeNodeComponent_old.callbackDelayMS);
|
||||
}
|
||||
}
|
||||
if (this.props.node.isExpanded !== this.isExpanded) {
|
||||
@ -145,13 +223,13 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
}
|
||||
|
||||
private renderNode(node: TreeNode, generation: number): JSX.Element {
|
||||
let paddingLeft = generation * TreeNodeComponent.paddingPerGenerationPx;
|
||||
let paddingLeft = generation * TreeNodeComponent_old.paddingPerGenerationPx;
|
||||
let additionalOffsetPx = 15;
|
||||
|
||||
if (node.children) {
|
||||
const childrenWithSubChildren = node.children.filter((child: TreeNode) => !!child.children);
|
||||
if (childrenWithSubChildren.length > 0) {
|
||||
additionalOffsetPx = TreeNodeComponent.iconOffset;
|
||||
additionalOffsetPx = TreeNodeComponent_old.iconOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,10 +237,10 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
const showSelected =
|
||||
this.props.node.isSelected &&
|
||||
this.props.node.isSelected() &&
|
||||
!TreeNodeComponent.isAnyDescendantSelected(this.props.node);
|
||||
!TreeNodeComponent_old.isAnyDescendantSelected(this.props.node);
|
||||
|
||||
const headerStyle: React.CSSProperties = { paddingLeft: this.props.paddingLeft };
|
||||
if (TreeNodeComponent.isNodeHeaderBlank(node)) {
|
||||
if (TreeNodeComponent_old.isNodeHeaderBlank(node)) {
|
||||
headerStyle.height = 0;
|
||||
headerStyle.padding = 0;
|
||||
}
|
||||
@ -194,10 +272,10 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
<img className="loadingIcon" src={LoadingIndicator_3Squares} hidden={!this.props.node.isLoading} />
|
||||
</div>
|
||||
{node.children && (
|
||||
<AnimateHeight duration={TreeNodeComponent.transitionDurationMS} height={this.state.isExpanded ? "auto" : 0}>
|
||||
<AnimateHeight duration={TreeNodeComponent_old.transitionDurationMS} height={this.state.isExpanded ? "auto" : 0}>
|
||||
<div className="nodeChildren" data-test={node.label} role="group">
|
||||
{TreeNodeComponent.getSortedChildren(node).map((childNode: TreeNode) => (
|
||||
<TreeNodeComponent
|
||||
{TreeNodeComponent_old.getSortedChildren(node).map((childNode: TreeNode) => (
|
||||
<TreeNodeComponent_old
|
||||
key={`${childNode.label}-${generation + 1}-${childNode.timestamp}`}
|
||||
node={childNode}
|
||||
generation={generation + 1}
|
||||
@ -220,7 +298,7 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
node.children &&
|
||||
node.children.reduce(
|
||||
(previous: boolean, child: TreeNode) =>
|
||||
previous || (child.isSelected && child.isSelected()) || TreeNodeComponent.isAnyDescendantSelected(child),
|
||||
previous || (child.isSelected && child.isSelected()) || TreeNodeComponent_old.isAnyDescendantSelected(child),
|
||||
false
|
||||
)
|
||||
);
|
||||
@ -231,7 +309,7 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
}
|
||||
|
||||
private onRightClick = (): void => {
|
||||
this.contextMenuRef.current.firstChild.dispatchEvent(TreeNodeComponent.createClickEvent());
|
||||
this.contextMenuRef.current.firstChild.dispatchEvent(TreeNodeComponent_old.createClickEvent());
|
||||
};
|
||||
|
||||
private renderContextMenuButton(node: TreeNode): JSX.Element {
|
||||
@ -264,7 +342,7 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
<div
|
||||
data-test={`treeComponentMenuItemContainer`}
|
||||
className="treeComponentMenuItemContainer"
|
||||
onContextMenu={(e) => e.target.dispatchEvent(TreeNodeComponent.createClickEvent())}
|
||||
onContextMenu={(e) => e.target.dispatchEvent(TreeNodeComponent_old.createClickEvent())}
|
||||
>
|
||||
{props.item.onRenderIcon()}
|
||||
<span
|
||||
@ -318,7 +396,7 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
if (node.children) {
|
||||
const isExpanded = !this.state.isExpanded;
|
||||
// Prevent collapsing if node header is blank
|
||||
if (!(TreeNodeComponent.isNodeHeaderBlank(node) && !isExpanded)) {
|
||||
if (!(TreeNodeComponent_old.isNodeHeaderBlank(node) && !isExpanded)) {
|
||||
this.setState({ isExpanded });
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Callout, DirectionalHint, ICalloutProps, ILinkProps, Link, Stack, Text } from "@fluentui/react";
|
||||
import { SampleDataTree } from "Explorer/Tree/SampleDataTree";
|
||||
import { BrandVariants, FluentProvider, Theme, Tree, createLightTheme } from "@fluentui/react-components";
|
||||
import { buildSampleDataTree } from "Explorer/Tree/SampleDataTree";
|
||||
import { getItemName } from "Utils/APITypeUtils";
|
||||
import * as React from "react";
|
||||
import shallow from "zustand/shallow";
|
||||
@ -26,9 +27,8 @@ import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import { useSidePanel } from "../../hooks/useSidePanel";
|
||||
import { useTabs } from "../../hooks/useTabs";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import { AccordionComponent, AccordionItemComponent } from "../Controls/Accordion/AccordionComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import { TreeComponent, TreeNode, TreeNodeMenuItem } from "../Controls/TreeComponent/TreeComponent";
|
||||
import { TreeNode, TreeNodeComponent, TreeNodeMenuItem } from "../Controls/TreeComponent/TreeComponent";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { mostRecentActivity } from "../MostRecentActivity/MostRecentActivity";
|
||||
@ -50,6 +50,30 @@ interface ResourceTreeProps {
|
||||
container: Explorer;
|
||||
}
|
||||
|
||||
|
||||
const cosmosdb: BrandVariants = {
|
||||
10: "#020305",
|
||||
20: "#111723",
|
||||
30: "#16263D",
|
||||
40: "#193253",
|
||||
50: "#1B3F6A",
|
||||
60: "#1B4C82",
|
||||
70: "#18599B",
|
||||
80: "#1267B4",
|
||||
90: "#3174C2",
|
||||
100: "#4F82C8",
|
||||
110: "#6790CF",
|
||||
120: "#7D9ED5",
|
||||
130: "#92ACDC",
|
||||
140: "#A6BAE2",
|
||||
150: "#BAC9E9",
|
||||
160: "#CDD8EF"
|
||||
};
|
||||
|
||||
const lightTheme: Theme = {
|
||||
...createLightTheme(cosmosdb),
|
||||
};
|
||||
|
||||
export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: ResourceTreeProps): JSX.Element => {
|
||||
const databases = useDatabases((state) => state.databases);
|
||||
const {
|
||||
@ -118,7 +142,8 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
||||
|
||||
const buildNotebooksTree = (): TreeNode => {
|
||||
const notebooksTree: TreeNode = {
|
||||
label: undefined,
|
||||
id: "notebooks",
|
||||
label: "NOTEBOOKS",
|
||||
isExpanded: true,
|
||||
children: [],
|
||||
};
|
||||
@ -502,7 +527,8 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
||||
});
|
||||
|
||||
return {
|
||||
label: undefined,
|
||||
id: "data",
|
||||
label: "DATA",
|
||||
isExpanded: true,
|
||||
children: databaseTreeNodes,
|
||||
};
|
||||
@ -768,56 +794,30 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
||||
const isSampleDataEnabled = userContext.sampleDataConnectionInfo && userContext.apiType === "SQL";
|
||||
const sampleDataResourceTokenCollection = useDatabases((state) => state.sampleDataResourceTokenCollection);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isNotebookEnabled && !isSampleDataEnabled && (
|
||||
<TreeComponent className="dataResourceTree" rootNode={dataRootNode} />
|
||||
)}
|
||||
{isNotebookEnabled && !isSampleDataEnabled && (
|
||||
<>
|
||||
<AccordionComponent>
|
||||
<AccordionItemComponent title={"DATA"} isExpanded={!gitHubNotebooksContentRoot}>
|
||||
<TreeComponent className="dataResourceTree" rootNode={dataRootNode} />
|
||||
</AccordionItemComponent>
|
||||
<AccordionItemComponent title={"NOTEBOOKS"}>
|
||||
<TreeComponent className="notebookResourceTree" rootNode={buildNotebooksTree()} />
|
||||
</AccordionItemComponent>
|
||||
</AccordionComponent>
|
||||
const treeNodes = React.useMemo(() => {
|
||||
if (!isNotebookEnabled && !isSampleDataEnabled) {
|
||||
return dataRootNode.children;
|
||||
}
|
||||
|
||||
{buildGalleryCallout()}
|
||||
</>
|
||||
)}
|
||||
{!isNotebookEnabled && isSampleDataEnabled && (
|
||||
<>
|
||||
<AccordionComponent>
|
||||
<AccordionItemComponent title={"MY DATA"} isExpanded={!gitHubNotebooksContentRoot}>
|
||||
<TreeComponent className="dataResourceTree" rootNode={dataRootNode} />
|
||||
</AccordionItemComponent>
|
||||
<AccordionItemComponent title={"SAMPLE DATA"} containerStyles={{ display: "table" }}>
|
||||
<SampleDataTree sampleDataResourceTokenCollection={sampleDataResourceTokenCollection} />
|
||||
</AccordionItemComponent>
|
||||
</AccordionComponent>
|
||||
const nodes: TreeNode[] = [dataRootNode];
|
||||
if (isSampleDataEnabled) {
|
||||
nodes.push(buildSampleDataTree(sampleDataResourceTokenCollection));
|
||||
}
|
||||
|
||||
{buildGalleryCallout()}
|
||||
</>
|
||||
)}
|
||||
{isNotebookEnabled && isSampleDataEnabled && (
|
||||
<>
|
||||
<AccordionComponent>
|
||||
<AccordionItemComponent title={"MY DATA"} isExpanded={!gitHubNotebooksContentRoot}>
|
||||
<TreeComponent className="dataResourceTree" rootNode={dataRootNode} />
|
||||
</AccordionItemComponent>
|
||||
<AccordionItemComponent title={"SAMPLE DATA"} containerStyles={{ display: "table" }}>
|
||||
<SampleDataTree sampleDataResourceTokenCollection={sampleDataResourceTokenCollection} />
|
||||
</AccordionItemComponent>
|
||||
<AccordionItemComponent title={"NOTEBOOKS"}>
|
||||
<TreeComponent className="notebookResourceTree" rootNode={buildNotebooksTree()} />
|
||||
</AccordionItemComponent>
|
||||
</AccordionComponent>
|
||||
if (isNotebookEnabled) {
|
||||
nodes.push(buildNotebooksTree());
|
||||
}
|
||||
|
||||
{buildGalleryCallout()}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return nodes;
|
||||
}, [isNotebookEnabled, isSampleDataEnabled]);
|
||||
|
||||
return (<>
|
||||
<FluentProvider theme={lightTheme}>
|
||||
<Tree openItems={treeNodes.map(node => node.label)}>
|
||||
{treeNodes.map(node => <TreeNodeComponent key={node.id} className="dataResourceTree" node={node} />)}
|
||||
</Tree>
|
||||
</FluentProvider>
|
||||
{(isNotebookEnabled || isSampleDataEnabled) && buildGalleryCallout()}
|
||||
</>);
|
||||
};
|
||||
|
||||
|
83
src/Explorer/Tree/SampleDataTree.ts
Normal file
83
src/Explorer/Tree/SampleDataTree.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import CosmosDBIcon from "../../../images/Azure-Cosmos-DB.svg";
|
||||
import CollectionIcon from "../../../images/tree-collection.svg";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import { TreeNode } from "../Controls/TreeComponent/TreeComponent";
|
||||
|
||||
export const buildSampleDataTree = (sampleDataResourceTokenCollection: ViewModels.CollectionBase): TreeNode => {
|
||||
const updatedSampleTree: TreeNode = {
|
||||
label: sampleDataResourceTokenCollection.databaseId,
|
||||
isExpanded: false,
|
||||
iconSrc: CosmosDBIcon,
|
||||
className: "databaseHeader",
|
||||
children: [
|
||||
{
|
||||
label: sampleDataResourceTokenCollection.id(),
|
||||
iconSrc: CollectionIcon,
|
||||
isExpanded: false,
|
||||
className: "collectionHeader",
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||
onClick: () => {
|
||||
useSelectedNode.getState().setSelectedNode(sampleDataResourceTokenCollection);
|
||||
useCommandBar.getState().setContextButtons([]);
|
||||
useTabs
|
||||
.getState()
|
||||
.refreshActiveTab(
|
||||
(tab: TabsBase) =>
|
||||
tab.collection?.id() === sampleDataResourceTokenCollection.id() &&
|
||||
tab.collection.databaseId === sampleDataResourceTokenCollection.databaseId
|
||||
);
|
||||
},
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(sampleDataResourceTokenCollection.databaseId, sampleDataResourceTokenCollection.id()),
|
||||
onContextMenuOpen: () => useSelectedNode.getState().setSelectedNode(sampleDataResourceTokenCollection),
|
||||
children: [
|
||||
{
|
||||
label: "Items",
|
||||
onClick: () => sampleDataResourceTokenCollection.onDocumentDBDocumentsClick(),
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(
|
||||
sampleDataResourceTokenCollection.databaseId,
|
||||
sampleDataResourceTokenCollection.id(),
|
||||
[ViewModels.CollectionTabKind.Documents]
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// TODO handle case non-initialized
|
||||
return updatedSampleTree;
|
||||
|
||||
// export const SampleDataTree = ({
|
||||
// sampleDataResourceTokenCollection,
|
||||
// }: {
|
||||
// sampleDataResourceTokenCollection: ViewModels.CollectionBase;
|
||||
// }): JSX.Element => {
|
||||
|
||||
|
||||
// return {
|
||||
// id: "sampleData",
|
||||
// label: "SAMPLE DATA",
|
||||
// isExpanded: true,
|
||||
// children: [updatedSampleTree],
|
||||
// };
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <TreeNodeComponent
|
||||
// className="dataResourceTree"
|
||||
// node={sampleDataResourceTokenCollection ? buildSampleDataTree() : { label: "Sample data not initialized." }}
|
||||
// />
|
||||
// );
|
||||
};
|
@ -1,78 +0,0 @@
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React from "react";
|
||||
import CosmosDBIcon from "../../../images/Azure-Cosmos-DB.svg";
|
||||
import CollectionIcon from "../../../images/tree-collection.svg";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import { TreeComponent, TreeNode } from "../Controls/TreeComponent/TreeComponent";
|
||||
|
||||
export const SampleDataTree = ({
|
||||
sampleDataResourceTokenCollection,
|
||||
}: {
|
||||
sampleDataResourceTokenCollection: ViewModels.CollectionBase;
|
||||
}): JSX.Element => {
|
||||
const buildSampleDataTree = (): TreeNode => {
|
||||
const updatedSampleTree: TreeNode = {
|
||||
label: sampleDataResourceTokenCollection.databaseId,
|
||||
isExpanded: false,
|
||||
iconSrc: CosmosDBIcon,
|
||||
className: "databaseHeader",
|
||||
children: [
|
||||
{
|
||||
label: sampleDataResourceTokenCollection.id(),
|
||||
iconSrc: CollectionIcon,
|
||||
isExpanded: false,
|
||||
className: "collectionHeader",
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||
onClick: () => {
|
||||
useSelectedNode.getState().setSelectedNode(sampleDataResourceTokenCollection);
|
||||
useCommandBar.getState().setContextButtons([]);
|
||||
useTabs
|
||||
.getState()
|
||||
.refreshActiveTab(
|
||||
(tab: TabsBase) =>
|
||||
tab.collection?.id() === sampleDataResourceTokenCollection.id() &&
|
||||
tab.collection.databaseId === sampleDataResourceTokenCollection.databaseId
|
||||
);
|
||||
},
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(sampleDataResourceTokenCollection.databaseId, sampleDataResourceTokenCollection.id()),
|
||||
onContextMenuOpen: () => useSelectedNode.getState().setSelectedNode(sampleDataResourceTokenCollection),
|
||||
children: [
|
||||
{
|
||||
label: "Items",
|
||||
onClick: () => sampleDataResourceTokenCollection.onDocumentDBDocumentsClick(),
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(
|
||||
sampleDataResourceTokenCollection.databaseId,
|
||||
sampleDataResourceTokenCollection.id(),
|
||||
[ViewModels.CollectionTabKind.Documents]
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return {
|
||||
label: undefined,
|
||||
isExpanded: true,
|
||||
children: [updatedSampleTree],
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<TreeComponent
|
||||
className="dataResourceTree"
|
||||
rootNode={sampleDataResourceTokenCollection ? buildSampleDataTree() : { label: "Sample data not initialized." }}
|
||||
/>
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user