Migrate Collapse/Open Resource Tree to React (#733)

Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
Sunil Kumar Yadav 2021-05-13 06:33:52 +05:30 committed by GitHub
parent 8e6d274b11
commit d7c62ac7f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 120 additions and 124 deletions

View File

@ -2099,7 +2099,7 @@ a:link {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 auto;
overflow-x: auto; overflow-x: auto;
overflow-y: auto; overflow-y: hidden;
height: 100%; height: 100%;
} }
@ -3085,3 +3085,7 @@ settings-pane {
padding-left: @SmallSpace; padding-left: @SmallSpace;
} }
} }
.hiddenMain {
visibility: hidden;
height: 0px;
}

View File

@ -3,6 +3,7 @@
.resourceTree { .resourceTree {
height: 100%; height: 100%;
width: 20%;
flex: 0 0 auto; flex: 0 0 auto;
.main { .main {
height: 100%; height: 100%;

View File

@ -0,0 +1,35 @@
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
export interface CollapsedResourceTreeProps {
toggleLeftPaneExpanded: () => void;
isLeftPaneExpanded: boolean;
}
export const CollapsedResourceTree: FunctionComponent<CollapsedResourceTreeProps> = ({
toggleLeftPaneExpanded,
isLeftPaneExpanded,
}: CollapsedResourceTreeProps): JSX.Element => {
return (
<div id="mini" className={!isLeftPaneExpanded ? "mini toggle-mini" : "hiddenMain"}>
<div className="main-nav nav">
<ul className="nav">
<li
className="resourceTreeCollapse"
id="collapseToggleLeftPaneButton"
role="button"
tabIndex={0}
aria-label="Expand Tree"
>
<span className="leftarrowCollapsed" onClick={toggleLeftPaneExpanded}>
<img className="arrowCollapsed" src={arrowLeftImg} alt="Expand" />
</span>
<span className="collectionCollapsed" onClick={toggleLeftPaneExpanded}>
<span data-bind="text: collectionTitle" />
</span>
</li>
</ul>
</div>
</div>
);
};

View File

@ -0,0 +1,59 @@
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
import refreshImg from "../../images/refresh-cosmos.svg";
import { AuthType } from "../AuthType";
import { userContext } from "../UserContext";
export interface ResourceTreeProps {
toggleLeftPaneExpanded: () => void;
isLeftPaneExpanded: boolean;
}
export const ResourceTree: FunctionComponent<ResourceTreeProps> = ({
toggleLeftPaneExpanded,
isLeftPaneExpanded,
}: ResourceTreeProps): JSX.Element => {
return (
<div id="main" className={isLeftPaneExpanded ? "main" : "hiddenMain"}>
{/* Collections Window - - Start */}
<div id="mainslide" className="flexContainer">
{/* Collections Window Title/Command Bar - Start */}
<div className="collectiontitle">
<div className="coltitle">
<span className="titlepadcol" data-bind="text: collectionTitle" />
<div className="float-right">
<span
className="padimgcolrefresh"
data-test="refreshTree"
role="button"
data-bind="click: onRefreshResourcesClick, clickBubble: false, event: { keypress: onRefreshDatabasesKeyPress }"
tabIndex={0}
aria-label="Refresh tree"
title="Refresh tree"
>
<img className="refreshcol" src={refreshImg} alt="Refresh tree" />
</span>
<span
className="padimgcolrefresh1"
id="expandToggleLeftPaneButton"
role="button"
onClick={toggleLeftPaneExpanded}
tabIndex={0}
aria-label="Collapse Tree"
title="Collapse Tree"
>
<img className="refreshcol1" src={arrowLeftImg} alt="Hide" />
</span>
</div>
</div>
</div>
{userContext.authType === AuthType.ResourceToken ? (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTreeForResourceToken" />
) : (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTree" />
)}
</div>
{/* Collections Window - End */}
</div>
);
};

View File

@ -1051,7 +1051,6 @@ exports[`SettingsComponent renders 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -1118,7 +1117,6 @@ exports[`SettingsComponent renders 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
}, },
"databaseId": "test", "databaseId": "test",
"defaultTtl": [Function], "defaultTtl": [Function],
@ -2163,7 +2161,6 @@ exports[`SettingsComponent renders 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -2230,7 +2227,6 @@ exports[`SettingsComponent renders 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
} }
} }
isAutoPilotSelected={false} isAutoPilotSelected={false}
@ -3288,7 +3284,6 @@ exports[`SettingsComponent renders 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -3355,7 +3350,6 @@ exports[`SettingsComponent renders 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
}, },
"databaseId": "test", "databaseId": "test",
"defaultTtl": [Function], "defaultTtl": [Function],
@ -4400,7 +4394,6 @@ exports[`SettingsComponent renders 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -4467,7 +4460,6 @@ exports[`SettingsComponent renders 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
} }
} }
geospatialConfigType="Geometry" geospatialConfigType="Geometry"

