mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 17:30:46 +00:00
remove knockout component
This commit is contained in:
@@ -117,8 +117,6 @@ src/Explorer/OpenActions.ts
|
|||||||
src/Explorer/OpenActionsStubs.ts
|
src/Explorer/OpenActionsStubs.ts
|
||||||
src/Explorer/Panes/AddCollectionPane.test.ts
|
src/Explorer/Panes/AddCollectionPane.test.ts
|
||||||
src/Explorer/Panes/AddCollectionPane.ts
|
src/Explorer/Panes/AddCollectionPane.ts
|
||||||
src/Explorer/Panes/AddDatabasePane.test.ts
|
|
||||||
src/Explorer/Panes/AddDatabasePane.ts
|
|
||||||
src/Explorer/Panes/BrowseQueriesPane.ts
|
src/Explorer/Panes/BrowseQueriesPane.ts
|
||||||
src/Explorer/Panes/CassandraAddCollectionPane.ts
|
src/Explorer/Panes/CassandraAddCollectionPane.ts
|
||||||
src/Explorer/Panes/ContextualPaneBase.ts
|
src/Explorer/Panes/ContextualPaneBase.ts
|
||||||
|
|||||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -55,7 +55,7 @@
|
|||||||
"clean-webpack-plugin": "0.1.19",
|
"clean-webpack-plugin": "0.1.19",
|
||||||
"clipboard-copy": "4.0.1",
|
"clipboard-copy": "4.0.1",
|
||||||
"copy-webpack-plugin": "6.0.2",
|
"copy-webpack-plugin": "6.0.2",
|
||||||
"core-js": "3.5.0",
|
"core-js": "3.9.1",
|
||||||
"crossroads": "0.12.2",
|
"crossroads": "0.12.2",
|
||||||
"css-element-queries": "1.1.1",
|
"css-element-queries": "1.1.1",
|
||||||
"d3": "6.1.1",
|
"d3": "6.1.1",
|
||||||
@@ -8384,9 +8384,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/core-js": {
|
"node_modules/core-js": {
|
||||||
"version": "3.5.0",
|
"version": "3.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz",
|
||||||
"integrity": "sha512-Ifh3kj78gzQ7NAoJXeTu+XwzDld0QRIwjBLRqAMhuLhP3d2Av5wmgE9ycfnvK6NAEjTkQ1sDPeoEZAWO3Hx1Uw==",
|
"integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -30916,9 +30916,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "3.5.0",
|
"version": "3.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz",
|
||||||
"integrity": "sha512-Ifh3kj78gzQ7NAoJXeTu+XwzDld0QRIwjBLRqAMhuLhP3d2Av5wmgE9ycfnvK6NAEjTkQ1sDPeoEZAWO3Hx1Uw=="
|
"integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg=="
|
||||||
},
|
},
|
||||||
"core-js-compat": {
|
"core-js-compat": {
|
||||||
"version": "3.9.1",
|
"version": "3.9.1",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
"clean-webpack-plugin": "0.1.19",
|
"clean-webpack-plugin": "0.1.19",
|
||||||
"clipboard-copy": "4.0.1",
|
"clipboard-copy": "4.0.1",
|
||||||
"copy-webpack-plugin": "6.0.2",
|
"copy-webpack-plugin": "6.0.2",
|
||||||
"core-js": "3.5.0",
|
"core-js": "3.9.1",
|
||||||
"crossroads": "0.12.2",
|
"crossroads": "0.12.2",
|
||||||
"css-element-queries": "1.1.1",
|
"css-element-queries": "1.1.1",
|
||||||
"d3": "6.1.1",
|
"d3": "6.1.1",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useId } from "@uifabric/react-hooks";
|
import { useId } from "@uifabric/react-hooks";
|
||||||
import { Icon } from "office-ui-fabric-react";
|
import { IButtonStyles, IconButton } from "office-ui-fabric-react";
|
||||||
import { ITooltipHostStyles, TooltipHost } from "office-ui-fabric-react/lib/Tooltip";
|
import { ITooltipHostStyles, TooltipHost } from "office-ui-fabric-react/lib/Tooltip";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
@@ -9,13 +9,18 @@ const hostStyles: Partial<ITooltipHostStyles> = { root: { display: "inline-block
|
|||||||
export interface TooltipProps {
|
export interface TooltipProps {
|
||||||
children: string;
|
children: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const iconButtonStyles: Partial<IButtonStyles> = { root: { marginBottom: -3 } };
|
||||||
|
const iconProps = { iconName: "Info" };
|
||||||
|
|
||||||
export const Tooltip: React.FunctionComponent = ({ children }: TooltipProps) => {
|
export const Tooltip: React.FunctionComponent = ({ children }: TooltipProps) => {
|
||||||
const tooltipId = useId("tooltip");
|
const tooltipId = useId("tooltip");
|
||||||
|
|
||||||
|
const iconButtonId: string = useId("iconButton");
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<TooltipHost content={children} id={tooltipId} calloutProps={calloutProps} styles={hostStyles}>
|
<TooltipHost content={children} id={tooltipId} calloutProps={calloutProps} styles={hostStyles}>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<IconButton id={iconButtonId} iconProps={iconProps} ariaLabel="Info" styles={iconButtonStyles} />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@@ -1,31 +1,31 @@
|
|||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
import * as PaneComponents from "./Panes/PaneComponents";
|
|
||||||
import { DiffEditorComponent } from "./Controls/DiffEditor/DiffEditorComponent";
|
import { DiffEditorComponent } from "./Controls/DiffEditor/DiffEditorComponent";
|
||||||
import { DynamicListComponent } from "./Controls/DynamicList/DynamicListComponent";
|
import { DynamicListComponent } from "./Controls/DynamicList/DynamicListComponent";
|
||||||
import { EditorComponent } from "./Controls/Editor/EditorComponent";
|
import { EditorComponent } from "./Controls/Editor/EditorComponent";
|
||||||
import { ErrorDisplayComponent } from "./Controls/ErrorDisplayComponent/ErrorDisplayComponent";
|
import { ErrorDisplayComponent } from "./Controls/ErrorDisplayComponent/ErrorDisplayComponent";
|
||||||
import { GraphStyleComponent } from "./Graph/GraphStyleComponent/GraphStyleComponent";
|
|
||||||
import { InputTypeaheadComponent } from "./Controls/InputTypeahead/InputTypeahead";
|
import { InputTypeaheadComponent } from "./Controls/InputTypeahead/InputTypeahead";
|
||||||
import { JsonEditorComponent } from "./Controls/JsonEditor/JsonEditorComponent";
|
import { JsonEditorComponent } from "./Controls/JsonEditor/JsonEditorComponent";
|
||||||
import { NewVertexComponent } from "./Graph/NewVertexComponent/NewVertexComponent";
|
|
||||||
import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3";
|
import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3";
|
||||||
|
import { GraphStyleComponent } from "./Graph/GraphStyleComponent/GraphStyleComponent";
|
||||||
|
import { NewVertexComponent } from "./Graph/NewVertexComponent/NewVertexComponent";
|
||||||
|
import * as PaneComponents from "./Panes/PaneComponents";
|
||||||
|
import ConflictsTab from "./Tabs/ConflictsTab";
|
||||||
|
import DatabaseSettingsTab from "./Tabs/DatabaseSettingsTab";
|
||||||
import DocumentsTab from "./Tabs/DocumentsTab";
|
import DocumentsTab from "./Tabs/DocumentsTab";
|
||||||
import StoredProcedureTab from "./Tabs/StoredProcedureTab";
|
import GalleryTab from "./Tabs/GalleryTab";
|
||||||
import TriggerTab from "./Tabs/TriggerTab";
|
|
||||||
import UserDefinedFunctionTab from "./Tabs/UserDefinedFunctionTab";
|
|
||||||
import { DatabaseSettingsTabV2, SettingsTabV2 } from "./Tabs/SettingsTabV2";
|
|
||||||
import QueryTab from "./Tabs/QueryTab";
|
|
||||||
import QueryTablesTab from "./Tabs/QueryTablesTab";
|
|
||||||
import GraphTab from "./Tabs/GraphTab";
|
import GraphTab from "./Tabs/GraphTab";
|
||||||
import MongoShellTab from "./Tabs/MongoShellTab";
|
import MongoShellTab from "./Tabs/MongoShellTab";
|
||||||
import ConflictsTab from "./Tabs/ConflictsTab";
|
|
||||||
import NotebookTabV2 from "./Tabs/NotebookV2Tab";
|
import NotebookTabV2 from "./Tabs/NotebookV2Tab";
|
||||||
import TerminalTab from "./Tabs/TerminalTab";
|
|
||||||
import GalleryTab from "./Tabs/GalleryTab";
|
|
||||||
import NotebookViewerTab from "./Tabs/NotebookViewerTab";
|
import NotebookViewerTab from "./Tabs/NotebookViewerTab";
|
||||||
import DatabaseSettingsTab from "./Tabs/DatabaseSettingsTab";
|
import QueryTab from "./Tabs/QueryTab";
|
||||||
|
import QueryTablesTab from "./Tabs/QueryTablesTab";
|
||||||
|
import { DatabaseSettingsTabV2, SettingsTabV2 } from "./Tabs/SettingsTabV2";
|
||||||
|
import StoredProcedureTab from "./Tabs/StoredProcedureTab";
|
||||||
import TabsManagerTemplate from "./Tabs/TabsManager.html";
|
import TabsManagerTemplate from "./Tabs/TabsManager.html";
|
||||||
|
import TerminalTab from "./Tabs/TerminalTab";
|
||||||
|
import TriggerTab from "./Tabs/TriggerTab";
|
||||||
|
import UserDefinedFunctionTab from "./Tabs/UserDefinedFunctionTab";
|
||||||
|
|
||||||
|
|
||||||
ko.components.register("input-typeahead", new InputTypeaheadComponent());
|
ko.components.register("input-typeahead", new InputTypeaheadComponent());
|
||||||
ko.components.register("new-vertex-form", NewVertexComponent);
|
ko.components.register("new-vertex-form", NewVertexComponent);
|
||||||
@@ -59,7 +59,6 @@ ko.components.register("tabs-manager", { template: TabsManagerTemplate });
|
|||||||
].forEach(({ component: { name, template } }) => ko.components.register(name, { template }));
|
].forEach(({ component: { name, template } }) => ko.components.register(name, { template }));
|
||||||
|
|
||||||
// Panes
|
// Panes
|
||||||
ko.components.register("add-database-pane", new PaneComponents.AddDatabasePaneComponent());
|
|
||||||
ko.components.register("add-collection-pane", new PaneComponents.AddCollectionPaneComponent());
|
ko.components.register("add-collection-pane", new PaneComponents.AddCollectionPaneComponent());
|
||||||
ko.components.register(
|
ko.components.register(
|
||||||
"delete-collection-confirmation-pane",
|
"delete-collection-confirmation-pane",
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ import { NotebookContentItem, NotebookContentItemType } from "./Notebook/Noteboo
|
|||||||
import { NotebookUtil } from "./Notebook/NotebookUtil";
|
import { NotebookUtil } from "./Notebook/NotebookUtil";
|
||||||
import AddCollectionPane from "./Panes/AddCollectionPane";
|
import AddCollectionPane from "./Panes/AddCollectionPane";
|
||||||
import { AddCollectionPanel } from "./Panes/AddCollectionPanel";
|
import { AddCollectionPanel } from "./Panes/AddCollectionPanel";
|
||||||
import AddDatabasePane from "./Panes/AddDatabasePane";
|
import { AddDatabasePane } from "./Panes/AddDatabasePane";
|
||||||
import { AddDatabasePaneF } from "./Panes/AddDatabasePaneF";
|
|
||||||
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
||||||
import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
|
import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
|
||||||
import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
||||||
@@ -203,7 +202,6 @@ export default class Explorer {
|
|||||||
public tabsManager: TabsManager;
|
public tabsManager: TabsManager;
|
||||||
|
|
||||||
// Contextual panes
|
// Contextual panes
|
||||||
public addDatabasePane: AddDatabasePane;
|
|
||||||
public addCollectionPane: AddCollectionPane;
|
public addCollectionPane: AddCollectionPane;
|
||||||
public deleteCollectionConfirmationPane: DeleteCollectionConfirmationPane;
|
public deleteCollectionConfirmationPane: DeleteCollectionConfirmationPane;
|
||||||
public deleteDatabaseConfirmationPane: DeleteDatabaseConfirmationPane;
|
public deleteDatabaseConfirmationPane: DeleteDatabaseConfirmationPane;
|
||||||
@@ -565,13 +563,6 @@ export default class Explorer {
|
|||||||
return this.databases().filter((database: ViewModels.Database) => !this._isSystemDatabasePredicate(database));
|
return this.databases().filter((database: ViewModels.Database) => !this._isSystemDatabasePredicate(database));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addDatabasePane = new AddDatabasePane({
|
|
||||||
id: "adddatabasepane",
|
|
||||||
visible: ko.observable<boolean>(false),
|
|
||||||
|
|
||||||
container: this,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addCollectionPane = new AddCollectionPane({
|
this.addCollectionPane = new AddCollectionPane({
|
||||||
isPreferredApiTable: ko.computed(() => this.isPreferredApiTable()),
|
isPreferredApiTable: ko.computed(() => this.isPreferredApiTable()),
|
||||||
id: "addcollectionpane",
|
id: "addcollectionpane",
|
||||||
@@ -711,7 +702,6 @@ export default class Explorer {
|
|||||||
this.tabsManager = new TabsManager();
|
this.tabsManager = new TabsManager();
|
||||||
|
|
||||||
this._panes = [
|
this._panes = [
|
||||||
this.addDatabasePane,
|
|
||||||
this.addCollectionPane,
|
this.addCollectionPane,
|
||||||
this.deleteCollectionConfirmationPane,
|
this.deleteCollectionConfirmationPane,
|
||||||
this.deleteDatabaseConfirmationPane,
|
this.deleteDatabaseConfirmationPane,
|
||||||
@@ -732,7 +722,7 @@ export default class Explorer {
|
|||||||
this.stringInputPane,
|
this.stringInputPane,
|
||||||
this.setupNotebooksPane,
|
this.setupNotebooksPane,
|
||||||
];
|
];
|
||||||
this.addDatabaseText.subscribe((addDatabaseText: string) => this.addDatabasePane.title(addDatabaseText));
|
//this.addDatabaseText.subscribe((addDatabaseText: string) => this.addDatabasePane.title(addDatabaseText));
|
||||||
this.isTabsContentExpanded = ko.observable(false);
|
this.isTabsContentExpanded = ko.observable(false);
|
||||||
|
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
@@ -2495,7 +2485,7 @@ export default class Explorer {
|
|||||||
public openAddDatabasePane(): void {
|
public openAddDatabasePane(): void {
|
||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"Add Database",
|
"Add Database",
|
||||||
<AddDatabasePaneF explorer={this} openNotificationConsole={this.expandConsole} closePanel={this.closeSidePanel} />
|
<AddDatabasePane explorer={this} openNotificationConsole={this.expandConsole} closePanel={this.closeSidePanel} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,6 @@ function createNewDatabase(container: Explorer): CommandButtonComponentProps {
|
|||||||
iconSrc: AddDatabaseIcon,
|
iconSrc: AddDatabaseIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
// container.addDatabasePane.open();
|
|
||||||
container.openAddDatabasePane();
|
container.openAddDatabasePane();
|
||||||
document.getElementById("linkAddDatabase").focus();
|
document.getElementById("linkAddDatabase").focus();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,174 +0,0 @@
|
|||||||
<div data-bind="visible: visible, event: { keydown: onPaneKeyDown }">
|
|
||||||
<div class="contextual-pane-out" data-bind="click: cancel, clickBubble: false"></div>
|
|
||||||
<div class="contextual-pane" data-bind="attr: { id: id }">
|
|
||||||
<!-- Add database form -- Start -->
|
|
||||||
<div class="contextual-pane-in">
|
|
||||||
<form data-bind="submit: submit" style="height: 100%">
|
|
||||||
<div
|
|
||||||
class="paneContentContainer"
|
|
||||||
role="dialog"
|
|
||||||
aria-labelledby="databaseTitle"
|
|
||||||
data-bind="template: { name: 'add-database-inputs' }"
|
|
||||||
></div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<!-- Add database form -- End -->
|
|
||||||
<!-- Loader - Start -->
|
|
||||||
<div class="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer" data-bind="visible: isExecuting">
|
|
||||||
<img class="dataExplorerLoader" src="/LoadingIndicator_3Squares.gif" />
|
|
||||||
</div>
|
|
||||||
<!-- Loader - End -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/html" id="add-database-inputs">
|
|
||||||
<!-- Add database header - Start -->
|
|
||||||
<div class="firstdivbg headerline">
|
|
||||||
<span id="databaseTitle" role="heading" aria-level="2" data-bind="text: title"></span>
|
|
||||||
<div
|
|
||||||
class="closeImg"
|
|
||||||
role="button"
|
|
||||||
aria-label="Close pane"
|
|
||||||
data-bind="click: cancel, event: { keypress: onCloseKeyPress }"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<img src="../../../images/close-black.svg" title="Close" alt="Close" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Add database header - End -->
|
|
||||||
|
|
||||||
<!-- Add database errors - Start -->
|
|
||||||
<div class="warningErrorContainer" aria-live="assertive" data-bind="visible: formErrors() && formErrors() !== ''">
|
|
||||||
<div class="warningErrorContent">
|
|
||||||
<span><img class="paneErrorIcon" src="/error_red.svg" alt="Error" /></span>
|
|
||||||
<span class="warningErrorDetailsLinkContainer">
|
|
||||||
<span class="formErrors" data-bind="text: formErrors, attr: { title: formErrors }"></span>
|
|
||||||
<a
|
|
||||||
class="errorLink"
|
|
||||||
role="link"
|
|
||||||
data-bind="visible: formErrorsDetails() && formErrorsDetails() !== '', click: showErrorDetails, event: { keypress: onMoreDetailsKeyPress }"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
More details</a
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Add database errors - End -->
|
|
||||||
|
|
||||||
<!-- upsell message - start -->
|
|
||||||
<div
|
|
||||||
class="infoBoxContainer"
|
|
||||||
aria-live="assertive"
|
|
||||||
data-bind="visible: showUpsellMessage && showUpsellMessage() && formErrors && !formErrors()"
|
|
||||||
>
|
|
||||||
<div class="infoBoxContent">
|
|
||||||
<span><img class="infoBoxIcon" src="/info_color.svg" alt="Promo" /></span>
|
|
||||||
<span class="infoBoxDetails">
|
|
||||||
<span class="infoBoxMessage" data-bind="text: upsellMessage, attr: { title: upsellMessage }"></span>
|
|
||||||
<a
|
|
||||||
class="underlinedLink"
|
|
||||||
id="linkAddDatabase"
|
|
||||||
data-bind="text: upsellAnchorText, attr: { 'href': upsellAnchorUrl, 'aria-label': upsellMessageAriaLabel }"
|
|
||||||
target="_blank"
|
|
||||||
href=""
|
|
||||||
tabindex="0"
|
|
||||||
></a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- upsell message - end -->
|
|
||||||
|
|
||||||
<!-- Add database inputs - Start -->
|
|
||||||
<div class="paneMainContent">
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<span class="mandatoryStar">*</span>
|
|
||||||
<span data-bind="text: databaseIdLabel"></span>
|
|
||||||
<span class="infoTooltip" role="tooltip" tabindex="0">
|
|
||||||
<img class="infoImg" src="/info-bubble.svg" alt="More information" />
|
|
||||||
<span class="tooltiptext infoTooltipWidth" data-bind="text: databaseIdTooltipText"></span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<input
|
|
||||||
id="database-id"
|
|
||||||
type="text"
|
|
||||||
aria-required="true"
|
|
||||||
autocomplete="off"
|
|
||||||
pattern="[^/?#\\]*[^/?# \\]"
|
|
||||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
|
||||||
size="40"
|
|
||||||
class="collid"
|
|
||||||
data-bind="textInput: databaseId, hasFocus: firstFieldHasFocus, attr: { 'aria-label': databaseIdLabel, 'placeholder': databaseIdPlaceHolder }"
|
|
||||||
autofocus
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Database provisioned throughput - Start -->
|
|
||||||
<!-- ko if: canConfigureThroughput -->
|
|
||||||
<div class="databaseProvision" aria-label="New database provision support">
|
|
||||||
<input
|
|
||||||
tabindex="0"
|
|
||||||
type="checkbox"
|
|
||||||
id="addDatabasePane-databaseSharedThroughput"
|
|
||||||
title="Provision shared throughput"
|
|
||||||
data-bind="checked: databaseCreateNewShared"
|
|
||||||
/>
|
|
||||||
<span class="databaseProvisionText" for="databaseSharedThroughput">Provision throughput</span>
|
|
||||||
<span class="infoTooltip" role="tooltip" tabindex="0">
|
|
||||||
<img class="infoImg" src="/info-bubble.svg" alt="More information" />
|
|
||||||
<span
|
|
||||||
class="tooltiptext provisionDatabaseThroughput"
|
|
||||||
data-bind="text: databaseLevelThroughputTooltipText"
|
|
||||||
></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div data-bind="visible: databaseCreateNewShared">
|
|
||||||
<throughput-input-autopilot-v3
|
|
||||||
params="{
|
|
||||||
step: 100,
|
|
||||||
value: throughput,
|
|
||||||
testId: 'sharedThroughputValue',
|
|
||||||
minimum: minThroughputRU,
|
|
||||||
maximum: maxThroughputRU,
|
|
||||||
isEnabled: databaseCreateNewShared,
|
|
||||||
label: throughputRangeText,
|
|
||||||
ariaLabel: throughputRangeText,
|
|
||||||
costsVisible: costsVisible,
|
|
||||||
requestUnitsUsageCost: requestUnitsUsageCost,
|
|
||||||
spendAckChecked: throughputSpendAck,
|
|
||||||
spendAckId: 'throughputSpendAckDatabase',
|
|
||||||
spendAckText: throughputSpendAckText,
|
|
||||||
spendAckVisible: throughputSpendAckVisible,
|
|
||||||
showAsMandatory: true,
|
|
||||||
infoBubbleText: ruToolTipText,
|
|
||||||
throughputAutoPilotRadioId: 'newDatabase-databaseThroughput-autoPilotRadio',
|
|
||||||
throughputProvisionedRadioId: 'newDatabase-databaseThroughput-manualRadio',
|
|
||||||
throughputModeRadioName: 'throughputModeRadioName',
|
|
||||||
isAutoPilotSelected: isAutoPilotSelected,
|
|
||||||
maxAutoPilotThroughputSet: maxAutoPilotThroughputSet,
|
|
||||||
autoPilotUsageCost: autoPilotUsageCost,
|
|
||||||
canExceedMaximumValue: canExceedMaximumValue,
|
|
||||||
freeTierExceedThroughputTooltip: freeTierExceedThroughputTooltip
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</throughput-input-autopilot-v3>
|
|
||||||
<p data-bind="visible: canRequestSupport">
|
|
||||||
<!-- TODO: Replace link with call to the Azure Support blade --><a
|
|
||||||
href="https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20More%20Throughput%20Request"
|
|
||||||
>Contact support</a
|
|
||||||
>
|
|
||||||
for more than <span data-bind="text: maxThroughputRUText"></span> RU/s.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- /ko -->
|
|
||||||
<!-- Database provisioned throughput - End -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paneFooter">
|
|
||||||
<div class="leftpanel-okbut">
|
|
||||||
<input type="submit" value="OK" class="btncreatecoll1" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Add database inputs - End -->
|
|
||||||
</script>
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
import * as Constants from "../../Common/Constants";
|
|
||||||
import { SubscriptionType } from "../../Contracts/SubscriptionType";
|
|
||||||
import Explorer from "../Explorer";
|
|
||||||
import AddDatabasePane from "./AddDatabasePane";
|
|
||||||
import { DatabaseAccount } from "../../Contracts/DataModels";
|
|
||||||
|
|
||||||
describe("Add Database Pane", () => {
|
|
||||||
describe("getSharedThroughputDefault()", () => {
|
|
||||||
let explorer: Explorer;
|
|
||||||
const mockDatabaseAccount: DatabaseAccount = {
|
|
||||||
id: "mock",
|
|
||||||
kind: "DocumentDB",
|
|
||||||
location: "",
|
|
||||||
name: "mock",
|
|
||||||
properties: {
|
|
||||||
documentEndpoint: "",
|
|
||||||
cassandraEndpoint: "",
|
|
||||||
gremlinEndpoint: "",
|
|
||||||
tableEndpoint: "",
|
|
||||||
enableFreeTier: false,
|
|
||||||
},
|
|
||||||
type: undefined,
|
|
||||||
tags: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockFreeTierDatabaseAccount: DatabaseAccount = {
|
|
||||||
id: "mock",
|
|
||||||
kind: "DocumentDB",
|
|
||||||
location: "",
|
|
||||||
name: "mock",
|
|
||||||
properties: {
|
|
||||||
documentEndpoint: "",
|
|
||||||
cassandraEndpoint: "",
|
|
||||||
gremlinEndpoint: "",
|
|
||||||
tableEndpoint: "",
|
|
||||||
enableFreeTier: true,
|
|
||||||
},
|
|
||||||
type: undefined,
|
|
||||||
tags: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
explorer = new Explorer();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be true if subscription type is Benefits", () => {
|
|
||||||
explorer.subscriptionType(SubscriptionType.Benefits);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.getSharedThroughputDefault()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be false if subscription type is EA", () => {
|
|
||||||
explorer.subscriptionType(SubscriptionType.EA);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.getSharedThroughputDefault()).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be true if subscription type is Free", () => {
|
|
||||||
explorer.subscriptionType(SubscriptionType.Free);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.getSharedThroughputDefault()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be true if subscription type is Internal", () => {
|
|
||||||
explorer.subscriptionType(SubscriptionType.Internal);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.getSharedThroughputDefault()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should be true if subscription type is PAYG", () => {
|
|
||||||
explorer.subscriptionType(SubscriptionType.PAYG);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.getSharedThroughputDefault()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should display free tier text in upsell messaging", () => {
|
|
||||||
explorer.databaseAccount(mockFreeTierDatabaseAccount);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.isFreeTierAccount()).toBe(true);
|
|
||||||
expect(addDatabasePane.upsellMessage()).toContain("With free tier");
|
|
||||||
expect(addDatabasePane.upsellAnchorUrl()).toBe(Constants.Urls.freeTierInformation);
|
|
||||||
expect(addDatabasePane.upsellAnchorText()).toBe("Learn more");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should display standard texr in upsell messaging", () => {
|
|
||||||
explorer.databaseAccount(mockDatabaseAccount);
|
|
||||||
const addDatabasePane = explorer.addDatabasePane as AddDatabasePane;
|
|
||||||
expect(addDatabasePane.isFreeTierAccount()).toBe(false);
|
|
||||||
expect(addDatabasePane.upsellMessage()).toContain("Start at");
|
|
||||||
expect(addDatabasePane.upsellAnchorUrl()).toBe(Constants.Urls.cosmosPricing);
|
|
||||||
expect(addDatabasePane.upsellAnchorText()).toBe("More details");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,469 +0,0 @@
|
|||||||
import * as ko from "knockout";
|
|
||||||
import * as Constants from "../../Common/Constants";
|
|
||||||
import { createDatabase } from "../../Common/dataAccess/createDatabase";
|
|
||||||
import editable from "../../Common/EditableUtility";
|
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
|
||||||
import { configContext, Platform } from "../../ConfigContext";
|
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
|
||||||
import { SubscriptionType } from "../../Contracts/SubscriptionType";
|
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import * as SharedConstants from "../../Shared/Constants";
|
|
||||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
|
||||||
import { userContext } from "../../UserContext";
|
|
||||||
import * as AutoPilotUtils from "../../Utils/AutoPilotUtils";
|
|
||||||
import * as PricingUtils from "../../Utils/PricingUtils";
|
|
||||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
|
||||||
|
|
||||||
export default class AddDatabasePane extends ContextualPaneBase {
|
|
||||||
public defaultExperience: ko.Computed<string>;
|
|
||||||
public databaseIdLabel: ko.Computed<string>;
|
|
||||||
public databaseIdPlaceHolder: ko.Computed<string>;
|
|
||||||
public databaseId: ko.Observable<string>;
|
|
||||||
public databaseIdTooltipText: ko.Computed<string>;
|
|
||||||
public databaseLevelThroughputTooltipText: ko.Computed<string>;
|
|
||||||
public databaseCreateNewShared: ko.Observable<boolean>;
|
|
||||||
public formErrorsDetails: ko.Observable<string>;
|
|
||||||
public throughput: ViewModels.Editable<number>;
|
|
||||||
public maxThroughputRU: ko.Observable<number>;
|
|
||||||
public minThroughputRU: ko.Observable<number>;
|
|
||||||
public maxThroughputRUText: ko.PureComputed<string>;
|
|
||||||
public throughputRangeText: ko.Computed<string>;
|
|
||||||
public throughputSpendAckText: ko.Observable<string>;
|
|
||||||
public throughputSpendAck: ko.Observable<boolean>;
|
|
||||||
public throughputSpendAckVisible: ko.Computed<boolean>;
|
|
||||||
public requestUnitsUsageCost: ko.Computed<string>;
|
|
||||||
public canRequestSupport: ko.PureComputed<boolean>;
|
|
||||||
public costsVisible: ko.PureComputed<boolean>;
|
|
||||||
public upsellMessage: ko.PureComputed<string>;
|
|
||||||
public upsellMessageAriaLabel: ko.PureComputed<string>;
|
|
||||||
public upsellAnchorUrl: ko.PureComputed<string>;
|
|
||||||
public upsellAnchorText: ko.PureComputed<string>;
|
|
||||||
public isAutoPilotSelected: ko.Observable<boolean>;
|
|
||||||
public maxAutoPilotThroughputSet: ko.Observable<number>;
|
|
||||||
public autoPilotUsageCost: ko.Computed<string>;
|
|
||||||
public canExceedMaximumValue: ko.PureComputed<boolean>;
|
|
||||||
public ruToolTipText: ko.Computed<string>;
|
|
||||||
public freeTierExceedThroughputTooltip: ko.Computed<string>;
|
|
||||||
public isFreeTierAccount: ko.Computed<boolean>;
|
|
||||||
public canConfigureThroughput: ko.PureComputed<boolean>;
|
|
||||||
public showUpsellMessage: ko.PureComputed<boolean>;
|
|
||||||
|
|
||||||
constructor(options: ViewModels.PaneOptions) {
|
|
||||||
super(options);
|
|
||||||
this.title((this.container && this.container.addDatabaseText()) || "New Database");
|
|
||||||
this.databaseId = ko.observable<string>();
|
|
||||||
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText());
|
|
||||||
this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
|
||||||
|
|
||||||
this.canExceedMaximumValue = ko.pureComputed(() => this.container.canExceedMaximumValue());
|
|
||||||
|
|
||||||
// TODO 388844: get defaults from parent frame
|
|
||||||
this.databaseCreateNewShared = ko.observable<boolean>(this.getSharedThroughputDefault());
|
|
||||||
|
|
||||||
this.container.subscriptionType &&
|
|
||||||
this.container.subscriptionType.subscribe((subscriptionType) => {
|
|
||||||
this.databaseCreateNewShared(this.getSharedThroughputDefault());
|
|
||||||
});
|
|
||||||
|
|
||||||
this.databaseIdLabel = ko.computed<string>(() =>
|
|
||||||
this.container.isPreferredApiCassandra() ? "Keyspace id" : "Database id"
|
|
||||||
);
|
|
||||||
|
|
||||||
this.databaseIdPlaceHolder = ko.computed<string>(() =>
|
|
||||||
this.container.isPreferredApiCassandra() ? "Type a new keyspace id" : "Type a new database id"
|
|
||||||
);
|
|
||||||
|
|
||||||
this.databaseIdTooltipText = ko.computed<string>(() => {
|
|
||||||
const isCassandraAccount: boolean = this.container.isPreferredApiCassandra();
|
|
||||||
return `A ${isCassandraAccount ? "keyspace" : "database"} is a logical container of one or more ${
|
|
||||||
isCassandraAccount ? "tables" : "collections"
|
|
||||||
}`;
|
|
||||||
});
|
|
||||||
this.databaseLevelThroughputTooltipText = ko.computed<string>(() => {
|
|
||||||
const isCassandraAccount: boolean = this.container.isPreferredApiCassandra();
|
|
||||||
const databaseLabel: string = isCassandraAccount ? "keyspace" : "database";
|
|
||||||
const collectionsLabel: string = isCassandraAccount ? "tables" : "collections";
|
|
||||||
return `Provisioned throughput at the ${databaseLabel} level will be shared across all ${collectionsLabel} within the ${databaseLabel}.`;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.throughput = editable.observable<number>();
|
|
||||||
this.maxThroughputRU = ko.observable<number>();
|
|
||||||
this.minThroughputRU = ko.observable<number>();
|
|
||||||
this.throughputSpendAckText = ko.observable<string>();
|
|
||||||
this.throughputSpendAck = ko.observable<boolean>(false);
|
|
||||||
this.isAutoPilotSelected = ko.observable<boolean>(false);
|
|
||||||
this.maxAutoPilotThroughputSet = ko.observable<number>(AutoPilotUtils.minAutoPilotThroughput);
|
|
||||||
this.autoPilotUsageCost = ko.pureComputed<string>(() => {
|
|
||||||
const autoPilot = this._isAutoPilotSelectedAndWhatTier();
|
|
||||||
if (!autoPilot) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return PricingUtils.getAutoPilotV3SpendHtml(autoPilot.maxThroughput, true /* isDatabaseThroughput */);
|
|
||||||
});
|
|
||||||
this.throughputRangeText = ko.pureComputed<string>(() => {
|
|
||||||
if (this.isAutoPilotSelected()) {
|
|
||||||
return AutoPilotUtils.getAutoPilotHeaderText();
|
|
||||||
}
|
|
||||||
return `Throughput (${this.minThroughputRU().toLocaleString()} - ${this.maxThroughputRU().toLocaleString()} RU/s)`;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.requestUnitsUsageCost = ko.computed(() => {
|
|
||||||
const offerThroughput: number = this.throughput();
|
|
||||||
if (
|
|
||||||
offerThroughput < this.minThroughputRU() ||
|
|
||||||
(offerThroughput > this.maxThroughputRU() && !this.canExceedMaximumValue())
|
|
||||||
) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const account = this.container.databaseAccount();
|
|
||||||
if (!account) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const regions =
|
|
||||||
(account &&
|
|
||||||
account.properties &&
|
|
||||||
account.properties.readLocations &&
|
|
||||||
account.properties.readLocations.length) ||
|
|
||||||
1;
|
|
||||||
const multimaster = (account && account.properties && account.properties.enableMultipleWriteLocations) || false;
|
|
||||||
|
|
||||||
let estimatedSpendAcknowledge: string;
|
|
||||||
let estimatedSpend: string;
|
|
||||||
if (!this.isAutoPilotSelected()) {
|
|
||||||
estimatedSpend = PricingUtils.getEstimatedSpendHtml(
|
|
||||||
offerThroughput,
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster
|
|
||||||
);
|
|
||||||
estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString(
|
|
||||||
offerThroughput,
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster,
|
|
||||||
this.isAutoPilotSelected()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
estimatedSpend = PricingUtils.getEstimatedAutoscaleSpendHtml(
|
|
||||||
this.maxAutoPilotThroughputSet(),
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster
|
|
||||||
);
|
|
||||||
estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString(
|
|
||||||
this.maxAutoPilotThroughputSet(),
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster,
|
|
||||||
this.isAutoPilotSelected()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// TODO: change throughputSpendAckText to be a computed value, instead of having this side effect
|
|
||||||
this.throughputSpendAckText(estimatedSpendAcknowledge);
|
|
||||||
return estimatedSpend;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (
|
|
||||||
configContext.platform !== Platform.Emulator &&
|
|
||||||
!userContext.isTryCosmosDBSubscription &&
|
|
||||||
configContext.platform !== Platform.Portal
|
|
||||||
) {
|
|
||||||
const offerThroughput: number = this.throughput();
|
|
||||||
return offerThroughput <= 100000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.isFreeTierAccount = ko.computed<boolean>(() => {
|
|
||||||
const databaseAccount = this.container && this.container.databaseAccount && this.container.databaseAccount();
|
|
||||||
const isFreeTierAccount =
|
|
||||||
databaseAccount && databaseAccount.properties && databaseAccount.properties.enableFreeTier;
|
|
||||||
return isFreeTierAccount;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.showUpsellMessage = ko.pureComputed(() => {
|
|
||||||
if (this.container.isServerlessEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isFreeTierAccount()) {
|
|
||||||
return this.databaseCreateNewShared();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.maxThroughputRUText = ko.pureComputed(() => {
|
|
||||||
return this.maxThroughputRU().toLocaleString();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.costsVisible = ko.pureComputed(() => {
|
|
||||||
return configContext.platform !== Platform.Emulator;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.throughputSpendAckVisible = ko.pureComputed<boolean>(() => {
|
|
||||||
const autoscaleThroughput = this.maxAutoPilotThroughputSet() * 1;
|
|
||||||
if (this.isAutoPilotSelected()) {
|
|
||||||
return autoscaleThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedThroughput: number = this.throughput();
|
|
||||||
const maxRU: number = this.maxThroughputRU && this.maxThroughputRU();
|
|
||||||
|
|
||||||
const isMaxRUGreaterThanDefault: boolean = maxRU > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
const isThroughputSetGreaterThanDefault: boolean =
|
|
||||||
selectedThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
|
|
||||||
if (this.canExceedMaximumValue()) {
|
|
||||||
return isThroughputSetGreaterThanDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isThroughputSetGreaterThanDefault && isMaxRUGreaterThanDefault;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.databaseCreateNewShared.subscribe((useShared: boolean) => {
|
|
||||||
this._updateThroughputLimitByDatabase();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.resetData();
|
|
||||||
this.container.flight.subscribe(() => {
|
|
||||||
this.resetData();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.freeTierExceedThroughputTooltip = ko.pureComputed<string>(() =>
|
|
||||||
this.isFreeTierAccount() && !this.container.isFirstResourceCreated()
|
|
||||||
? "The first 400 RU/s in this account are free. Billing will apply to any throughput beyond 400 RU/s."
|
|
||||||
: ""
|
|
||||||
);
|
|
||||||
|
|
||||||
this.upsellMessage = ko.pureComputed<string>(() => {
|
|
||||||
return PricingUtils.getUpsellMessage(
|
|
||||||
userContext.portalEnv,
|
|
||||||
this.isFreeTierAccount(),
|
|
||||||
this.container.isFirstResourceCreated(),
|
|
||||||
this.container.defaultExperience(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.upsellMessageAriaLabel = ko.pureComputed<string>(() => {
|
|
||||||
return `${this.upsellMessage()}. Click ${this.isFreeTierAccount() ? "to learn more" : "for more details"}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.upsellAnchorUrl = ko.pureComputed<string>(() => {
|
|
||||||
return this.isFreeTierAccount() ? Constants.Urls.freeTierInformation : Constants.Urls.cosmosPricing;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.upsellAnchorText = ko.pureComputed<string>(() => {
|
|
||||||
return this.isFreeTierAccount() ? "Learn more" : "More details";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onMoreDetailsKeyPress = (source: any, event: KeyboardEvent): boolean => {
|
|
||||||
if (event.keyCode === Constants.KeyCodes.Space || event.keyCode === Constants.KeyCodes.Enter) {
|
|
||||||
this.showErrorDetails();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
public open() {
|
|
||||||
super.open();
|
|
||||||
this.resetData();
|
|
||||||
const addDatabasePaneOpenMessage = {
|
|
||||||
subscriptionType: SubscriptionType[this.container.subscriptionType()],
|
|
||||||
subscriptionQuotaId: userContext.quotaId,
|
|
||||||
defaultsCheck: {
|
|
||||||
throughput: this.throughput(),
|
|
||||||
flight: this.container.flight(),
|
|
||||||
},
|
|
||||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
|
||||||
};
|
|
||||||
const focusElement = document.getElementById("database-id");
|
|
||||||
focusElement && focusElement.focus();
|
|
||||||
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public submit() {
|
|
||||||
if (!this._isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const offerThroughput: number = this._computeOfferThroughput();
|
|
||||||
|
|
||||||
const addDatabasePaneStartMessage = {
|
|
||||||
database: ko.toJS({
|
|
||||||
id: this.databaseId(),
|
|
||||||
shared: this.databaseCreateNewShared(),
|
|
||||||
}),
|
|
||||||
offerThroughput,
|
|
||||||
subscriptionType: SubscriptionType[this.container.subscriptionType()],
|
|
||||||
subscriptionQuotaId: userContext.quotaId,
|
|
||||||
defaultsCheck: {
|
|
||||||
flight: this.container.flight(),
|
|
||||||
},
|
|
||||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
|
||||||
};
|
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateDatabase, addDatabasePaneStartMessage);
|
|
||||||
this.formErrors("");
|
|
||||||
this.isExecuting(true);
|
|
||||||
|
|
||||||
const createDatabaseParams: DataModels.CreateDatabaseParams = {
|
|
||||||
databaseId: addDatabasePaneStartMessage.database.id,
|
|
||||||
databaseLevelThroughput: addDatabasePaneStartMessage.database.shared,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.isAutoPilotSelected()) {
|
|
||||||
createDatabaseParams.autoPilotMaxThroughput = this.maxAutoPilotThroughputSet();
|
|
||||||
} else {
|
|
||||||
createDatabaseParams.offerThroughput = addDatabasePaneStartMessage.offerThroughput;
|
|
||||||
}
|
|
||||||
|
|
||||||
createDatabase(createDatabaseParams).then(
|
|
||||||
(database: DataModels.Database) => {
|
|
||||||
this._onCreateDatabaseSuccess(offerThroughput, startKey);
|
|
||||||
},
|
|
||||||
(error: any) => {
|
|
||||||
this._onCreateDatabaseFailure(error, offerThroughput, startKey);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public resetData() {
|
|
||||||
this.databaseId("");
|
|
||||||
this.databaseCreateNewShared(this.getSharedThroughputDefault());
|
|
||||||
this.isAutoPilotSelected(this.container.isAutoscaleDefaultEnabled());
|
|
||||||
this.maxAutoPilotThroughputSet(AutoPilotUtils.minAutoPilotThroughput);
|
|
||||||
this._updateThroughputLimitByDatabase();
|
|
||||||
this.throughputSpendAck(false);
|
|
||||||
super.resetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSharedThroughputDefault(): boolean {
|
|
||||||
const subscriptionType = this.container.subscriptionType && this.container.subscriptionType();
|
|
||||||
|
|
||||||
if (subscriptionType === SubscriptionType.EA || this.container.isServerlessEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _onCreateDatabaseSuccess(offerThroughput: number, startKey: number): void {
|
|
||||||
this.isExecuting(false);
|
|
||||||
this.close();
|
|
||||||
this.container.refreshAllDatabases();
|
|
||||||
const addDatabasePaneSuccessMessage = {
|
|
||||||
database: ko.toJS({
|
|
||||||
id: this.databaseId(),
|
|
||||||
shared: this.databaseCreateNewShared(),
|
|
||||||
}),
|
|
||||||
offerThroughput: offerThroughput,
|
|
||||||
subscriptionType: SubscriptionType[this.container.subscriptionType()],
|
|
||||||
subscriptionQuotaId: userContext.quotaId,
|
|
||||||
defaultsCheck: {
|
|
||||||
flight: this.container.flight(),
|
|
||||||
},
|
|
||||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
|
||||||
};
|
|
||||||
TelemetryProcessor.traceSuccess(Action.CreateDatabase, addDatabasePaneSuccessMessage, startKey);
|
|
||||||
this.resetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _onCreateDatabaseFailure(error: any, offerThroughput: number, startKey: number): void {
|
|
||||||
this.isExecuting(false);
|
|
||||||
const errorMessage = getErrorMessage(error);
|
|
||||||
this.formErrors(errorMessage);
|
|
||||||
this.formErrorsDetails(errorMessage);
|
|
||||||
const addDatabasePaneFailedMessage = {
|
|
||||||
database: ko.toJS({
|
|
||||||
id: this.databaseId(),
|
|
||||||
shared: this.databaseCreateNewShared(),
|
|
||||||
}),
|
|
||||||
offerThroughput: offerThroughput,
|
|
||||||
subscriptionType: SubscriptionType[this.container.subscriptionType()],
|
|
||||||
subscriptionQuotaId: userContext.quotaId,
|
|
||||||
defaultsCheck: {
|
|
||||||
flight: this.container.flight(),
|
|
||||||
},
|
|
||||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
|
||||||
error: errorMessage,
|
|
||||||
errorStack: getErrorStack(error),
|
|
||||||
};
|
|
||||||
TelemetryProcessor.traceFailure(Action.CreateDatabase, addDatabasePaneFailedMessage, startKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getThroughput(): number {
|
|
||||||
const throughput: number = this.throughput();
|
|
||||||
return isNaN(throughput) ? 0 : Number(throughput);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeOfferThroughput(): number {
|
|
||||||
if (!this.canConfigureThroughput()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isAutoPilotSelected()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._getThroughput();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _isValid(): boolean {
|
|
||||||
// TODO add feature flag that disables validation for customers with custom accounts
|
|
||||||
if (this.isAutoPilotSelected()) {
|
|
||||||
const autoPilot = this._isAutoPilotSelectedAndWhatTier();
|
|
||||||
if (
|
|
||||||
!autoPilot ||
|
|
||||||
!autoPilot.maxThroughput ||
|
|
||||||
!AutoPilotUtils.isValidAutoPilotThroughput(autoPilot.maxThroughput)
|
|
||||||
) {
|
|
||||||
this.formErrors(
|
|
||||||
`Please enter a value greater than ${AutoPilotUtils.minAutoPilotThroughput} for autopilot throughput`
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const throughput = this._getThroughput();
|
|
||||||
|
|
||||||
if (throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && !this.throughputSpendAck()) {
|
|
||||||
this.formErrors(`Please acknowledge the estimated daily spend.`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const autoscaleThroughput = this.maxAutoPilotThroughputSet() * 1;
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.isAutoPilotSelected() &&
|
|
||||||
autoscaleThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K &&
|
|
||||||
!this.throughputSpendAck()
|
|
||||||
) {
|
|
||||||
this.formErrors(`Please acknowledge the estimated monthly spend.`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _isAutoPilotSelectedAndWhatTier(): DataModels.AutoPilotCreationSettings {
|
|
||||||
if (this.isAutoPilotSelected() && this.maxAutoPilotThroughputSet()) {
|
|
||||||
return {
|
|
||||||
maxThroughput: this.maxAutoPilotThroughputSet() * 1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _updateThroughputLimitByDatabase() {
|
|
||||||
const throughputDefaults = this.container.collectionCreationDefaults.throughput;
|
|
||||||
this.throughput(throughputDefaults.shared);
|
|
||||||
this.maxThroughputRU(throughputDefaults.unlimitedmax);
|
|
||||||
this.minThroughputRU(throughputDefaults.unlimitedmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Checkbox, TextField } from "office-ui-fabric-react";
|
import { Checkbox, Text, TextField } from "office-ui-fabric-react";
|
||||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import { createDatabase } from "../../../Common/dataAccess/createDatabase";
|
import { createDatabase } from "../../../Common/dataAccess/createDatabase";
|
||||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||||
|
import { Tooltip } from "../../../Common/Tooltip";
|
||||||
import { configContext, Platform } from "../../../ConfigContext";
|
import { configContext, Platform } from "../../../ConfigContext";
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
import { SubscriptionType } from "../../../Contracts/SubscriptionType";
|
import { SubscriptionType } from "../../../Contracts/SubscriptionType";
|
||||||
@@ -16,7 +17,6 @@ import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput"
|
|||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import { GenericRightPaneComponent, GenericRightPaneProps } from "../GenericRightPaneComponent";
|
import { GenericRightPaneComponent, GenericRightPaneProps } from "../GenericRightPaneComponent";
|
||||||
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||||
import { Tooltip } from "./Tooltip";
|
|
||||||
|
|
||||||
export interface AddDatabasePaneProps {
|
export interface AddDatabasePaneProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
@@ -24,7 +24,7 @@ export interface AddDatabasePaneProps {
|
|||||||
openNotificationConsole: () => void;
|
openNotificationConsole: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
export const AddDatabasePane: FunctionComponent<AddDatabasePaneProps> = ({
|
||||||
explorer: container,
|
explorer: container,
|
||||||
closePanel,
|
closePanel,
|
||||||
openNotificationConsole,
|
openNotificationConsole,
|
||||||
@@ -67,82 +67,11 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
const [throughput, setThroughput] = useState<number>(throughputDefaults.shared);
|
const [throughput, setThroughput] = useState<number>(throughputDefaults.shared);
|
||||||
|
|
||||||
const [maxThroughputRU, setMaxThroughputRU] = useState<number>(throughputDefaults.unlimitedmax);
|
const [maxThroughputRU, setMaxThroughputRU] = useState<number>(throughputDefaults.unlimitedmax);
|
||||||
const [minThroughputRU, setMinThroughputRU] = useState<number>(throughputDefaults.unlimitedmin);
|
|
||||||
const maxThroughputRUText: string = maxThroughputRU?.toLocaleString();
|
const maxThroughputRUText: string = maxThroughputRU?.toLocaleString();
|
||||||
const [isAutoPilotSelected, setIsAutoPilotSelected] = useState<boolean>(container.isAutoscaleDefaultEnabled());
|
const [isAutoPilotSelected, setIsAutoPilotSelected] = useState<boolean>(container.isAutoscaleDefaultEnabled());
|
||||||
const [throughputRangeText, setThroughputRangeText] = useState<string>(
|
|
||||||
isAutoPilotSelected
|
|
||||||
? AutoPilotUtils.getAutoPilotHeaderText()
|
|
||||||
: `Throughput (${minThroughputRU?.toLocaleString()} - ${maxThroughputRU?.toLocaleString()} RU/s)`
|
|
||||||
);
|
|
||||||
const [throughputSpendAckText, setThroughputSpendAckText] = useState<string>();
|
|
||||||
const [throughputSpendAck, setThroughputSpendAck] = useState<boolean>(false);
|
const [throughputSpendAck, setThroughputSpendAck] = useState<boolean>(false);
|
||||||
const canExceedMaximumValue: boolean = container.canExceedMaximumValue();
|
|
||||||
const [throughputSpendAckVisible, setThroughputSpendAckVisible] = useState<boolean>(() => {
|
|
||||||
if (isAutoPilotSelected) {
|
|
||||||
const autoscaleThroughput = maxAutoPilotThroughputSet * 1;
|
|
||||||
return autoscaleThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedThroughput: number = throughput;
|
|
||||||
const maxRU: number = maxThroughputRU && maxThroughputRU;
|
|
||||||
|
|
||||||
const isMaxRUGreaterThanDefault: boolean = maxRU > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
const isThroughputSetGreaterThanDefault: boolean =
|
|
||||||
selectedThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K;
|
|
||||||
|
|
||||||
if (canExceedMaximumValue) {
|
|
||||||
return isThroughputSetGreaterThanDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isThroughputSetGreaterThanDefault && isMaxRUGreaterThanDefault;
|
|
||||||
});
|
|
||||||
const [requestUnitsUsageCost, setRequestUnitsUsageCost] = useState<string>(() => {
|
|
||||||
const offerThroughput: number = throughput;
|
|
||||||
if (offerThroughput < minThroughputRU || (offerThroughput > maxThroughputRU && !canExceedMaximumValue)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const account = userContext.databaseAccount;
|
|
||||||
if (!account) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const regions =
|
|
||||||
(account && account.properties && account.properties.readLocations && account.properties.readLocations.length) ||
|
|
||||||
1;
|
|
||||||
const multimaster = (account && account.properties && account.properties.enableMultipleWriteLocations) || false;
|
|
||||||
|
|
||||||
let estimatedSpendAcknowledge: string;
|
|
||||||
let estimatedSpend: string;
|
|
||||||
if (!isAutoPilotSelected) {
|
|
||||||
estimatedSpend = PricingUtils.getEstimatedSpendHtml(offerThroughput, userContext.portalEnv, regions, multimaster);
|
|
||||||
estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString(
|
|
||||||
offerThroughput,
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster,
|
|
||||||
isAutoPilotSelected
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
estimatedSpend = PricingUtils.getEstimatedAutoscaleSpendHtml(
|
|
||||||
maxAutoPilotThroughputSet,
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster
|
|
||||||
);
|
|
||||||
estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString(
|
|
||||||
maxAutoPilotThroughputSet,
|
|
||||||
userContext.portalEnv,
|
|
||||||
regions,
|
|
||||||
multimaster,
|
|
||||||
isAutoPilotSelected
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// TODO: change throughputSpendAckText to be a computed value, instead of having this side effect
|
|
||||||
setThroughputSpendAckText(estimatedSpendAcknowledge);
|
|
||||||
return estimatedSpend;
|
|
||||||
});
|
|
||||||
const canRequestSupport = () => {
|
const canRequestSupport = () => {
|
||||||
if (
|
if (
|
||||||
configContext.platform !== Platform.Emulator &&
|
configContext.platform !== Platform.Emulator &&
|
||||||
@@ -155,7 +84,6 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const [costsVisible, setCostsVisible] = useState<boolean>(configContext.platform !== Platform.Emulator);
|
|
||||||
const isFreeTierAccount: boolean = userContext.databaseAccount?.properties?.enableFreeTier;
|
const isFreeTierAccount: boolean = userContext.databaseAccount?.properties?.enableFreeTier;
|
||||||
const upsellMessage: string = PricingUtils.getUpsellMessage(
|
const upsellMessage: string = PricingUtils.getUpsellMessage(
|
||||||
userContext.portalEnv,
|
userContext.portalEnv,
|
||||||
@@ -164,9 +92,7 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
userContext.defaultExperience,
|
userContext.defaultExperience,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const upsellMessageAriaLabel: string = `${upsellMessage}. Click ${
|
|
||||||
isFreeTierAccount ? "to learn more" : "for more details"
|
|
||||||
}`;
|
|
||||||
const upsellAnchorUrl: string = isFreeTierAccount ? Constants.Urls.freeTierInformation : Constants.Urls.cosmosPricing;
|
const upsellAnchorUrl: string = isFreeTierAccount ? Constants.Urls.freeTierInformation : Constants.Urls.cosmosPricing;
|
||||||
|
|
||||||
const upsellAnchorText: string = isFreeTierAccount ? "Learn more" : "More details";
|
const upsellAnchorText: string = isFreeTierAccount ? "Learn more" : "More details";
|
||||||
@@ -174,15 +100,6 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
AutoPilotUtils.minAutoPilotThroughput
|
AutoPilotUtils.minAutoPilotThroughput
|
||||||
);
|
);
|
||||||
|
|
||||||
const [autoPilotUsageCost, setAutoPilotUsageCost] = useState<string>(() => {
|
|
||||||
const autoPilot = _isAutoPilotSelectedAndWhatTier();
|
|
||||||
if (!autoPilot) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return PricingUtils.getAutoPilotV3SpendHtml(autoPilot.maxThroughput, true /* isDatabaseThroughput */);
|
|
||||||
});
|
|
||||||
const ruToolTipText: string = PricingUtils.getRuToolTipText();
|
|
||||||
|
|
||||||
const canConfigureThroughput = !container.isServerlessEnabled();
|
const canConfigureThroughput = !container.isServerlessEnabled();
|
||||||
const showUpsellMessage = () => {
|
const showUpsellMessage = () => {
|
||||||
if (container.isServerlessEnabled()) {
|
if (container.isServerlessEnabled()) {
|
||||||
@@ -202,7 +119,6 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
const throughputDefaults = container.collectionCreationDefaults.throughput;
|
const throughputDefaults = container.collectionCreationDefaults.throughput;
|
||||||
setThroughput(throughputDefaults.shared);
|
setThroughput(throughputDefaults.shared);
|
||||||
setMaxThroughputRU(throughputDefaults.unlimitedmax);
|
setMaxThroughputRU(throughputDefaults.unlimitedmax);
|
||||||
setMinThroughputRU(throughputDefaults.unlimitedmin);
|
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
_updateThroughputLimitByDatabase();
|
_updateThroughputLimitByDatabase();
|
||||||
@@ -412,7 +328,7 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<span className="mandatoryStar">*</span>
|
<span className="mandatoryStar">*</span>
|
||||||
<span>{databaseIdLabel}</span>
|
<Text variant="small">{databaseIdLabel}</Text>
|
||||||
<Tooltip>{databaseIdTooltipText}</Tooltip>
|
<Tooltip>{databaseIdTooltipText}</Tooltip>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -439,16 +355,14 @@ export const AddDatabasePaneF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
title="Provision shared throughput"
|
title="Provision shared throughput"
|
||||||
styles={{
|
styles={{
|
||||||
text: { fontSize: 12 },
|
|
||||||
checkbox: { width: 12, height: 12 },
|
checkbox: { width: 12, height: 12 },
|
||||||
label: { padding: 0, alignItems: "center" },
|
label: { padding: 0, alignItems: "center" },
|
||||||
}}
|
}}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
label="Provision throughput"
|
label="Provision throughput"
|
||||||
className="databaseProvisionText"
|
|
||||||
checked={databaseCreateNewShared}
|
checked={databaseCreateNewShared}
|
||||||
onChange={() => setDatabaseCreateNewShared(!databaseCreateNewShared)}
|
onChange={() => setDatabaseCreateNewShared(!databaseCreateNewShared)}
|
||||||
/>
|
/>{" "}
|
||||||
<Tooltip>{databaseLevelThroughputTooltipText}</Tooltip>
|
<Tooltip>{databaseLevelThroughputTooltipText}</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
{databaseCreateNewShared && (
|
{databaseCreateNewShared && (
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
import AddDatabasePaneTemplate from "./AddDatabasePane.html";
|
|
||||||
import AddCollectionPaneTemplate from "./AddCollectionPane.html";
|
import AddCollectionPaneTemplate from "./AddCollectionPane.html";
|
||||||
|
import BrowseQueriesPaneTemplate from "./BrowseQueriesPane.html";
|
||||||
|
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
|
||||||
import DeleteCollectionConfirmationPaneTemplate from "./DeleteCollectionConfirmationPane.html";
|
import DeleteCollectionConfirmationPaneTemplate from "./DeleteCollectionConfirmationPane.html";
|
||||||
import DeleteDatabaseConfirmationPaneTemplate from "./DeleteDatabaseConfirmationPane.html";
|
import DeleteDatabaseConfirmationPaneTemplate from "./DeleteDatabaseConfirmationPane.html";
|
||||||
|
import ExecuteSprocParamsPaneTemplate from "./ExecuteSprocParamsPane.html";
|
||||||
|
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
||||||
import GraphNewVertexPaneTemplate from "./GraphNewVertexPane.html";
|
import GraphNewVertexPaneTemplate from "./GraphNewVertexPane.html";
|
||||||
import GraphStylingPaneTemplate from "./GraphStylingPane.html";
|
import GraphStylingPaneTemplate from "./GraphStylingPane.html";
|
||||||
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html";
|
|
||||||
import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html";
|
|
||||||
import TableColumnOptionsPaneTemplate from "./Tables/TableColumnOptionsPane.html";
|
|
||||||
import TableQuerySelectPaneTemplate from "./Tables/TableQuerySelectPane.html";
|
|
||||||
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
|
|
||||||
import SettingsPaneTemplate from "./SettingsPane.html";
|
|
||||||
import ExecuteSprocParamsPaneTemplate from "./ExecuteSprocParamsPane.html";
|
|
||||||
import UploadItemsPaneTemplate from "./UploadItemsPane.html";
|
|
||||||
import LoadQueryPaneTemplate from "./LoadQueryPane.html";
|
import LoadQueryPaneTemplate from "./LoadQueryPane.html";
|
||||||
import SaveQueryPaneTemplate from "./SaveQueryPane.html";
|
import SaveQueryPaneTemplate from "./SaveQueryPane.html";
|
||||||
import BrowseQueriesPaneTemplate from "./BrowseQueriesPane.html";
|
import SettingsPaneTemplate from "./SettingsPane.html";
|
||||||
import UploadFilePaneTemplate from "./UploadFilePane.html";
|
|
||||||
import StringInputPaneTemplate from "./StringInputPane.html";
|
|
||||||
import SetupNotebooksPaneTemplate from "./SetupNotebooksPane.html";
|
import SetupNotebooksPaneTemplate from "./SetupNotebooksPane.html";
|
||||||
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
import StringInputPaneTemplate from "./StringInputPane.html";
|
||||||
|
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html";
|
||||||
|
import TableColumnOptionsPaneTemplate from "./Tables/TableColumnOptionsPane.html";
|
||||||
|
import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html";
|
||||||
|
import TableQuerySelectPaneTemplate from "./Tables/TableQuerySelectPane.html";
|
||||||
|
import UploadFilePaneTemplate from "./UploadFilePane.html";
|
||||||
|
import UploadItemsPaneTemplate from "./UploadItemsPane.html";
|
||||||
|
|
||||||
export class PaneComponent {
|
export class PaneComponent {
|
||||||
constructor(data: any) {
|
constructor(data: any) {
|
||||||
@@ -26,14 +25,6 @@ export class PaneComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AddDatabasePaneComponent {
|
|
||||||
constructor() {
|
|
||||||
return {
|
|
||||||
viewModel: PaneComponent,
|
|
||||||
template: AddDatabasePaneTemplate,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AddCollectionPaneComponent {
|
export class AddCollectionPaneComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
iconSrc: AddDatabaseIcon,
|
iconSrc: AddDatabaseIcon,
|
||||||
title: this.container.addDatabaseText(),
|
title: this.container.addDatabaseText(),
|
||||||
description: null,
|
description: null,
|
||||||
onClick: () => this.container.addDatabasePane.open(),
|
onClick: () => this.container.openAddDatabasePane(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -241,7 +241,6 @@ const App: React.FunctionComponent = () => {
|
|||||||
isConsoleExpanded={isNotificationConsoleExpanded}
|
isConsoleExpanded={isNotificationConsoleExpanded}
|
||||||
/>
|
/>
|
||||||
<div data-bind="react:uploadItemsPaneAdapter" />
|
<div data-bind="react:uploadItemsPaneAdapter" />
|
||||||
<div data-bind='component: { name: "add-database-pane", params: {data: addDatabasePane} }' />
|
|
||||||
<div data-bind='component: { name: "add-collection-pane", params: { data: addCollectionPane} }' />
|
<div data-bind='component: { name: "add-collection-pane", params: { data: addCollectionPane} }' />
|
||||||
<div data-bind='component: { name: "delete-collection-confirmation-pane", params: { data: deleteCollectionConfirmationPane} }' />
|
<div data-bind='component: { name: "delete-collection-confirmation-pane", params: { data: deleteCollectionConfirmationPane} }' />
|
||||||
<div data-bind='component: { name: "delete-database-confirmation-pane", params: { data: deleteDatabaseConfirmationPane} }' />
|
<div data-bind='component: { name: "delete-database-confirmation-pane", params: { data: deleteDatabaseConfirmationPane} }' />
|
||||||
|
|||||||
Reference in New Issue
Block a user