View File

@ -134,7 +134,6 @@ export default class Explorer {
public databases: ko.ObservableArray<ViewModels.Database>; public databases: ko.ObservableArray<ViewModels.Database>;
public selectedDatabaseId: ko.Computed<string>; public selectedDatabaseId: ko.Computed<string>;
public selectedCollectionId: ko.Computed<string>; public selectedCollectionId: ko.Computed<string>;
public isLeftPaneExpanded: ko.Observable<boolean>;
public selectedNode: ko.Observable<ViewModels.TreeNode>; public selectedNode: ko.Observable<ViewModels.TreeNode>;
private resourceTree: ResourceTreeAdapter; private resourceTree: ResourceTreeAdapter;
@ -231,6 +230,7 @@ export default class Explorer {
}); });
} }
}); });
this.isNotebooksEnabledForAccount = ko.observable(false); this.isNotebooksEnabledForAccount = ko.observable(false);
this.isNotebooksEnabledForAccount.subscribe((isEnabledForAccount: boolean) => this.refreshCommandBarButtons()); this.isNotebooksEnabledForAccount.subscribe((isEnabledForAccount: boolean) => this.refreshCommandBarButtons());
this.isSparkEnabledForAccount = ko.observable(false); this.isSparkEnabledForAccount = ko.observable(false);
@ -335,7 +335,6 @@ export default class Explorer {
} }
return true; return true;
}); });
this.isLeftPaneExpanded = ko.observable<boolean>(true);
this.selectedNode = ko.observable<ViewModels.TreeNode>(); this.selectedNode = ko.observable<ViewModels.TreeNode>();
this.selectedNode.subscribe((nodeSelected: ViewModels.TreeNode) => { this.selectedNode.subscribe((nodeSelected: ViewModels.TreeNode) => {
// Make sure switching tabs restores tabs display // Make sure switching tabs restores tabs display
@ -675,16 +674,8 @@ export default class Explorer {
this.setIsNotificationConsoleExpanded(true); this.setIsNotificationConsoleExpanded(true);
} }
public toggleLeftPaneExpanded() { public collapseConsole(): void {
this.isLeftPaneExpanded(!this.isLeftPaneExpanded()); this.setIsNotificationConsoleExpanded(false);
if (this.isLeftPaneExpanded()) {
document.getElementById("expandToggleLeftPaneButton").focus();
this.splitter.expandLeft();
} else {
document.getElementById("collapseToggleLeftPaneButton").focus();
this.splitter.collapseLeft();
}
} }
public refreshDatabaseForResourceToken(): Q.Promise<any> { public refreshDatabaseForResourceToken(): Q.Promise<any> {
@ -803,14 +794,6 @@ export default class Explorer {
this.refreshNotebookList(); this.refreshNotebookList();
}; };
public toggleLeftPaneExpandedKeyPress = (source: any, event: KeyboardEvent): boolean => {
if (event.keyCode === Constants.KeyCodes.Space || event.keyCode === Constants.KeyCodes.Enter) {
this.toggleLeftPaneExpanded();
return false;
}
return true;
};
// Facade // Facade
public provideFeedbackEmail = () => { public provideFeedbackEmail = () => {
window.open(Constants.Urls.feedbackEmail, "_blank"); window.open(Constants.Urls.feedbackEmail, "_blank");

View File

@ -1040,7 +1040,6 @@ exports[`GitHub Repos Panel should render Default properly 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -1107,7 +1106,6 @@ exports[`GitHub Repos Panel should render Default properly 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
}, },
"getRepo": [Function], "getRepo": [Function],
"pinRepo": [Function], "pinRepo": [Function],

View File

@ -1030,7 +1030,6 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"isAutoscaleDefaultEnabled": [Function], "isAutoscaleDefaultEnabled": [Function],
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -1097,7 +1096,6 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
} }
} }
inProgressMessage="Creating directory " inProgressMessage="Creating directory "

View File

@ -1030,7 +1030,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"isHostedDataExplorerEnabled": [Function], "isHostedDataExplorerEnabled": [Function],
"isLastCollection": [Function], "isLastCollection": [Function],
"isLastNonEmptyDatabase": [Function], "isLastNonEmptyDatabase": [Function],
"isLeftPaneExpanded": [Function],
"isMongoIndexingEnabled": [Function], "isMongoIndexingEnabled": [Function],
"isNotebookEnabled": [Function], "isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function], "isNotebooksEnabledForAccount": [Function],
@ -1099,7 +1098,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"activeTab": [Function], "activeTab": [Function],
"openedTabs": [Function], "openedTabs": [Function],
}, },
"toggleLeftPaneExpandedKeyPress": [Function],
} }
} }
openNotificationConsole={[Function]} openNotificationConsole={[Function]}

View File

@ -14,8 +14,6 @@ import "../externals/jquery.typeahead.min.js";
import "../images/CosmosDB_rgb_ui_lighttheme.ico"; import "../images/CosmosDB_rgb_ui_lighttheme.ico";
import "../images/favicon.ico"; import "../images/favicon.ico";
import hdeConnectImage from "../images/HdeConnectCosmosDB.svg"; import hdeConnectImage from "../images/HdeConnectCosmosDB.svg";
import arrowLeftImg from "../images/imgarrowlefticon.svg";
import refreshImg from "../images/refresh-cosmos.svg";
import "../less/documentDB.less"; import "../less/documentDB.less";
import "../less/forms.less"; import "../less/forms.less";
import "../less/infobox.less"; import "../less/infobox.less";
@ -27,7 +25,8 @@ import "../less/TableStyles/EntityEditor.less";
import "../less/TableStyles/fulldatatables.less"; import "../less/TableStyles/fulldatatables.less";
import "../less/TableStyles/queryBuilder.less"; import "../less/TableStyles/queryBuilder.less";
import "../less/tree.less"; import "../less/tree.less";
import { AuthType } from "./AuthType"; import { CollapsedResourceTree } from "./Common/CollapsedResourceTree";
import { ResourceTree } from "./Common/ResourceTree";
import "./Explorer/Controls/Accordion/AccordionComponent.less"; import "./Explorer/Controls/Accordion/AccordionComponent.less";
import "./Explorer/Controls/CollapsiblePanel/CollapsiblePanelComponent.less"; import "./Explorer/Controls/CollapsiblePanel/CollapsiblePanelComponent.less";
import { Dialog, DialogProps } from "./Explorer/Controls/Dialog"; import { Dialog, DialogProps } from "./Explorer/Controls/Dialog";
@ -54,7 +53,6 @@ import { useSidePanel } from "./hooks/useSidePanel";
import { useTabs } from "./hooks/useTabs"; import { useTabs } from "./hooks/useTabs";
import "./Libs/jquery"; import "./Libs/jquery";
import "./Shared/appInsights"; import "./Shared/appInsights";
import { userContext } from "./UserContext";
initializeIcons(); initializeIcons();
@ -63,6 +61,7 @@ const App: React.FunctionComponent = () => {
const [notificationConsoleData, setNotificationConsoleData] = useState(undefined); const [notificationConsoleData, setNotificationConsoleData] = useState(undefined);
//TODO: Refactor so we don't need to pass the id to remove a console data //TODO: Refactor so we don't need to pass the id to remove a console data
const [inProgressConsoleDataIdToBeDeleted, setInProgressConsoleDataIdToBeDeleted] = useState(""); const [inProgressConsoleDataIdToBeDeleted, setInProgressConsoleDataIdToBeDeleted] = useState("");
const [isLeftPaneExpanded, setIsLeftPaneExpanded] = useState<boolean>(true);
const [dialogProps, setDialogProps] = useState<DialogProps>(); const [dialogProps, setDialogProps] = useState<DialogProps>();
const [showDialog, setShowDialog] = useState<boolean>(false); const [showDialog, setShowDialog] = useState<boolean>(false);
@ -92,6 +91,15 @@ const App: React.FunctionComponent = () => {
const config = useConfig(); const config = useConfig();
const explorer = useKnockoutExplorer(config?.platform, explorerParams); const explorer = useKnockoutExplorer(config?.platform, explorerParams);
const toggleLeftPaneExpanded = () => {
setIsLeftPaneExpanded(!isLeftPaneExpanded);
if (isLeftPaneExpanded) {
document.getElementById("expandToggleLeftPaneButton").focus();
} else {
document.getElementById("collapseToggleLeftPaneButton").focus();
}
};
if (!explorer) { if (!explorer) {
return <LoadingExplorer />; return <LoadingExplorer />;
} }
@ -107,93 +115,13 @@ const App: React.FunctionComponent = () => {
<div id="resourcetree" data-test="resourceTreeId" className="resourceTree"> <div id="resourcetree" data-test="resourceTreeId" className="resourceTree">
<div className="collectionsTreeWithSplitter"> <div className="collectionsTreeWithSplitter">
{/* Collections Tree Expanded - Start */} {/* Collections Tree Expanded - Start */}
<div <ResourceTree toggleLeftPaneExpanded={toggleLeftPaneExpanded} isLeftPaneExpanded={isLeftPaneExpanded} />
id="main"
className="main"
data-bind="
visible: isLeftPaneExpanded()"
>
{/* Collections Window - - Start */}
<div id="mainslide" className="flexContainer">
{/* Collections Window Title/Command Bar - Start */}
<div className="collectiontitle">
<div className="coltitle">
<span className="titlepadcol" data-bind="text: collectionTitle" />
<div className="float-right">
<span
className="padimgcolrefresh"
data-test="refreshTree"
role="button"
data-bind="
click: onRefreshResourcesClick, clickBubble: false, event: { keypress: onRefreshDatabasesKeyPress }"
tabIndex={0}
aria-label="Refresh tree"
title="Refresh tree"
>
<img className="refreshcol" src={refreshImg} data-bind="attr: { alt: refreshTreeTitle }" />
</span>
<span
className="padimgcolrefresh1"
id="expandToggleLeftPaneButton"
role="button"
data-bind="
click: toggleLeftPaneExpanded, event: { keypress: toggleLeftPaneExpandedKeyPress }"
tabIndex={0}
aria-label="Collapse Tree"
title="Collapse Tree"
>
<img className="refreshcol1" src={arrowLeftImg} alt="Hide" />
</span>
</div>
</div>
</div>
{userContext.authType === AuthType.ResourceToken ? (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTreeForResourceToken" />
) : (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTree" />
)}
</div>
{/* Collections Window - End */}
</div>
{/* Collections Tree Expanded - End */} {/* Collections Tree Expanded - End */}
{/* Collections Tree Collapsed - Start */} {/* Collections Tree Collapsed - Start */}
<div <CollapsedResourceTree
id="mini" toggleLeftPaneExpanded={toggleLeftPaneExpanded}
className="mini toggle-mini" isLeftPaneExpanded={isLeftPaneExpanded}
data-bind="visible: !isLeftPaneExpanded()
attr: { style: { width: collapsedResourceTreeWidth }}"
>
<div className="main-nav nav">
<ul className="nav">
<li
className="resourceTreeCollapse"
id="collapseToggleLeftPaneButton"
role="button"
data-bind="event: { keypress: toggleLeftPaneExpandedKeyPress }"
tabIndex={0}
aria-label="Expand Tree"
>
<span
className="leftarrowCollapsed"
data-bind="
click: toggleLeftPaneExpanded"
>
<img className="arrowCollapsed" src={arrowLeftImg} alt="Expand" />
</span>
<span
className="collectionCollapsed"
data-bind="
click: toggleLeftPaneExpanded"
>
<span
data-bind="
text: collectionTitle"
/> />
</span>
</li>
</ul>
</div>
</div>
{/* Collections Tree Collapsed - End */} {/* Collections Tree Collapsed - End */}
</div> </div>
{/* Splitter - Start */} {/* Splitter - Start */}