mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
resolve merge conflict
This commit is contained in:
@@ -26,4 +26,3 @@ ko.components.register("graph-styling-pane", new PaneComponents.GraphStylingPane
|
|||||||
ko.components.register("table-add-entity-pane", new PaneComponents.TableAddEntityPaneComponent());
|
ko.components.register("table-add-entity-pane", new PaneComponents.TableAddEntityPaneComponent());
|
||||||
ko.components.register("table-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent());
|
ko.components.register("table-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent());
|
||||||
ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent());
|
ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent());
|
||||||
ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent());
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ export interface DatabaseContextMenuButtonParams {
|
|||||||
* New resource tree (in ReactJS)
|
* New resource tree (in ReactJS)
|
||||||
*/
|
*/
|
||||||
export class ResourceTreeContextMenuButtonFactory {
|
export class ResourceTreeContextMenuButtonFactory {
|
||||||
public static createDatabaseContextMenu(container: Explorer): TreeNodeMenuItem[] {
|
public static createDatabaseContextMenu(container: Explorer, databaseId: string): TreeNodeMenuItem[] {
|
||||||
const items: TreeNodeMenuItem[] = [
|
const items: TreeNodeMenuItem[] = [
|
||||||
{
|
{
|
||||||
iconSrc: AddCollectionIcon,
|
iconSrc: AddCollectionIcon,
|
||||||
onClick: () => container.onNewCollectionClicked(),
|
onClick: () => container.onNewCollectionClicked(databaseId),
|
||||||
label: container.addCollectionText(),
|
label: container.addCollectionText(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { accordionStackTokens } from "../Settings/SettingsRenderUtils";
|
|||||||
export interface CollapsibleSectionProps {
|
export interface CollapsibleSectionProps {
|
||||||
title: string;
|
title: string;
|
||||||
isExpandedByDefault: boolean;
|
isExpandedByDefault: boolean;
|
||||||
|
onExpand?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollapsibleSectionState {
|
export interface CollapsibleSectionState {
|
||||||
@@ -23,6 +24,12 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
|
|||||||
this.setState({ isExpanded: !this.state.isExpanded });
|
this.setState({ isExpanded: !this.state.isExpanded });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public componentDidUpdate(): void {
|
||||||
|
if (this.state.isExpanded && this.props.onExpand) {
|
||||||
|
this.props.onExpand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ export interface RepoListItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class GitHubReposComponent extends React.Component<GitHubReposComponentProps> {
|
export class GitHubReposComponent extends React.Component<GitHubReposComponentProps> {
|
||||||
public static readonly ConnectToGitHubTitle = "Connect to GitHub";
|
|
||||||
public static readonly ManageGitHubRepoTitle = "Manage GitHub settings";
|
|
||||||
private static readonly ManageGitHubRepoDescription =
|
private static readonly ManageGitHubRepoDescription =
|
||||||
"Select your GitHub repos and branch(es) to pin to your notebooks workspace.";
|
"Select your GitHub repos and branch(es) to pin to your notebooks workspace.";
|
||||||
private static readonly ManageGitHubRepoResetConnection = "View or change your GitHub authorization settings.";
|
private static readonly ManageGitHubRepoResetConnection = "View or change your GitHub authorization settings.";
|
||||||
@@ -32,14 +30,6 @@ export class GitHubReposComponent extends React.Component<GitHubReposComponentPr
|
|||||||
private static readonly CancelButtonText = "Cancel";
|
private static readonly CancelButtonText = "Cancel";
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
const header: JSX.Element = (
|
|
||||||
<p>
|
|
||||||
{this.props.showAuthorizeAccess
|
|
||||||
? GitHubReposComponent.ConnectToGitHubTitle
|
|
||||||
: GitHubReposComponent.ManageGitHubRepoTitle}
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
|
|
||||||
const content: JSX.Element = this.props.showAuthorizeAccess ? (
|
const content: JSX.Element = this.props.showAuthorizeAccess ? (
|
||||||
<AuthorizeAccessComponent {...this.props.authorizeAccessProps} />
|
<AuthorizeAccessComponent {...this.props.authorizeAccessProps} />
|
||||||
) : (
|
) : (
|
||||||
@@ -66,9 +56,6 @@ export class GitHubReposComponent extends React.Component<GitHubReposComponentPr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={"firstdivbg headerline"} role="heading" aria-level={2}>
|
|
||||||
{header}
|
|
||||||
</div>
|
|
||||||
<div className={"paneMainContent"}>{content}</div>
|
<div className={"paneMainContent"}>{content}</div>
|
||||||
{!this.props.showAuthorizeAccess && (
|
{!this.props.showAuthorizeAccess && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
IStyleFunctionOrObject,
|
|
||||||
ICheckboxStyleProps,
|
ICheckboxStyleProps,
|
||||||
ICheckboxStyles,
|
ICheckboxStyles,
|
||||||
IDropdownStyles,
|
|
||||||
IDropdownStyleProps,
|
IDropdownStyleProps,
|
||||||
|
IDropdownStyles,
|
||||||
|
IStyleFunctionOrObject,
|
||||||
} from "office-ui-fabric-react";
|
} from "office-ui-fabric-react";
|
||||||
|
|
||||||
export const ButtonsFooterStyle: React.CSSProperties = {
|
export const ButtonsFooterStyle: React.CSSProperties = {
|
||||||
padding: 14,
|
paddingTop: 14,
|
||||||
height: "auto",
|
height: "auto",
|
||||||
|
borderTop: "2px solid lightGray",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ContentFooterStyle: React.CSSProperties = {
|
export const ContentFooterStyle: React.CSSProperties = {
|
||||||
padding: "10px 24px 10px 24px",
|
paddingTop: "10px",
|
||||||
height: "auto",
|
height: "auto",
|
||||||
|
borderTop: "2px solid lightGray",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChildrenMargin = 10;
|
export const ChildrenMargin = 10;
|
||||||
@@ -53,6 +55,11 @@ export const BranchesDropdownOptionContainerStyle: React.CSSProperties = {
|
|||||||
padding: 8,
|
padding: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ContentMainStyle: React.CSSProperties = {
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
};
|
||||||
|
|
||||||
export const ReposListRepoColumnMinWidth = 192;
|
export const ReposListRepoColumnMinWidth = 192;
|
||||||
export const ReposListBranchesColumnWidth = 116;
|
export const ReposListBranchesColumnWidth = 116;
|
||||||
export const BranchesDropdownWidth = 200;
|
export const BranchesDropdownWidth = 200;
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
|
|||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<em>
|
<em>
|
||||||
*This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
||||||
</em>
|
</em>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -689,7 +689,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
|
|||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<em>
|
<em>
|
||||||
*This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
||||||
</em>
|
</em>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -150,7 +150,7 @@ exports[`SettingsUtils functions render 1`] = `
|
|||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<em>
|
<em>
|
||||||
*This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
|
||||||
</em>
|
</em>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { CostEstimateText } from ".";
|
import { CostEstimateText } from "./CostEstimateText";
|
||||||
const props = {
|
const props = {
|
||||||
requestUnits: 5,
|
requestUnits: 5,
|
||||||
isAutoscale: false,
|
isAutoscale: false,
|
||||||
@@ -1,8 +1,17 @@
|
|||||||
import { Text } from "office-ui-fabric-react";
|
import { Text } from "office-ui-fabric-react";
|
||||||
import React, { FunctionComponent } from "react";
|
import React, { FunctionComponent } from "react";
|
||||||
|
import { Tooltip } from "../../../../Common/Tooltip/Tooltip";
|
||||||
import * as SharedConstants from "../../../../Shared/Constants";
|
import * as SharedConstants from "../../../../Shared/Constants";
|
||||||
import { userContext } from "../../../../UserContext";
|
import { userContext } from "../../../../UserContext";
|
||||||
import * as PricingUtils from "../../../../Utils/PricingUtils";
|
import {
|
||||||
|
calculateEstimateNumber,
|
||||||
|
computeRUUsagePriceHourly,
|
||||||
|
getAutoscalePricePerRu,
|
||||||
|
getCurrencySign,
|
||||||
|
getMultimasterMultiplier,
|
||||||
|
getPriceCurrency,
|
||||||
|
getPricePerRu,
|
||||||
|
} from "../../../../Utils/PricingUtils";
|
||||||
|
|
||||||
interface CostEstimateTextProps {
|
interface CostEstimateTextProps {
|
||||||
requestUnits: number;
|
requestUnits: number;
|
||||||
@@ -13,15 +22,15 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
|||||||
requestUnits,
|
requestUnits,
|
||||||
isAutoscale,
|
isAutoscale,
|
||||||
}: CostEstimateTextProps) => {
|
}: CostEstimateTextProps) => {
|
||||||
const databaseAccount = userContext.databaseAccount;
|
const { databaseAccount } = userContext;
|
||||||
if (!databaseAccount || !databaseAccount.properties) {
|
if (!databaseAccount?.properties) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const serverId: string = userContext.portalEnv;
|
const serverId: string = userContext.portalEnv;
|
||||||
const numberOfRegions: number = databaseAccount.properties.readLocations?.length || 1;
|
const numberOfRegions: number = databaseAccount.properties.readLocations?.length || 1;
|
||||||
const multimasterEnabled: boolean = databaseAccount.properties.enableMultipleWriteLocations;
|
const multimasterEnabled: boolean = databaseAccount.properties.enableMultipleWriteLocations;
|
||||||
const hourlyPrice: number = PricingUtils.computeRUUsagePriceHourly({
|
const hourlyPrice: number = computeRUUsagePriceHourly({
|
||||||
serverId,
|
serverId,
|
||||||
requestUnits,
|
requestUnits,
|
||||||
numberOfRegions,
|
numberOfRegions,
|
||||||
@@ -30,20 +39,22 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
|||||||
});
|
});
|
||||||
const dailyPrice: number = hourlyPrice * 24;
|
const dailyPrice: number = hourlyPrice * 24;
|
||||||
const monthlyPrice: number = hourlyPrice * SharedConstants.hoursInAMonth;
|
const monthlyPrice: number = hourlyPrice * SharedConstants.hoursInAMonth;
|
||||||
const currency: string = PricingUtils.getPriceCurrency(serverId);
|
const currency: string = getPriceCurrency(serverId);
|
||||||
const currencySign: string = PricingUtils.getCurrencySign(serverId);
|
const currencySign: string = getCurrencySign(serverId);
|
||||||
const multiplier = PricingUtils.getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
const multiplier = getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
||||||
const pricePerRu = isAutoscale
|
const pricePerRu = isAutoscale
|
||||||
? PricingUtils.getAutoscalePricePerRu(serverId, multiplier) * multiplier
|
? getAutoscalePricePerRu(serverId, multiplier) * multiplier
|
||||||
: PricingUtils.getPricePerRu(serverId) * multiplier;
|
: getPricePerRu(serverId) * multiplier;
|
||||||
|
|
||||||
|
const iconWithEstimatedCostDisclaimer: JSX.Element = <Tooltip>PricingUtils.estimatedCostDisclaimer</Tooltip>;
|
||||||
|
|
||||||
if (isAutoscale) {
|
if (isAutoscale) {
|
||||||
return (
|
return (
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
Estimated monthly cost ({currency}):{" "}
|
Estimated monthly cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||||
<b>
|
<b>
|
||||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
{currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
||||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice)}{" "}
|
{currencySign + calculateEstimateNumber(monthlyPrice)}{" "}
|
||||||
</b>
|
</b>
|
||||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits / 10} - {requestUnits}{" "}
|
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits / 10} - {requestUnits}{" "}
|
||||||
RU/s, {currencySign + pricePerRu}/RU)
|
RU/s, {currencySign + pricePerRu}/RU)
|
||||||
@@ -53,16 +64,14 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
Cost ({currency}):{" "}
|
Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||||
<b>
|
<b>
|
||||||
{currencySign + PricingUtils.calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
{currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
||||||
{currencySign + PricingUtils.calculateEstimateNumber(dailyPrice)} daily /{" "}
|
{currencySign + calculateEstimateNumber(dailyPrice)} daily /{" "}
|
||||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
{currencySign + calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
||||||
</b>
|
</b>
|
||||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits}RU/s,{" "}
|
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits}RU/s,{" "}
|
||||||
{currencySign + pricePerRu}/RU)
|
{currencySign + pricePerRu}/RU)
|
||||||
<br />
|
|
||||||
<em>{PricingUtils.estimatedCostDisclaimer}</em>
|
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
padding: 0 @LargeSpace 0 @SmallSpace;
|
padding: 0 @LargeSpace 0 @SmallSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.throughputInputSpacing {
|
.throughputInputSpacing > :not(:last-child) {
|
||||||
margin-bottom: @SmallSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import { ThroughputInput } from "./ThroughputInput";
|
|||||||
const props = {
|
const props = {
|
||||||
isDatabase: false,
|
isDatabase: false,
|
||||||
showFreeTierExceedThroughputTooltip: true,
|
showFreeTierExceedThroughputTooltip: true,
|
||||||
|
isSharded: false,
|
||||||
setThroughputValue: () => jest.fn(),
|
setThroughputValue: () => jest.fn(),
|
||||||
setIsAutoscale: () => jest.fn(),
|
setIsAutoscale: () => jest.fn(),
|
||||||
onCostAcknowledgeChange: () => jest.fn(),
|
onCostAcknowledgeChange: () => jest.fn(),
|
||||||
@@ -22,7 +23,7 @@ describe("ThroughputInput Pane", () => {
|
|||||||
it("test Autoscale Mode select", () => {
|
it("test Autoscale Mode select", () => {
|
||||||
wrapper.setProps({ isAutoscaleSelected: true });
|
wrapper.setProps({ isAutoscaleSelected: true });
|
||||||
expect(wrapper.find('[data-testid="ruDescription"]').at(0).text()).toContain(
|
expect(wrapper.find('[data-testid="ruDescription"]').at(0).text()).toContain(
|
||||||
"Provision maximum RU/s required by this resource. Estimate your required RU/s with"
|
"Estimate your required RU/s with capacity calculator."
|
||||||
);
|
);
|
||||||
expect(wrapper.find('[data-testid="maxRUDescription"]').at(0).text()).toContain("Max RU/s");
|
expect(wrapper.find('[data-testid="maxRUDescription"]').at(0).text()).toContain("Max RU/s");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ import * as Constants from "../../../Common/Constants";
|
|||||||
import { Tooltip } from "../../../Common/Tooltip/Tooltip";
|
import { Tooltip } from "../../../Common/Tooltip/Tooltip";
|
||||||
import * as SharedConstants from "../../../Shared/Constants";
|
import * as SharedConstants from "../../../Shared/Constants";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
|
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
import * as PricingUtils from "../../../Utils/PricingUtils";
|
||||||
import { CostEstimateText } from "./CostEstimateText";
|
import { CostEstimateText } from "./CostEstimateText/CostEstimateText";
|
||||||
import "./styles.less";
|
import "./ThroughputInput.less";
|
||||||
|
|
||||||
export interface ThroughputInputProps {
|
export interface ThroughputInputProps {
|
||||||
isDatabase: boolean;
|
isDatabase: boolean;
|
||||||
|
isSharded: boolean;
|
||||||
showFreeTierExceedThroughputTooltip: boolean;
|
showFreeTierExceedThroughputTooltip: boolean;
|
||||||
setThroughputValue: (throughput: number) => void;
|
setThroughputValue: (throughput: number) => void;
|
||||||
setIsAutoscale: (isAutoscale: boolean) => void;
|
setIsAutoscale: (isAutoscale: boolean) => void;
|
||||||
@@ -34,32 +36,40 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
showFreeTierExceedThroughputTooltip,
|
showFreeTierExceedThroughputTooltip,
|
||||||
setThroughputValue,
|
setThroughputValue,
|
||||||
setIsAutoscale,
|
setIsAutoscale,
|
||||||
|
isSharded,
|
||||||
isAutoscaleSelected = true,
|
isAutoscaleSelected = true,
|
||||||
throughput = AutoPilotUtils.minAutoPilotThroughput,
|
throughput = AutoPilotUtils.minAutoPilotThroughput,
|
||||||
onCostAcknowledgeChange,
|
onCostAcknowledgeChange,
|
||||||
}: ThroughputInputProps) => {
|
}: ThroughputInputProps) => {
|
||||||
const [isCostAcknowledged, setIsCostAcknowledged] = useState<boolean>(false);
|
const [isCostAcknowledged, setIsCostAcknowledged] = useState<boolean>(false);
|
||||||
|
const [throughputError, setThroughputError] = useState<string>("");
|
||||||
const getThroughputLabelText = (): string => {
|
const getThroughputLabelText = (): string => {
|
||||||
|
let throughputHeaderText: string;
|
||||||
if (isAutoscaleSelected) {
|
if (isAutoscaleSelected) {
|
||||||
return AutoPilotUtils.getAutoPilotHeaderText();
|
throughputHeaderText = AutoPilotUtils.getAutoPilotHeaderText().toLocaleLowerCase();
|
||||||
}
|
} else {
|
||||||
const minRU: string = SharedConstants.CollectionCreation.DefaultCollectionRUs400.toLocaleString();
|
const minRU: string = SharedConstants.CollectionCreation.DefaultCollectionRUs400.toLocaleString();
|
||||||
const maxRU: string = userContext.isTryCosmosDBSubscription
|
const maxRU: string = userContext.isTryCosmosDBSubscription
|
||||||
? Constants.TryCosmosExperience.maxRU.toLocaleString()
|
? Constants.TryCosmosExperience.maxRU.toLocaleString()
|
||||||
: "unlimited";
|
: "unlimited";
|
||||||
return isAutoscaleSelected ? AutoPilotUtils.getAutoPilotHeaderText() : `Throughput (${minRU} - ${maxRU} RU/s)`;
|
throughputHeaderText = `throughput (${minRU} - ${maxRU} RU/s)`;
|
||||||
|
}
|
||||||
|
return `${isDatabase ? "Database" : getCollectionName()} ${throughputHeaderText}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onThroughputValueChange = (newInput: string): void => {
|
const onThroughputValueChange = (newInput: string): void => {
|
||||||
const newThroughput = parseInt(newInput);
|
const newThroughput = parseInt(newInput);
|
||||||
setThroughputValue(newThroughput);
|
setThroughputValue(newThroughput);
|
||||||
setIsAutoscale(isAutoscaleSelected);
|
if (!isSharded && newThroughput > 10000) {
|
||||||
|
setThroughputError("Unsharded collections support up to 10,000 RUs");
|
||||||
|
} else {
|
||||||
|
setThroughputError("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAutoScaleTooltip = (): string => {
|
const getAutoScaleTooltip = (): string => {
|
||||||
return `After the first ${AutoPilotUtils.getStorageBasedOnUserInput(throughput)} GB of data stored, the max
|
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||||
RU/s will be automatically upgraded based on the new storage value.`;
|
return `Set the max RU/s to the highest RU/s you want your ${collectionName} to scale to. The ${collectionName} will scale between 10% of max RU/s to the max RU/s based on usage.`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCostAcknowledgeText = (): string => {
|
const getCostAcknowledgeText = (): string => {
|
||||||
@@ -98,13 +108,13 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
<div className="throughputInputContainer throughputInputSpacing">
|
<div className="throughputInputContainer throughputInputSpacing">
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text variant="small" style={{ lineHeight: "20px" }}>
|
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}>
|
||||||
{getThroughputLabelText()}
|
{getThroughputLabelText()}
|
||||||
</Text>
|
</Text>
|
||||||
<Tooltip>{PricingUtils.getRuToolTipText()}</Tooltip>
|
<Tooltip>{PricingUtils.getRuToolTipText()}</Tooltip>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack>
|
<Stack horizontal verticalAlign="center">
|
||||||
<ChoiceGroup
|
<ChoiceGroup
|
||||||
selectedKey={"" + isAutoscaleSelected}
|
selectedKey={"" + isAutoscaleSelected}
|
||||||
options={optionList}
|
options={optionList}
|
||||||
@@ -116,7 +126,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
{isAutoscaleSelected && (
|
{isAutoscaleSelected && (
|
||||||
<Stack className="throughputInputSpacing">
|
<Stack className="throughputInputSpacing">
|
||||||
<Text variant="small" data-testid="ruDescription">
|
<Text variant="small" data-testid="ruDescription">
|
||||||
Provision maximum RU/s required by this resource. Estimate your required RU/s with
|
Estimate your required RU/s with
|
||||||
<Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/" data-testid="ruDescription">
|
<Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/" data-testid="ruDescription">
|
||||||
capacity calculator
|
capacity calculator
|
||||||
</Link>
|
</Link>
|
||||||
@@ -124,8 +134,8 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<Text variant="small" style={{ lineHeight: "20px" }} data-testid="maxRUDescription">
|
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }} data-testid="maxRUDescription">
|
||||||
Max RU/s
|
{isDatabase ? "Database" : getCollectionName()} Max RU/s
|
||||||
</Text>
|
</Text>
|
||||||
<Tooltip>{getAutoScaleTooltip()}</Tooltip>
|
<Tooltip>{getAutoScaleTooltip()}</Tooltip>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -142,10 +152,12 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
value={throughput.toString()}
|
value={throughput.toString()}
|
||||||
aria-label="Max request units per second"
|
aria-label="Max request units per second"
|
||||||
required={true}
|
required={true}
|
||||||
|
errorMessage={throughputError}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
Your {isDatabase ? "database" : "container"} throughput will automatically scale from{" "}
|
Your {isDatabase ? "database" : getCollectionName().toLocaleLowerCase()} throughput will automatically scale
|
||||||
|
from{" "}
|
||||||
<b>
|
<b>
|
||||||
{AutoPilotUtils.getMinRUsBasedOnUserInput(throughput)} RU/s (10% of max RU/s) - {throughput} RU/s
|
{AutoPilotUtils.getMinRUsBasedOnUserInput(throughput)} RU/s (10% of max RU/s) - {throughput} RU/s
|
||||||
</b>{" "}
|
</b>{" "}
|
||||||
@@ -186,6 +198,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
value={throughput.toString()}
|
value={throughput.toString()}
|
||||||
aria-label="Max request units per second"
|
aria-label="Max request units per second"
|
||||||
required={true}
|
required={true}
|
||||||
|
errorMessage={throughputError}
|
||||||
/>
|
/>
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
exports[`ThroughputInput Pane should render Default properly 1`] = `
|
exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||||
<ThroughputInput
|
<ThroughputInput
|
||||||
isDatabase={false}
|
isDatabase={false}
|
||||||
|
isSharded={false}
|
||||||
onCostAcknowledgeChange={[Function]}
|
onCostAcknowledgeChange={[Function]}
|
||||||
setIsAutoscale={[Function]}
|
setIsAutoscale={[Function]}
|
||||||
setThroughputValue={[Function]}
|
setThroughputValue={[Function]}
|
||||||
@@ -27,6 +28,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
key=".0:$.1"
|
key=".0:$.1"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
|
"fontWeight": 600,
|
||||||
"lineHeight": "20px",
|
"lineHeight": "20px",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,11 +38,12 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
className="css-41"
|
className="css-41"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
|
"fontWeight": 600,
|
||||||
"lineHeight": "20px",
|
"lineHeight": "20px",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Throughput (autoscale)
|
Container throughput (autoscale)
|
||||||
</span>
|
</span>
|
||||||
</Text>
|
</Text>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@@ -1423,7 +1426,10 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
verticalAlign="center"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-Stack css-51"
|
className="ms-Stack css-51"
|
||||||
>
|
>
|
||||||
@@ -2426,7 +2432,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
className="throughputInputSpacing"
|
className="throughputInputSpacing"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-Stack throughputInputSpacing css-51"
|
className="ms-Stack throughputInputSpacing css-63"
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
data-testid="ruDescription"
|
data-testid="ruDescription"
|
||||||
@@ -2437,7 +2443,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
className="css-41"
|
className="css-41"
|
||||||
data-testid="ruDescription"
|
data-testid="ruDescription"
|
||||||
>
|
>
|
||||||
Provision maximum RU/s required by this resource. Estimate your required RU/s with
|
Estimate your required RU/s with
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
data-testid="ruDescription"
|
data-testid="ruDescription"
|
||||||
href="https://cosmos.azure.com/capacitycalculator/"
|
href="https://cosmos.azure.com/capacitycalculator/"
|
||||||
@@ -2723,7 +2729,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
className="ms-Link root-63"
|
className="ms-Link root-64"
|
||||||
data-testid="ruDescription"
|
data-testid="ruDescription"
|
||||||
href="https://cosmos.azure.com/capacitycalculator/"
|
href="https://cosmos.azure.com/capacitycalculator/"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@@ -2748,6 +2754,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
key=".0:$.0"
|
key=".0:$.0"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
|
"fontWeight": 600,
|
||||||
"lineHeight": "20px",
|
"lineHeight": "20px",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2758,10 +2765,12 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
data-testid="maxRUDescription"
|
data-testid="maxRUDescription"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
|
"fontWeight": 600,
|
||||||
"lineHeight": "20px",
|
"lineHeight": "20px",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
Container
|
||||||
Max RU/s
|
Max RU/s
|
||||||
</span>
|
</span>
|
||||||
</Text>
|
</Text>
|
||||||
@@ -2775,8 +2784,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
"gapSpace": 0,
|
"gapSpace": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content="After the first 40 GB of data stored, the max
|
content="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage."
|
||||||
RU/s will be automatically upgraded based on the new storage value."
|
|
||||||
id="tooltip8"
|
id="tooltip8"
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
@@ -2792,8 +2800,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
"gapSpace": 0,
|
"gapSpace": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content="After the first 40 GB of data stored, the max
|
content="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage."
|
||||||
RU/s will be automatically upgraded based on the new storage value."
|
|
||||||
delay={1}
|
delay={1}
|
||||||
id="tooltip8"
|
id="tooltip8"
|
||||||
styles={[Function]}
|
styles={[Function]}
|
||||||
@@ -4149,6 +4156,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
</Stack>
|
</Stack>
|
||||||
<StyledTextFieldBase
|
<StyledTextFieldBase
|
||||||
aria-label="Max request units per second"
|
aria-label="Max request units per second"
|
||||||
|
errorMessage=""
|
||||||
key=".0:$.2"
|
key=".0:$.2"
|
||||||
min={4000}
|
min={4000}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@@ -4172,6 +4180,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
aria-label="Max request units per second"
|
aria-label="Max request units per second"
|
||||||
canRevealPassword={false}
|
canRevealPassword={false}
|
||||||
deferredValidationTime={200}
|
deferredValidationTime={200}
|
||||||
|
errorMessage=""
|
||||||
min={4000}
|
min={4000}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
required={true}
|
required={true}
|
||||||
@@ -4456,17 +4465,17 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
value="4000"
|
value="4000"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-TextField is-required root-65"
|
className="ms-TextField is-required root-66"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-TextField-wrapper"
|
className="ms-TextField-wrapper"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-TextField-fieldGroup fieldGroup-66"
|
className="ms-TextField-fieldGroup fieldGroup-67"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
aria-invalid={false}
|
aria-invalid={false}
|
||||||
className="ms-TextField-field field-67"
|
className="ms-TextField-field field-68"
|
||||||
id="TextField14"
|
id="TextField14"
|
||||||
min={4000}
|
min={4000}
|
||||||
onBlur={[Function]}
|
onBlur={[Function]}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import _ from "underscore";
|
|||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
||||||
import * as Constants from "../Common/Constants";
|
import * as Constants from "../Common/Constants";
|
||||||
import { ExplorerMetrics } from "../Common/Constants";
|
import { ExplorerMetrics, HttpStatusCodes } from "../Common/Constants";
|
||||||
import { readCollection } from "../Common/dataAccess/readCollection";
|
import { readCollection } from "../Common/dataAccess/readCollection";
|
||||||
import { readDatabases } from "../Common/dataAccess/readDatabases";
|
import { readDatabases } from "../Common/dataAccess/readDatabases";
|
||||||
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
||||||
@@ -19,7 +19,9 @@ import { configContext, Platform } from "../ConfigContext";
|
|||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as ViewModels from "../Contracts/ViewModels";
|
||||||
import { IGalleryItem } from "../Juno/JunoClient";
|
import { GitHubClient } from "../GitHub/GitHubClient";
|
||||||
|
import { GitHubOAuthService } from "../GitHub/GitHubOAuthService";
|
||||||
|
import { IGalleryItem, JunoClient } from "../Juno/JunoClient";
|
||||||
import { NotebookWorkspaceManager } from "../NotebookWorkspaceManager/NotebookWorkspaceManager";
|
import { NotebookWorkspaceManager } from "../NotebookWorkspaceManager/NotebookWorkspaceManager";
|
||||||
import { ResourceProviderClientFactory } from "../ResourceProvider/ResourceProviderClientFactory";
|
import { ResourceProviderClientFactory } from "../ResourceProvider/ResourceProviderClientFactory";
|
||||||
import { RouteHandler } from "../RouteHandlers/RouteHandler";
|
import { RouteHandler } from "../RouteHandlers/RouteHandler";
|
||||||
@@ -30,12 +32,12 @@ import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants"
|
|||||||
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { ArcadiaResourceManager } from "../SparkClusterManager/ArcadiaResourceManager";
|
import { ArcadiaResourceManager } from "../SparkClusterManager/ArcadiaResourceManager";
|
||||||
import { userContext } from "../UserContext";
|
import { userContext } from "../UserContext";
|
||||||
|
import { getCollectionName } from "../Utils/APITypeUtils";
|
||||||
import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||||
import { stringToBlob } from "../Utils/BlobUtils";
|
import { stringToBlob } from "../Utils/BlobUtils";
|
||||||
import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils";
|
import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils";
|
||||||
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
||||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils";
|
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils";
|
||||||
import * as PricingUtils from "../Utils/PricingUtils";
|
|
||||||
import * as ComponentRegisterer from "./ComponentRegisterer";
|
import * as ComponentRegisterer from "./ComponentRegisterer";
|
||||||
import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker";
|
import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker";
|
||||||
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
||||||
@@ -58,6 +60,7 @@ import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
|||||||
import { DeleteCollectionConfirmationPane } from "./Panes/DeleteCollectionConfirmationPane/DeleteCollectionConfirmationPane";
|
import { DeleteCollectionConfirmationPane } from "./Panes/DeleteCollectionConfirmationPane/DeleteCollectionConfirmationPane";
|
||||||
import { DeleteDatabaseConfirmationPanel } from "./Panes/DeleteDatabaseConfirmationPanel";
|
import { DeleteDatabaseConfirmationPanel } from "./Panes/DeleteDatabaseConfirmationPanel";
|
||||||
import { ExecuteSprocParamsPane } from "./Panes/ExecuteSprocParamsPane/ExecuteSprocParamsPane";
|
import { ExecuteSprocParamsPane } from "./Panes/ExecuteSprocParamsPane/ExecuteSprocParamsPane";
|
||||||
|
import { GitHubReposPanel } from "./Panes/GitHubReposPanel/GitHubReposPanel";
|
||||||
import GraphStylingPane from "./Panes/GraphStylingPane";
|
import GraphStylingPane from "./Panes/GraphStylingPane";
|
||||||
import { LoadQueryPane } from "./Panes/LoadQueryPane/LoadQueryPane";
|
import { LoadQueryPane } from "./Panes/LoadQueryPane/LoadQueryPane";
|
||||||
import { SaveQueryPane } from "./Panes/SaveQueryPane/SaveQueryPane";
|
import { SaveQueryPane } from "./Panes/SaveQueryPane/SaveQueryPane";
|
||||||
@@ -167,10 +170,11 @@ export default class Explorer {
|
|||||||
public addCollectionPane: AddCollectionPane;
|
public addCollectionPane: AddCollectionPane;
|
||||||
public graphStylingPane: GraphStylingPane;
|
public graphStylingPane: GraphStylingPane;
|
||||||
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
||||||
public gitHubReposPane: ContextualPaneBase;
|
private gitHubClient: GitHubClient;
|
||||||
|
public gitHubOAuthService: GitHubOAuthService;
|
||||||
|
public junoClient: JunoClient;
|
||||||
|
|
||||||
// features
|
// features
|
||||||
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
|
||||||
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
||||||
public isHostedDataExplorerEnabled: ko.Computed<boolean>;
|
public isHostedDataExplorerEnabled: ko.Computed<boolean>;
|
||||||
public isRightPanelV2Enabled: ko.Computed<boolean>;
|
public isRightPanelV2Enabled: ko.Computed<boolean>;
|
||||||
@@ -212,6 +216,8 @@ export default class Explorer {
|
|||||||
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
||||||
|
|
||||||
constructor(params?: ExplorerParams) {
|
constructor(params?: ExplorerParams) {
|
||||||
|
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
||||||
|
this.junoClient = new JunoClient();
|
||||||
this.setIsNotificationConsoleExpanded = params?.setIsNotificationConsoleExpanded;
|
this.setIsNotificationConsoleExpanded = params?.setIsNotificationConsoleExpanded;
|
||||||
this.setNotificationConsoleData = params?.setNotificationConsoleData;
|
this.setNotificationConsoleData = params?.setNotificationConsoleData;
|
||||||
this.setInProgressConsoleDataIdToBeDeleted = params?.setInProgressConsoleDataIdToBeDeleted;
|
this.setInProgressConsoleDataIdToBeDeleted = params?.setInProgressConsoleDataIdToBeDeleted;
|
||||||
@@ -318,7 +324,6 @@ export default class Explorer {
|
|||||||
this.resourceTokenCollectionId = ko.observable<string>();
|
this.resourceTokenCollectionId = ko.observable<string>();
|
||||||
this.resourceTokenCollection = ko.observable<ViewModels.CollectionBase>();
|
this.resourceTokenCollection = ko.observable<ViewModels.CollectionBase>();
|
||||||
this.resourceTokenPartitionKey = ko.observable<string>();
|
this.resourceTokenPartitionKey = ko.observable<string>();
|
||||||
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
|
||||||
this.isMongoIndexingEnabled = ko.observable<boolean>(false);
|
this.isMongoIndexingEnabled = ko.observable<boolean>(false);
|
||||||
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||||
|
|
||||||
@@ -598,9 +603,6 @@ export default class Explorer {
|
|||||||
refreshCommandBarButtons: () => this.refreshCommandBarButtons(),
|
refreshCommandBarButtons: () => this.refreshCommandBarButtons(),
|
||||||
refreshNotebookList: () => this.refreshNotebookList(),
|
refreshNotebookList: () => this.refreshNotebookList(),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.gitHubReposPane = this.notebookManager.gitHubReposPane;
|
|
||||||
this.isGitHubPaneEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refreshCommandBarButtons();
|
this.refreshCommandBarButtons();
|
||||||
@@ -648,6 +650,23 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onGitHubClientError = (error: any): void => {
|
||||||
|
Logger.logError(getErrorMessage(error), "NotebookManager/onGitHubClientError");
|
||||||
|
|
||||||
|
if (error.status === HttpStatusCodes.Unauthorized) {
|
||||||
|
this.gitHubOAuthService.resetToken();
|
||||||
|
|
||||||
|
this.showOkCancelModalDialog(
|
||||||
|
undefined,
|
||||||
|
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||||
|
"Connect to GitHub",
|
||||||
|
() => this.openGitHubReposPanel("Connect to GitHub"),
|
||||||
|
"Cancel",
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public openEnableSynapseLinkDialog(): void {
|
public openEnableSynapseLinkDialog(): void {
|
||||||
const addSynapseLinkDialogProps: DialogProps = {
|
const addSynapseLinkDialogProps: DialogProps = {
|
||||||
linkProps: {
|
linkProps: {
|
||||||
@@ -1951,14 +1970,14 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public onNewCollectionClicked(): void {
|
public onNewCollectionClicked(databaseId?: string): void {
|
||||||
if (userContext.apiType === "Cassandra") {
|
if (userContext.apiType === "Cassandra") {
|
||||||
this.cassandraAddCollectionPane.open();
|
this.cassandraAddCollectionPane.open();
|
||||||
} else if (userContext.features.enableReactPane) {
|
} else if (userContext.features.enableKOPanel) {
|
||||||
this.openAddCollectionPanel();
|
|
||||||
} else {
|
|
||||||
this.addCollectionPane.open(this.selectedDatabaseId());
|
this.addCollectionPane.open(this.selectedDatabaseId());
|
||||||
document.getElementById("linkAddCollection").focus();
|
document.getElementById("linkAddCollection").focus();
|
||||||
|
} else {
|
||||||
|
this.openAddCollectionPanel(databaseId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2062,14 +2081,9 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public openDeleteCollectionConfirmationPane(): void {
|
public openDeleteCollectionConfirmationPane(): void {
|
||||||
let collectionName = PricingUtils.getCollectionName(userContext.apiType);
|
|
||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"Delete " + collectionName,
|
"Delete " + getCollectionName(),
|
||||||
<DeleteCollectionConfirmationPane
|
<DeleteCollectionConfirmationPane explorer={this} closePanel={this.closeSidePanel} />
|
||||||
explorer={this}
|
|
||||||
collectionName={collectionName}
|
|
||||||
closePanel={this.closeSidePanel}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2090,28 +2104,32 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public openSettingPane(): void {
|
public openSettingPane(): void {
|
||||||
this.openSidePanel("Settings", <SettingsPane explorer={this} closePanel={this.closeSidePanel} />);
|
this.openSidePanel(
|
||||||
|
"Settings",
|
||||||
|
<SettingsPane expandConsole={() => this.expandConsole()} closePanel={this.closeSidePanel} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public openExecuteSprocParamsPanel(storedProcedure: StoredProcedure): void {
|
public openExecuteSprocParamsPanel(storedProcedure: StoredProcedure): void {
|
||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"Input parameters",
|
"Input parameters",
|
||||||
<ExecuteSprocParamsPane
|
<ExecuteSprocParamsPane
|
||||||
explorer={this}
|
|
||||||
storedProcedure={storedProcedure}
|
storedProcedure={storedProcedure}
|
||||||
|
expandConsole={() => this.expandConsole()}
|
||||||
closePanel={() => this.closeSidePanel()}
|
closePanel={() => this.closeSidePanel()}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openAddCollectionPanel(): Promise<void> {
|
public async openAddCollectionPanel(databaseId?: string): Promise<void> {
|
||||||
await this.loadDatabaseOffers();
|
await this.loadDatabaseOffers();
|
||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"New Collection",
|
"New " + getCollectionName(),
|
||||||
<AddCollectionPanel
|
<AddCollectionPanel
|
||||||
explorer={this}
|
explorer={this}
|
||||||
closePanel={() => this.closeSidePanel()}
|
closePanel={() => this.closeSidePanel()}
|
||||||
openNotificationConsole={() => this.expandConsole()}
|
openNotificationConsole={() => this.expandConsole()}
|
||||||
|
databaseId={databaseId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2148,13 +2166,26 @@ export default class Explorer {
|
|||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"Upload File",
|
"Upload File",
|
||||||
<UploadFilePane
|
<UploadFilePane
|
||||||
explorer={this}
|
expandConsole={() => this.expandConsole()}
|
||||||
closePanel={this.closeSidePanel}
|
closePanel={this.closeSidePanel}
|
||||||
uploadFile={(name: string, content: string) => this.uploadFile(name, content, parent)}
|
uploadFile={(name: string, content: string) => this.uploadFile(name, content, parent)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public openGitHubReposPanel(header: string, junoClient?: JunoClient): void {
|
||||||
|
this.openSidePanel(
|
||||||
|
header,
|
||||||
|
<GitHubReposPanel
|
||||||
|
explorer={this}
|
||||||
|
closePanel={this.closeSidePanel}
|
||||||
|
gitHubClientProp={this.notebookManager.gitHubClient}
|
||||||
|
junoClientProp={junoClient}
|
||||||
|
openNotificationConsole={() => this.expandConsole()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public openAddTableEntityPanel(queryTablesTab: QueryTablesTab, tableEntityListViewModel: TableListViewModal): void {
|
public openAddTableEntityPanel(queryTablesTab: QueryTablesTab, tableEntityListViewModel: TableListViewModal): void {
|
||||||
this.openSidePanel(
|
this.openSidePanel(
|
||||||
"Add Table Entity",
|
"Add Table Entity",
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
|
||||||
import { GraphConfig } from "../../Tabs/GraphTab";
|
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
|
||||||
import { GraphExplorer, GraphAccessor } from "./GraphExplorer";
|
|
||||||
|
|
||||||
interface Parameter {
|
|
||||||
onIsNewVertexDisabledChange: (isEnabled: boolean) => void;
|
|
||||||
onGraphAccessorCreated: (instance: GraphAccessor) => void;
|
|
||||||
onIsFilterQueryLoading: (isFilterQueryLoading: boolean) => void;
|
|
||||||
onIsValidQuery: (isValidQuery: boolean) => void;
|
|
||||||
onIsPropertyEditing: (isEditing: boolean) => void;
|
|
||||||
onIsGraphDisplayed: (isDisplayed: boolean) => void;
|
|
||||||
onResetDefaultGraphConfigValues: () => void;
|
|
||||||
|
|
||||||
graphConfigUiData: ViewModels.GraphConfigUiData;
|
|
||||||
graphConfig?: GraphConfig;
|
|
||||||
|
|
||||||
collectionPartitionKeyProperty: string;
|
|
||||||
graphBackendEndpoint: string;
|
|
||||||
databaseId: string;
|
|
||||||
collectionId: string;
|
|
||||||
masterKey: string;
|
|
||||||
|
|
||||||
onLoadStartKey: number;
|
|
||||||
onLoadStartKeyChange: (newKey: number) => void;
|
|
||||||
resourceId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GraphExplorerAdapter implements ReactAdapter {
|
|
||||||
public params: Parameter;
|
|
||||||
public parameters = {};
|
|
||||||
public isNewVertexDisabled: boolean;
|
|
||||||
|
|
||||||
public constructor(params: Parameter) {
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public renderComponent(): JSX.Element {
|
|
||||||
return (
|
|
||||||
<GraphExplorer
|
|
||||||
onIsNewVertexDisabledChange={this.params.onIsNewVertexDisabledChange}
|
|
||||||
onGraphAccessorCreated={this.params.onGraphAccessorCreated}
|
|
||||||
onIsFilterQueryLoadingChange={this.params.onIsFilterQueryLoading}
|
|
||||||
onIsValidQueryChange={this.params.onIsValidQuery}
|
|
||||||
onIsPropertyEditing={this.params.onIsPropertyEditing}
|
|
||||||
onIsGraphDisplayed={this.params.onIsGraphDisplayed}
|
|
||||||
onResetDefaultGraphConfigValues={this.params.onResetDefaultGraphConfigValues}
|
|
||||||
collectionPartitionKeyProperty={this.params.collectionPartitionKeyProperty}
|
|
||||||
graphBackendEndpoint={this.params.graphBackendEndpoint}
|
|
||||||
databaseId={this.params.databaseId}
|
|
||||||
collectionId={this.params.collectionId}
|
|
||||||
masterKey={this.params.masterKey}
|
|
||||||
onLoadStartKey={this.params.onLoadStartKey}
|
|
||||||
onLoadStartKeyChange={this.params.onLoadStartKeyChange}
|
|
||||||
resourceId={this.params.resourceId}
|
|
||||||
/* TODO Figure out how to make this Knockout-free */
|
|
||||||
graphConfigUiData={this.params.graphConfigUiData}
|
|
||||||
graphConfig={this.params.graphConfig}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,11 +19,8 @@ import SettingsIcon from "../../../../images/settings_15x15.svg";
|
|||||||
import SynapseIcon from "../../../../images/synapse-link.svg";
|
import SynapseIcon from "../../../../images/synapse-link.svg";
|
||||||
import { AuthType } from "../../../AuthType";
|
import { AuthType } from "../../../AuthType";
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import { Areas } from "../../../Common/Constants";
|
|
||||||
import { configContext, Platform } from "../../../ConfigContext";
|
import { configContext, Platform } from "../../../ConfigContext";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
|
||||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
@@ -537,14 +534,7 @@ function createManageGitHubAccountButton(container: Explorer): CommandButtonComp
|
|||||||
return {
|
return {
|
||||||
iconSrc: GitHubIcon,
|
iconSrc: GitHubIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => container.openGitHubReposPanel(label),
|
||||||
if (!connectedToGitHub) {
|
|
||||||
TelemetryProcessor.trace(Action.NotebooksGitHubConnect, ActionModifiers.Mark, {
|
|
||||||
dataExplorerArea: Areas.Notebook,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
container.gitHubReposPane.open();
|
|
||||||
},
|
|
||||||
commandButtonLabel: label,
|
commandButtonLabel: label,
|
||||||
hasPopup: false,
|
hasPopup: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { getFullName } from "../../Utils/UserUtils";
|
|||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||||
import { CopyNotebookPane } from "../Panes/CopyNotebookPane/CopyNotebookPane";
|
import { CopyNotebookPane } from "../Panes/CopyNotebookPane/CopyNotebookPane";
|
||||||
import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
// import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
||||||
import { PublishNotebookPane } from "../Panes/PublishNotebookPane/PublishNotebookPane";
|
import { PublishNotebookPane } from "../Panes/PublishNotebookPane/PublishNotebookPane";
|
||||||
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
||||||
import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProvider";
|
import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProvider";
|
||||||
@@ -50,7 +50,7 @@ export default class NotebookManager {
|
|||||||
|
|
||||||
private gitHubContentProvider: GitHubContentProvider;
|
private gitHubContentProvider: GitHubContentProvider;
|
||||||
public gitHubOAuthService: GitHubOAuthService;
|
public gitHubOAuthService: GitHubOAuthService;
|
||||||
private gitHubClient: GitHubClient;
|
public gitHubClient: GitHubClient;
|
||||||
|
|
||||||
public gitHubReposPane: ContextualPaneBase;
|
public gitHubReposPane: ContextualPaneBase;
|
||||||
|
|
||||||
@@ -60,13 +60,6 @@ export default class NotebookManager {
|
|||||||
|
|
||||||
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
|
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
|
||||||
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
||||||
this.gitHubReposPane = new GitHubReposPane({
|
|
||||||
id: "gitHubReposPane",
|
|
||||||
visible: ko.observable<boolean>(false),
|
|
||||||
container: this.params.container,
|
|
||||||
junoClient: this.junoClient,
|
|
||||||
gitHubClient: this.gitHubClient,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.gitHubContentProvider = new GitHubContentProvider({
|
this.gitHubContentProvider = new GitHubContentProvider({
|
||||||
gitHubClient: this.gitHubClient,
|
gitHubClient: this.gitHubClient,
|
||||||
@@ -92,9 +85,9 @@ export default class NotebookManager {
|
|||||||
|
|
||||||
this.gitHubOAuthService.getTokenObservable().subscribe((token) => {
|
this.gitHubOAuthService.getTokenObservable().subscribe((token) => {
|
||||||
this.gitHubClient.setToken(token?.access_token);
|
this.gitHubClient.setToken(token?.access_token);
|
||||||
|
if (this?.gitHubOAuthService.isLoggedIn()) {
|
||||||
if (this.gitHubReposPane.visible()) {
|
this.params.container.closeSidePanel();
|
||||||
this.gitHubReposPane.open();
|
this.params.container.openGitHubReposPanel("Manager GitHub settings", this.junoClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.params.refreshCommandBarButtons();
|
this.params.refreshCommandBarButtons();
|
||||||
@@ -163,7 +156,7 @@ export default class NotebookManager {
|
|||||||
undefined,
|
undefined,
|
||||||
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||||
"Connect to GitHub",
|
"Connect to GitHub",
|
||||||
() => this.gitHubReposPane.open(),
|
() => this.params.container.openGitHubReposPanel("Connect to GitHub"),
|
||||||
"Cancel",
|
"Cancel",
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { ActionContracts } from "../Contracts/ExplorerContracts";
|
|||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as ViewModels from "../Contracts/ViewModels";
|
||||||
import Explorer from "./Explorer";
|
import Explorer from "./Explorer";
|
||||||
import { handleOpenAction } from "./OpenActions";
|
import { handleOpenAction } from "./OpenActions";
|
||||||
import AddCollectionPane from "./Panes/AddCollectionPane";
|
|
||||||
import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
|
import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
|
||||||
|
|
||||||
describe("OpenActions", () => {
|
describe("OpenActions", () => {
|
||||||
@@ -15,8 +14,7 @@ describe("OpenActions", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
explorer = {} as Explorer;
|
explorer = {} as Explorer;
|
||||||
explorer.addCollectionPane = {} as AddCollectionPane;
|
explorer.onNewCollectionClicked = jest.fn();
|
||||||
explorer.addCollectionPane.open = jest.fn();
|
|
||||||
explorer.cassandraAddCollectionPane = {} as CassandraAddCollectionPane;
|
explorer.cassandraAddCollectionPane = {} as CassandraAddCollectionPane;
|
||||||
explorer.cassandraAddCollectionPane.open = jest.fn();
|
explorer.cassandraAddCollectionPane.open = jest.fn();
|
||||||
explorer.closeAllPanes = () => {};
|
explorer.closeAllPanes = () => {};
|
||||||
@@ -90,24 +88,24 @@ describe("OpenActions", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("AddCollection pane kind", () => {
|
describe("AddCollection pane kind", () => {
|
||||||
it("string value should call addCollectionPane.open", () => {
|
it("string value should call explorer.onNewCollectionClicked", () => {
|
||||||
const action = {
|
const action = {
|
||||||
actionType: "OpenPane",
|
actionType: "OpenPane",
|
||||||
paneKind: "AddCollection",
|
paneKind: "AddCollection",
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionHandled = handleOpenAction(action, [], explorer);
|
const actionHandled = handleOpenAction(action, [], explorer);
|
||||||
expect(explorer.addCollectionPane.open).toHaveBeenCalled();
|
expect(explorer.onNewCollectionClicked).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("enum value should call addCollectionPane.open", () => {
|
it("enum value should call explorer.onNewCollectionClicked", () => {
|
||||||
const action = {
|
const action = {
|
||||||
actionType: "OpenPane",
|
actionType: "OpenPane",
|
||||||
paneKind: ActionContracts.PaneKind.AddCollection,
|
paneKind: ActionContracts.PaneKind.AddCollection,
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionHandled = handleOpenAction(action, [], explorer);
|
const actionHandled = handleOpenAction(action, [], explorer);
|
||||||
expect(explorer.addCollectionPane.open).toHaveBeenCalled();
|
expect(explorer.onNewCollectionClicked).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
|
|||||||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AddCollection]
|
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AddCollection]
|
||||||
) {
|
) {
|
||||||
explorer.closeAllPanes();
|
explorer.closeAllPanes();
|
||||||
explorer.addCollectionPane.open();
|
explorer.onNewCollectionClicked();
|
||||||
} else if (
|
} else if (
|
||||||
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
||||||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
||||||
|
|||||||
@@ -143,7 +143,6 @@
|
|||||||
size="40"
|
size="40"
|
||||||
class="collid"
|
class="collid"
|
||||||
data-bind="visible: databaseCreateNew, textInput: databaseId, hasFocus: firstFieldHasFocus"
|
data-bind="visible: databaseCreateNew, textInput: databaseId, hasFocus: firstFieldHasFocus"
|
||||||
aria-label="Database id"
|
|
||||||
autofocus
|
autofocus
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -161,7 +160,6 @@
|
|||||||
size="40"
|
size="40"
|
||||||
class="collid"
|
class="collid"
|
||||||
data-bind="visible: !databaseCreateNew(), textInput: databaseId, hasFocus: firstFieldHasFocus"
|
data-bind="visible: !databaseCreateNew(), textInput: databaseId, hasFocus: firstFieldHasFocus"
|
||||||
aria-label="Database id"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<datalist id="databasesList" data-bind="foreach: databaseIds" data-bind="visible: databaseCreateNew">
|
<datalist id="databasesList" data-bind="foreach: databaseIds" data-bind="visible: databaseCreateNew">
|
||||||
@@ -246,7 +244,7 @@
|
|||||||
placeholder="e.g., Container1"
|
placeholder="e.g., Container1"
|
||||||
size="40"
|
size="40"
|
||||||
class="textfontclr collid"
|
class="textfontclr collid"
|
||||||
data-bind="value: collectionId, attr: { 'aria-label': collectionIdTitle }"
|
data-bind="value: collectionId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -352,7 +350,6 @@
|
|||||||
attr: {
|
attr: {
|
||||||
placeholder: partitionKeyPlaceholder,
|
placeholder: partitionKeyPlaceholder,
|
||||||
required: partitionKeyVisible(),
|
required: partitionKeyVisible(),
|
||||||
'aria-label': partitionKeyName,
|
|
||||||
pattern: partitionKeyPattern,
|
pattern: partitionKeyPattern,
|
||||||
title: partitionKeyTitle
|
title: partitionKeyTitle
|
||||||
}"
|
}"
|
||||||
|
|||||||
@@ -476,7 +476,6 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
userContext.portalEnv,
|
userContext.portalEnv,
|
||||||
this.isFreeTierAccount(),
|
this.isFreeTierAccount(),
|
||||||
this.container.isFirstResourceCreated(),
|
this.container.isFirstResourceCreated(),
|
||||||
userContext.apiType,
|
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
IDropdownOption,
|
IDropdownOption,
|
||||||
Link,
|
Link,
|
||||||
|
Separator,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
TooltipHost,
|
TooltipHost,
|
||||||
@@ -23,6 +24,7 @@ import { CollectionCreation, IndexingPolicies } from "../../Shared/Constants";
|
|||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
|
import { getCollectionName } from "../../Utils/APITypeUtils";
|
||||||
import { getUpsellMessage } from "../../Utils/PricingUtils";
|
import { getUpsellMessage } from "../../Utils/PricingUtils";
|
||||||
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||||
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
||||||
@@ -35,6 +37,7 @@ export interface AddCollectionPanelProps {
|
|||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
closePanel: () => void;
|
closePanel: () => void;
|
||||||
openNotificationConsole: () => void;
|
openNotificationConsole: () => void;
|
||||||
|
databaseId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddCollectionPanelState {
|
export interface AddCollectionPanelState {
|
||||||
@@ -48,7 +51,7 @@ export interface AddCollectionPanelState {
|
|||||||
partitionKey: string;
|
partitionKey: string;
|
||||||
enableDedicatedThroughput: boolean;
|
enableDedicatedThroughput: boolean;
|
||||||
createMongoWildCardIndex: boolean;
|
createMongoWildCardIndex: boolean;
|
||||||
useHashV1: boolean;
|
useHashV2: boolean;
|
||||||
enableAnalyticalStore: boolean;
|
enableAnalyticalStore: boolean;
|
||||||
uniqueKeys: string[];
|
uniqueKeys: string[];
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
@@ -67,17 +70,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
createNewDatabase: userContext.apiType !== "Tables",
|
createNewDatabase: userContext.apiType !== "Tables" && !this.props.databaseId,
|
||||||
newDatabaseId: "",
|
newDatabaseId: "",
|
||||||
isSharedThroughputChecked: this.getSharedThroughputDefault(),
|
isSharedThroughputChecked: this.getSharedThroughputDefault(),
|
||||||
selectedDatabaseId: userContext.apiType === "Tables" ? CollectionCreation.TablesAPIDefaultDatabase : undefined,
|
selectedDatabaseId:
|
||||||
|
userContext.apiType === "Tables" ? CollectionCreation.TablesAPIDefaultDatabase : this.props.databaseId,
|
||||||
collectionId: "",
|
collectionId: "",
|
||||||
enableIndexing: true,
|
enableIndexing: true,
|
||||||
isSharded: userContext.apiType !== "Tables",
|
isSharded: userContext.apiType !== "Tables",
|
||||||
partitionKey: "",
|
partitionKey: "",
|
||||||
enableDedicatedThroughput: false,
|
enableDedicatedThroughput: false,
|
||||||
createMongoWildCardIndex: true,
|
createMongoWildCardIndex: true,
|
||||||
useHashV1: false,
|
useHashV2: false,
|
||||||
enableAnalyticalStore: false,
|
enableAnalyticalStore: false,
|
||||||
uniqueKeys: [],
|
uniqueKeys: [],
|
||||||
errorMessage: "",
|
errorMessage: "",
|
||||||
@@ -100,13 +104,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
|
|
||||||
{!this.state.errorMessage && this.isFreeTierAccount() && (
|
{!this.state.errorMessage && this.isFreeTierAccount() && (
|
||||||
<PanelInfoErrorComponent
|
<PanelInfoErrorComponent
|
||||||
message={getUpsellMessage(
|
message={getUpsellMessage(userContext.portalEnv, true, this.props.explorer.isFirstResourceCreated(), true)}
|
||||||
userContext.portalEnv,
|
|
||||||
true,
|
|
||||||
this.props.explorer.isFirstResourceCreated(),
|
|
||||||
userContext.apiType,
|
|
||||||
true
|
|
||||||
)}
|
|
||||||
messageType="info"
|
messageType="info"
|
||||||
showErrorDetails={false}
|
showErrorDetails={false}
|
||||||
openNotificationConsole={this.props.openNotificationConsole}
|
openNotificationConsole={this.props.openNotificationConsole}
|
||||||
@@ -120,13 +118,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
Database id
|
Database {userContext.apiType === "Mongo" ? "name" : "id"}
|
||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="A database is analogous to a namespace. It is the unit of management for a set of containers."
|
content={`A database is analogous to a namespace. It is the unit of management for a set of ${getCollectionName(
|
||||||
|
true
|
||||||
|
).toLocaleLowerCase()}.`}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -140,7 +140,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
type="radio"
|
type="radio"
|
||||||
role="radio"
|
role="radio"
|
||||||
id="databaseCreateNew"
|
id="databaseCreateNew"
|
||||||
data-test="addCollection-createNewDatabase"
|
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onChange={this.onCreateNewDatabaseRadioBtnChange.bind(this)}
|
onChange={this.onCreateNewDatabaseRadioBtnChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
@@ -154,8 +153,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
name="databaseType"
|
name="databaseType"
|
||||||
type="radio"
|
type="radio"
|
||||||
role="radio"
|
role="radio"
|
||||||
id="databaseUseExisting"
|
|
||||||
data-test="addCollection-existingDatabase"
|
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onChange={this.onUseExistingDatabaseRadioBtnChange.bind(this)}
|
onChange={this.onUseExistingDatabaseRadioBtnChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
@@ -166,8 +163,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
<Stack className="panelGroupSpacing">
|
<Stack className="panelGroupSpacing">
|
||||||
<input
|
<input
|
||||||
name="newDatabaseId"
|
name="newDatabaseId"
|
||||||
id="databaseId"
|
id="newDatabaseId"
|
||||||
data-test="addCollection-newDatabaseId"
|
|
||||||
aria-required
|
aria-required
|
||||||
required
|
required
|
||||||
type="text"
|
type="text"
|
||||||
@@ -177,7 +173,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
placeholder="Type a new database id"
|
placeholder="Type a new database id"
|
||||||
size={40}
|
size={40}
|
||||||
className="panelTextField"
|
className="panelTextField"
|
||||||
aria-label="Database id"
|
aria-label="New database id"
|
||||||
autoFocus
|
autoFocus
|
||||||
value={this.state.newDatabaseId}
|
value={this.state.newDatabaseId}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
@@ -188,7 +184,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
{!this.isServerlessAccount() && (
|
{!this.isServerlessAccount() && (
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label="Provision database throughput"
|
label={`Share throughput across ${getCollectionName(true).toLocaleLowerCase()}`}
|
||||||
checked={this.state.isSharedThroughputChecked}
|
checked={this.state.isSharedThroughputChecked}
|
||||||
styles={{
|
styles={{
|
||||||
text: { fontSize: 12 },
|
text: { fontSize: 12 },
|
||||||
@@ -201,9 +197,11 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
/>
|
/>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="Provisioned throughput at the database level will be shared across all containers within the database."
|
content={`Throughput configured at the database level will be shared across all ${getCollectionName(
|
||||||
|
true
|
||||||
|
).toLocaleLowerCase()} within the database.`}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
@@ -216,6 +214,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
isDatabase={true}
|
isDatabase={true}
|
||||||
isAutoscaleSelected={this.isNewDatabaseAutoscale}
|
isAutoscaleSelected={this.isNewDatabaseAutoscale}
|
||||||
throughput={this.newDatabaseThroughput}
|
throughput={this.newDatabaseThroughput}
|
||||||
|
isSharded={this.state.isSharded}
|
||||||
setThroughputValue={(throughput: number) => (this.newDatabaseThroughput = throughput)}
|
setThroughputValue={(throughput: number) => (this.newDatabaseThroughput = throughput)}
|
||||||
setIsAutoscale={(isAutoscale: boolean) => (this.isNewDatabaseAutoscale = isAutoscale)}
|
setIsAutoscale={(isAutoscale: boolean) => (this.isNewDatabaseAutoscale = isAutoscale)}
|
||||||
onCostAcknowledgeChange={(isAcknowledge: boolean) => (this.isCostAcknowledged = isAcknowledge)}
|
onCostAcknowledgeChange={(isAcknowledge: boolean) => (this.isCostAcknowledged = isAcknowledge)}
|
||||||
@@ -232,38 +231,40 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
onChange={(event: React.FormEvent<HTMLDivElement>, database: IDropdownOption) =>
|
onChange={(event: React.FormEvent<HTMLDivElement>, database: IDropdownOption) =>
|
||||||
this.setState({ selectedDatabaseId: database.key as string })
|
this.setState({ selectedDatabaseId: database.key as string })
|
||||||
}
|
}
|
||||||
|
defaultSelectedKey={this.props.databaseId}
|
||||||
|
responsiveMode={999}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Separator className="panelSeparator" />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
{`${this.getCollectionName()} id`}
|
{`${getCollectionName()} ${userContext.apiType === "Mongo" ? "name" : "id"}`}
|
||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="Unique identifier for the container and used for id-based routing through REST and all SDKs."
|
content={`Unique identifier for the ${getCollectionName().toLocaleLowerCase()} and used for id-based routing through REST and all SDKs.`}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
name="collectionId"
|
name="collectionId"
|
||||||
id="containerId"
|
id="collectionId"
|
||||||
data-test="addCollection-collectionId"
|
|
||||||
type="text"
|
type="text"
|
||||||
aria-required
|
aria-required
|
||||||
required
|
required
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
pattern="[^/?#\\]*[^/?# \\]"
|
pattern="[^/?#\\]*[^/?# \\]"
|
||||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
||||||
placeholder={`e.g., ${this.getCollectionName()}1`}
|
placeholder={`e.g., ${getCollectionName()}1`}
|
||||||
size={40}
|
size={40}
|
||||||
className="panelTextField"
|
className="panelTextField"
|
||||||
aria-label={`${this.getCollectionName()} id`}
|
aria-label={`${getCollectionName()} id`}
|
||||||
value={this.state.collectionId}
|
value={this.state.collectionId}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
this.setState({ collectionId: event.target.value })
|
this.setState({ collectionId: event.target.value })
|
||||||
@@ -322,13 +323,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
Sharding options
|
Sharding
|
||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="Unique identifier for the container and used for id-based routing through REST and all SDKs."
|
content={
|
||||||
|
"Sharded collections split your data across many replica sets (shards) to achieve unlimited scalability. Sharded collections require choosing a shard key (field) to evenly distribute your data."
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -373,18 +376,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content={`The ${this.getPartitionKeyName()} is used to automatically partition data among
|
content={this.getPartitionKeyTooltipText()}
|
||||||
multiple servers for scalability. Choose a JSON property name that has a wide range of values and is
|
|
||||||
likely to have evenly distributed access patterns.`}
|
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="addCollection-partitionKeyValue"
|
id="addCollection-partitionKeyValue"
|
||||||
data-test="addCollection-partitionKeyValue"
|
|
||||||
aria-required
|
aria-required
|
||||||
required
|
required
|
||||||
size={40}
|
size={40}
|
||||||
@@ -394,9 +394,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
pattern={userContext.apiType === "Gremlin" ? "^/[^/]*" : ".*"}
|
pattern={userContext.apiType === "Gremlin" ? "^/[^/]*" : ".*"}
|
||||||
title={userContext.apiType === "Gremlin" ? "May not use composite partition key" : ""}
|
title={userContext.apiType === "Gremlin" ? "May not use composite partition key" : ""}
|
||||||
value={this.state.partitionKey}
|
value={this.state.partitionKey}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ partitionKey: event.target.value })
|
if (
|
||||||
|
userContext.apiType !== "Mongo" &&
|
||||||
|
this.state.partitionKey === "" &&
|
||||||
|
!event.target.value.startsWith("/")
|
||||||
|
) {
|
||||||
|
this.setState({ partitionKey: "/" + event.target.value });
|
||||||
|
} else {
|
||||||
|
this.setState({ partitionKey: event.target.value });
|
||||||
}
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
@@ -404,7 +412,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
{!this.isServerlessAccount() && !this.state.createNewDatabase && this.isSelectedDatabaseSharedThroughput() && (
|
{!this.isServerlessAccount() && !this.state.createNewDatabase && this.isSelectedDatabaseSharedThroughput() && (
|
||||||
<Stack horizontal verticalAlign="center">
|
<Stack horizontal verticalAlign="center">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={`Provision dedicated throughput for this ${this.getCollectionName()}`}
|
label={`Provision dedicated throughput for this ${getCollectionName().toLocaleLowerCase()}`}
|
||||||
checked={this.state.enableDedicatedThroughput}
|
checked={this.state.enableDedicatedThroughput}
|
||||||
styles={{
|
styles={{
|
||||||
text: { fontSize: 12 },
|
text: { fontSize: 12 },
|
||||||
@@ -417,12 +425,14 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
/>
|
/>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="You can optionally provision dedicated throughput for a container within a database that has throughput
|
content={`You can optionally provision dedicated throughput for a ${getCollectionName().toLocaleLowerCase()} within a database that has throughput
|
||||||
provisioned. This dedicated throughput amount will not be shared with other containers in the database and
|
provisioned. This dedicated throughput amount will not be shared with other ${getCollectionName(
|
||||||
|
true
|
||||||
|
).toLocaleLowerCase()} in the database and
|
||||||
does not count towards the throughput you provisioned for the database. This throughput amount will be
|
does not count towards the throughput you provisioned for the database. This throughput amount will be
|
||||||
billed in addition to the throughput amount you provisioned at the database level."
|
billed in addition to the throughput amount you provisioned at the database level.`}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
@@ -435,6 +445,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
isDatabase={false}
|
isDatabase={false}
|
||||||
isAutoscaleSelected={this.isCollectionAutoscale}
|
isAutoscaleSelected={this.isCollectionAutoscale}
|
||||||
throughput={this.collectionThroughput}
|
throughput={this.collectionThroughput}
|
||||||
|
isSharded={this.state.isSharded}
|
||||||
setThroughputValue={(throughput: number) => (this.collectionThroughput = throughput)}
|
setThroughputValue={(throughput: number) => (this.collectionThroughput = throughput)}
|
||||||
setIsAutoscale={(isAutoscale: boolean) => (this.isCollectionAutoscale = isAutoscale)}
|
setIsAutoscale={(isAutoscale: boolean) => (this.isCollectionAutoscale = isAutoscale)}
|
||||||
onCostAcknowledgeChange={(isAcknowledged: boolean) => {
|
onCostAcknowledgeChange={(isAcknowledged: boolean) => {
|
||||||
@@ -455,7 +466,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
creating a unique key policy when a container is created, you ensure the uniqueness of one or more values
|
creating a unique key policy when a container is created, you ensure the uniqueness of one or more values
|
||||||
per partition key."
|
per partition key."
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -508,10 +519,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<CollapsibleSectionComponent title="Advanced" isExpandedByDefault={false}>
|
{userContext.apiType !== "Tables" && (
|
||||||
<Stack className="panelGroupSpacing">
|
<CollapsibleSectionComponent
|
||||||
|
title="Advanced"
|
||||||
|
isExpandedByDefault={false}
|
||||||
|
onExpand={() => {
|
||||||
|
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||||
|
this.scrollToAdvancedSection();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack className="panelGroupSpacing" id="collapsibleSectionContent">
|
||||||
{this.props.explorer.isEnableMongoCapabilityPresent() && (
|
{this.props.explorer.isEnableMongoCapabilityPresent() && (
|
||||||
<Stack>
|
<Stack className="panelGroupSpacing">
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
@@ -519,10 +538,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="By default, only the field _id is indexed. Creating a wildcard index on all fields will quickly optimize
|
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||||
query performance and is recommended during development."
|
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -542,31 +560,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{userContext.apiType === "SQL" && (
|
{userContext.apiType === "SQL" && (
|
||||||
<Stack className="panelGroupSpacing">
|
|
||||||
<Stack horizontal verticalAlign="start">
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={this.state.useHashV1}
|
label="My partition key is larger than 100 bytes"
|
||||||
|
checked={this.state.useHashV2}
|
||||||
styles={{
|
styles={{
|
||||||
|
text: { fontSize: 12 },
|
||||||
checkbox: { width: 12, height: 12 },
|
checkbox: { width: 12, height: 12 },
|
||||||
label: { padding: 0, margin: "4px 4px 0 0" },
|
label: { padding: 0, alignItems: "center" },
|
||||||
}}
|
}}
|
||||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||||
this.setState({ useHashV1: isChecked })
|
this.setState({ useHashV2: isChecked })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Text variant="small" style={{ lineHeight: "20px" }}>
|
|
||||||
My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Text variant="small">
|
|
||||||
To ensure compatibility with older SDKs, the created container will use a legacy partitioning scheme
|
|
||||||
that supports partition key values of size up to 100 bytes.{" "}
|
|
||||||
<Link target="_blank" href="https://aka.ms/cosmosdb/pkv2">
|
|
||||||
Learn more
|
|
||||||
</Link>
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.shouldShowAnalyticalStoreOptions() && (
|
{this.shouldShowAnalyticalStoreOptions() && (
|
||||||
@@ -577,9 +582,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</Text>
|
</Text>
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||||
content="Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads. Learn more"
|
content={this.getAnalyticalStorageTooltipContent()}
|
||||||
>
|
>
|
||||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
<Icon iconName="Info" className="panelInfoIcon" />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -618,8 +623,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
{!this.isSynapseLinkEnabled() && (
|
{!this.isSynapseLinkEnabled() && (
|
||||||
<Stack className="panelGroupSpacing">
|
<Stack className="panelGroupSpacing">
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
Azure Synapse Link is required for creating an analytical store container. Enable Synapse Link
|
Azure Synapse Link is required for creating an analytical store{" "}
|
||||||
for this Cosmos DB account.{" "}
|
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.{" "}
|
||||||
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
|
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</Link>
|
</Link>
|
||||||
@@ -636,6 +641,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</CollapsibleSectionComponent>
|
</CollapsibleSectionComponent>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PanelFooterComponent buttonLabel="OK" />
|
<PanelFooterComponent buttonLabel="OK" />
|
||||||
@@ -652,24 +658,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCollectionName(): string {
|
private getPartitionKeyName(isLowerCase?: boolean): string {
|
||||||
switch (userContext.apiType) {
|
const partitionKeyName = userContext.apiType === "Mongo" ? "Shard key" : "Partition key";
|
||||||
case "SQL":
|
|
||||||
return "Container";
|
|
||||||
case "Mongo":
|
|
||||||
return "Collection";
|
|
||||||
case "Cassandra":
|
|
||||||
case "Tables":
|
|
||||||
return "Table";
|
|
||||||
case "Gremlin":
|
|
||||||
return "Graph";
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported default experience type: ${userContext.apiType}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getPartitionKeyName(): string {
|
return isLowerCase ? partitionKeyName.toLocaleLowerCase() : partitionKeyName;
|
||||||
return userContext.apiType === "Mongo" ? "Shard key" : "Partition key";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPartitionKeyPlaceHolder(): string {
|
private getPartitionKeyPlaceHolder(): string {
|
||||||
@@ -778,6 +770,34 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
: "Indexing will be turned off. Recommended if you don't need to run queries or only have key value operations.";
|
: "Indexing will be turned off. Recommended if you don't need to run queries or only have key value operations.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getPartitionKeyTooltipText(): string {
|
||||||
|
if (userContext.apiType === "Mongo") {
|
||||||
|
return "The shard key (field) is used to split your data across many replica sets (shards) to achieve unlimited scalability. It’s critical to choose a field that will evenly distribute your data.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let tooltipText = `The ${this.getPartitionKeyName(
|
||||||
|
true
|
||||||
|
)} is used to automatically distribute data across partitions for scalability. Choose a property in your JSON document that has a wide range of values and evenly distributes request volume.`;
|
||||||
|
|
||||||
|
if (userContext.apiType === "SQL") {
|
||||||
|
tooltipText += " For small read-heavy workloads or write-heavy workloads of any size, id is often a good choice.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return tooltipText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getAnalyticalStorageTooltipContent(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<Text variant="small">
|
||||||
|
Enable analytical store capability to perform near real-time analytics on your operational data, without
|
||||||
|
impacting the performance of transactional workloads.{" "}
|
||||||
|
<Link target="_blank" href="https://aka.ms/analytical-store-overview">
|
||||||
|
Learn more
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private shouldShowCollectionThroughputInput(): boolean {
|
private shouldShowCollectionThroughputInput(): boolean {
|
||||||
if (this.isServerlessAccount()) {
|
if (this.isServerlessAccount()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -883,6 +903,11 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (throughput > CollectionCreation.MaxRUPerPartition && !this.state.isSharded) {
|
||||||
|
this.setState({ errorMessage: "Unsharded collections support up to 10,000 RUs" });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
userContext.apiType === "Gremlin" &&
|
userContext.apiType === "Gremlin" &&
|
||||||
(this.state.partitionKey === "/id" || this.state.partitionKey === "/label")
|
(this.state.partitionKey === "/id" || this.state.partitionKey === "/label")
|
||||||
@@ -909,6 +934,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
return Constants.AnalyticalStorageTtl.Disabled;
|
return Constants.AnalyticalStorageTtl.Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private scrollToAdvancedSection(): void {
|
||||||
|
document.getElementById("collapsibleSectionContent")?.scrollIntoView();
|
||||||
|
}
|
||||||
|
|
||||||
private async submit(event: React.FormEvent<HTMLFormElement>): Promise<void> {
|
private async submit(event: React.FormEvent<HTMLFormElement>): Promise<void> {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@@ -927,7 +956,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uniqueKeyPolicy: DataModels.UniqueKeyPolicy = this.parseUniqueKeys();
|
const uniqueKeyPolicy: DataModels.UniqueKeyPolicy = this.parseUniqueKeys();
|
||||||
const partitionKeyVersion = this.state.useHashV1 ? undefined : 2;
|
const partitionKeyVersion = this.state.useHashV2 ? 2 : undefined;
|
||||||
const partitionKey: DataModels.PartitionKey = partitionKeyString
|
const partitionKey: DataModels.PartitionKey = partitionKeyString
|
||||||
? {
|
? {
|
||||||
paths: [partitionKeyString],
|
paths: [partitionKeyString],
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
userContext.portalEnv,
|
userContext.portalEnv,
|
||||||
this.isFreeTierAccount(),
|
this.isFreeTierAccount(),
|
||||||
this.container.isFirstResourceCreated(),
|
this.container.isFirstResourceCreated(),
|
||||||
userContext.apiType,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,11 +15,8 @@ import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
|||||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
import * as PricingUtils from "../../../Utils/PricingUtils";
|
||||||
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
|
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import {
|
|
||||||
GenericRightPaneComponent,
|
|
||||||
GenericRightPaneProps,
|
|
||||||
} from "../GenericRightPaneComponent/GenericRightPaneComponent";
|
|
||||||
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||||
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
|
|
||||||
export interface AddDatabasePaneProps {
|
export interface AddDatabasePaneProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
@@ -85,7 +82,6 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
userContext.portalEnv,
|
userContext.portalEnv,
|
||||||
isFreeTierAccount,
|
isFreeTierAccount,
|
||||||
container.isFirstResourceCreated(),
|
container.isFirstResourceCreated(),
|
||||||
userContext.apiType,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -254,8 +250,8 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: RightPaneFormProps = {
|
||||||
container,
|
expandConsole: container.expandConsole,
|
||||||
formError: formErrors,
|
formError: formErrors,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "add-database-inputs",
|
id: "add-database-inputs",
|
||||||
@@ -267,7 +263,7 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GenericRightPaneComponent {...genericPaneProps}>
|
<RightPaneForm {...genericPaneProps}>
|
||||||
<form style={{ height: "100%" }}>
|
<form style={{ height: "100%" }}>
|
||||||
<div className="paneContentContainer" role="dialog" aria-labelledby="databaseTitle">
|
<div className="paneContentContainer" role="dialog" aria-labelledby="databaseTitle">
|
||||||
{showUpsellMessage && formErrors === "" && (
|
{showUpsellMessage && formErrors === "" && (
|
||||||
@@ -327,6 +323,7 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
<ThroughputInput
|
<ThroughputInput
|
||||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !container?.isFirstResourceCreated()}
|
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !container?.isFirstResourceCreated()}
|
||||||
isDatabase={true}
|
isDatabase={true}
|
||||||
|
isSharded={databaseCreateNewShared}
|
||||||
isAutoscaleSelected={isAutoPilotSelected}
|
isAutoscaleSelected={isAutoPilotSelected}
|
||||||
throughput={throughput}
|
throughput={throughput}
|
||||||
setThroughputValue={(throughput: number) => setThroughput(throughput)}
|
setThroughputValue={(throughput: number) => setThroughput(throughput)}
|
||||||
@@ -348,6 +345,6 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</GenericRightPaneComponent>
|
</RightPaneForm>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,505 +1,8 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||||
<GenericRightPaneComponent
|
<RightPaneForm
|
||||||
container={
|
expandConsole={[Function]}
|
||||||
Explorer {
|
|
||||||
"_closeModalDialog": [Function],
|
|
||||||
"_closeSynapseLinkModalDialog": [Function],
|
|
||||||
"_isAfecFeatureRegistered": [Function],
|
|
||||||
"_isInitializingNotebooks": false,
|
|
||||||
"_panes": Array [
|
|
||||||
AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"_refreshSparkEnabledStateForAccount": [Function],
|
|
||||||
"_resetNotebookWorkspace": [Function],
|
|
||||||
"addCollectionPane": AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addCollectionText": [Function],
|
|
||||||
"addDatabasePane": AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addDatabaseText": [Function],
|
|
||||||
"arcadiaToken": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canSaveQueries": [Function],
|
|
||||||
"cassandraAddCollectionPane": CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"clickHostedAccountSwitch": [Function],
|
|
||||||
"clickHostedDirectorySwitch": [Function],
|
|
||||||
"closeDialog": undefined,
|
|
||||||
"closeSidePanel": undefined,
|
|
||||||
"collapsedResourceTreeWidth": 36,
|
|
||||||
"collectionCreationDefaults": Object {
|
|
||||||
"storage": "100",
|
|
||||||
"throughput": Object {
|
|
||||||
"fixed": 400,
|
|
||||||
"shared": 400,
|
|
||||||
"unlimited": 400,
|
|
||||||
"unlimitedmax": 1000000,
|
|
||||||
"unlimitedmin": 400,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"collectionTitle": [Function],
|
|
||||||
"collectionTreeNodeAltText": [Function],
|
|
||||||
"commandBarComponentAdapter": CommandBarComponentAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"isNotebookTabActive": [Function],
|
|
||||||
"parameters": [Function],
|
|
||||||
"tabsButtons": Array [],
|
|
||||||
},
|
|
||||||
"databaseAccount": [Function],
|
|
||||||
"databases": [Function],
|
|
||||||
"defaultExperience": [Function],
|
|
||||||
"deleteCollectionText": [Function],
|
|
||||||
"deleteDatabaseText": [Function],
|
|
||||||
"graphStylingPane": GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"hasStorageAnalyticsAfecFeature": [Function],
|
|
||||||
"isAccountReady": [Function],
|
|
||||||
"isAutoscaleDefaultEnabled": [Function],
|
|
||||||
"isEnableMongoCapabilityPresent": [Function],
|
|
||||||
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
|
||||||
"isGitHubPaneEnabled": [Function],
|
|
||||||
"isHostedDataExplorerEnabled": [Function],
|
|
||||||
"isLeftPaneExpanded": [Function],
|
|
||||||
"isMongoIndexingEnabled": [Function],
|
|
||||||
"isNotebookEnabled": [Function],
|
|
||||||
"isNotebooksEnabledForAccount": [Function],
|
|
||||||
"isPublishNotebookPaneEnabled": [Function],
|
|
||||||
"isResourceTokenCollectionNodeSelected": [Function],
|
|
||||||
"isRightPanelV2Enabled": [Function],
|
|
||||||
"isSchemaEnabled": [Function],
|
|
||||||
"isServerlessEnabled": [Function],
|
|
||||||
"isSparkEnabled": [Function],
|
|
||||||
"isSparkEnabledForAccount": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTabsContentExpanded": [Function],
|
|
||||||
"memoryUsageInfo": [Function],
|
|
||||||
"notebookBasePath": [Function],
|
|
||||||
"notebookServerInfo": [Function],
|
|
||||||
"onRefreshDatabasesKeyPress": [Function],
|
|
||||||
"onRefreshResourcesClick": [Function],
|
|
||||||
"onSwitchToConnectionString": [Function],
|
|
||||||
"openDialog": undefined,
|
|
||||||
"openSidePanel": undefined,
|
|
||||||
"provideFeedbackEmail": [Function],
|
|
||||||
"queriesClient": QueriesClient {
|
|
||||||
"container": [Circular],
|
|
||||||
},
|
|
||||||
"refreshDatabaseAccount": [Function],
|
|
||||||
"refreshNotebookList": [Function],
|
|
||||||
"refreshTreeTitle": [Function],
|
|
||||||
"resourceTokenCollection": [Function],
|
|
||||||
"resourceTokenCollectionId": [Function],
|
|
||||||
"resourceTokenDatabaseId": [Function],
|
|
||||||
"resourceTokenPartitionKey": [Function],
|
|
||||||
"resourceTree": ResourceTreeAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"copyNotebook": [Function],
|
|
||||||
"databaseCollectionIdMap": Map {},
|
|
||||||
"koSubsCollectionIdMap": Map {},
|
|
||||||
"koSubsDatabaseIdMap": Map {},
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {
|
|
||||||
"container": [Circular],
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"selectedDatabaseId": [Function],
|
|
||||||
"selectedNode": [Function],
|
|
||||||
"setInProgressConsoleDataIdToBeDeleted": undefined,
|
|
||||||
"setIsNotificationConsoleExpanded": undefined,
|
|
||||||
"setNotificationConsoleData": undefined,
|
|
||||||
"signInAad": [Function],
|
|
||||||
"sparkClusterConnectionInfo": [Function],
|
|
||||||
"splitter": Splitter {
|
|
||||||
"bounds": Object {
|
|
||||||
"max": 400,
|
|
||||||
"min": 240,
|
|
||||||
},
|
|
||||||
"direction": "vertical",
|
|
||||||
"isCollapsed": [Function],
|
|
||||||
"leftSideId": "resourcetree",
|
|
||||||
"onResizeStart": [Function],
|
|
||||||
"onResizeStop": [Function],
|
|
||||||
"splitterId": "h_splitter1",
|
|
||||||
},
|
|
||||||
"tabsManager": TabsManager {
|
|
||||||
"activeTab": [Function],
|
|
||||||
"openedTabs": [Function],
|
|
||||||
},
|
|
||||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formError=""
|
formError=""
|
||||||
id="add-database-inputs"
|
id="add-database-inputs"
|
||||||
isExecuting={false}
|
isExecuting={false}
|
||||||
@@ -598,6 +101,7 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
|||||||
<ThroughputInput
|
<ThroughputInput
|
||||||
isAutoscaleSelected={false}
|
isAutoscaleSelected={false}
|
||||||
isDatabase={true}
|
isDatabase={true}
|
||||||
|
isSharded={true}
|
||||||
onCostAcknowledgeChange={[Function]}
|
onCostAcknowledgeChange={[Function]}
|
||||||
setIsAutoscale={[Function]}
|
setIsAutoscale={[Function]}
|
||||||
setThroughputValue={[Function]}
|
setThroughputValue={[Function]}
|
||||||
@@ -608,5 +112,5 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</GenericRightPaneComponent>
|
</RightPaneForm>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,194 +0,0 @@
|
|||||||
import ko from "knockout";
|
|
||||||
import { IDropdownOption } from "office-ui-fabric-react";
|
|
||||||
import * as React from "react";
|
|
||||||
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
|
|
||||||
import { HttpStatusCodes } from "../../Common/Constants";
|
|
||||||
import { getErrorMessage, handleError } from "../../Common/ErrorHandlingUtils";
|
|
||||||
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
|
||||||
import { IPinnedRepo, JunoClient } from "../../Juno/JunoClient";
|
|
||||||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
|
||||||
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
|
|
||||||
import Explorer from "../Explorer";
|
|
||||||
import { NotebookContentItem, NotebookContentItemType } from "../Notebook/NotebookContentItem";
|
|
||||||
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
|
||||||
import { CopyNotebookPaneComponent, CopyNotebookPaneProps } from "./CopyNotebookPane/CopyNotebookPaneComponent";
|
|
||||||
import { RightPaneForm, RightPaneFormProps } from "./RightPaneForm/RightPaneForm";
|
|
||||||
|
|
||||||
interface Location {
|
|
||||||
type: "MyNotebooks" | "GitHub";
|
|
||||||
|
|
||||||
// GitHub
|
|
||||||
owner?: string;
|
|
||||||
repo?: string;
|
|
||||||
branch?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CopyNotebookPaneAdapter implements ReactAdapter {
|
|
||||||
private static readonly BranchNameWhiteSpace = " ";
|
|
||||||
|
|
||||||
parameters: ko.Observable<number>;
|
|
||||||
private isOpened: boolean;
|
|
||||||
private isExecuting: boolean;
|
|
||||||
private formError: string;
|
|
||||||
private formErrorDetail: string;
|
|
||||||
private name: string;
|
|
||||||
private content: string;
|
|
||||||
private pinnedRepos: IPinnedRepo[];
|
|
||||||
private selectedLocation: Location;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private container: Explorer,
|
|
||||||
private junoClient: JunoClient,
|
|
||||||
private gitHubOAuthService: GitHubOAuthService
|
|
||||||
) {
|
|
||||||
this.parameters = ko.observable(Date.now());
|
|
||||||
this.reset();
|
|
||||||
this.triggerRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
public renderComponent(): JSX.Element {
|
|
||||||
if (!this.isOpened) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const genericPaneProps: RightPaneFormProps = {
|
|
||||||
container: this.container,
|
|
||||||
formError: this.formError,
|
|
||||||
formErrorDetail: this.formErrorDetail,
|
|
||||||
id: "copynotebookpane",
|
|
||||||
isExecuting: this.isExecuting,
|
|
||||||
title: "Copy notebook",
|
|
||||||
submitButtonText: "OK",
|
|
||||||
onClose: () => this.close(),
|
|
||||||
onSubmit: () => this.submit(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const copyNotebookPaneProps: CopyNotebookPaneProps = {
|
|
||||||
name: this.name,
|
|
||||||
pinnedRepos: this.pinnedRepos,
|
|
||||||
onDropDownChange: this.onDropDownChange,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RightPaneForm {...genericPaneProps}>
|
|
||||||
<CopyNotebookPaneComponent {...copyNotebookPaneProps} />
|
|
||||||
</RightPaneForm>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public triggerRender(): void {
|
|
||||||
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async open(name: string, content: string): Promise<void> {
|
|
||||||
this.name = name;
|
|
||||||
this.content = content;
|
|
||||||
|
|
||||||
this.isOpened = true;
|
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
if (this.gitHubOAuthService.isLoggedIn()) {
|
|
||||||
const response = await this.junoClient.getPinnedRepos(this.gitHubOAuthService.getTokenObservable()()?.scope);
|
|
||||||
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
||||||
handleError(`Received HTTP ${response.status} when fetching pinned repos`, "CopyNotebookPaneAdapter/submit");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.data?.length > 0) {
|
|
||||||
this.pinnedRepos = response.data;
|
|
||||||
this.triggerRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public close(): void {
|
|
||||||
this.reset();
|
|
||||||
this.triggerRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async submit(): Promise<void> {
|
|
||||||
let destination: string = this.selectedLocation?.type;
|
|
||||||
let clearMessage: () => void;
|
|
||||||
this.isExecuting = true;
|
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!this.selectedLocation) {
|
|
||||||
throw new Error(`No location selected`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.selectedLocation.type === "GitHub") {
|
|
||||||
destination = `${destination} - ${GitHubUtils.toRepoFullName(
|
|
||||||
this.selectedLocation.owner,
|
|
||||||
this.selectedLocation.repo
|
|
||||||
)} - ${this.selectedLocation.branch}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMessage = NotificationConsoleUtils.logConsoleProgress(`Copying ${this.name} to ${destination}`);
|
|
||||||
|
|
||||||
const notebookContentItem = await this.copyNotebook(this.selectedLocation);
|
|
||||||
if (!notebookContentItem) {
|
|
||||||
throw new Error(`Failed to upload ${this.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationConsoleUtils.logConsoleInfo(`Successfully copied ${this.name} to ${destination}`);
|
|
||||||
} catch (error) {
|
|
||||||
const errorMessage = getErrorMessage(error);
|
|
||||||
this.formError = `Failed to copy ${this.name} to ${destination}`;
|
|
||||||
this.formErrorDetail = `${errorMessage}`;
|
|
||||||
handleError(errorMessage, "CopyNotebookPaneAdapter/submit", this.formError);
|
|
||||||
return;
|
|
||||||
} finally {
|
|
||||||
clearMessage && clearMessage();
|
|
||||||
this.isExecuting = false;
|
|
||||||
this.triggerRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private copyNotebook = async (location: Location): Promise<NotebookContentItem> => {
|
|
||||||
let parent: NotebookContentItem;
|
|
||||||
switch (location.type) {
|
|
||||||
case "MyNotebooks":
|
|
||||||
parent = {
|
|
||||||
name: ResourceTreeAdapter.MyNotebooksTitle,
|
|
||||||
path: this.container.getNotebookBasePath(),
|
|
||||||
type: NotebookContentItemType.Directory,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "GitHub":
|
|
||||||
parent = {
|
|
||||||
name: ResourceTreeAdapter.GitHubReposTitle,
|
|
||||||
path: GitHubUtils.toContentUri(
|
|
||||||
this.selectedLocation.owner,
|
|
||||||
this.selectedLocation.repo,
|
|
||||||
this.selectedLocation.branch,
|
|
||||||
""
|
|
||||||
),
|
|
||||||
type: NotebookContentItemType.Directory,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported location type ${location.type}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.container.uploadFile(this.name, this.content, parent);
|
|
||||||
};
|
|
||||||
|
|
||||||
private onDropDownChange = (_: React.FormEvent<HTMLDivElement>, option?: IDropdownOption): void => {
|
|
||||||
this.selectedLocation = option?.data;
|
|
||||||
};
|
|
||||||
|
|
||||||
private reset = (): void => {
|
|
||||||
this.isOpened = false;
|
|
||||||
this.isExecuting = false;
|
|
||||||
this.formError = undefined;
|
|
||||||
this.formErrorDetail = undefined;
|
|
||||||
this.name = undefined;
|
|
||||||
this.content = undefined;
|
|
||||||
this.pinnedRepos = undefined;
|
|
||||||
this.selectedLocation = undefined;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -131,7 +131,6 @@ export const CopyNotebookPane: FunctionComponent<CopyNotebookPanelProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container,
|
|
||||||
formError,
|
formError,
|
||||||
formErrorDetail,
|
formErrorDetail,
|
||||||
id: "copynotebookpane",
|
id: "copynotebookpane",
|
||||||
@@ -140,6 +139,7 @@ export const CopyNotebookPane: FunctionComponent<CopyNotebookPanelProps> = ({
|
|||||||
submitButtonText: "OK",
|
submitButtonText: "OK",
|
||||||
onClose: closePanel,
|
onClose: closePanel,
|
||||||
onSubmit: () => submit(),
|
onSubmit: () => submit(),
|
||||||
|
expandConsole: () => container.expandConsole(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyNotebookPaneProps: CopyNotebookPaneProps = {
|
const copyNotebookPaneProps: CopyNotebookPaneProps = {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { DefaultExperienceUtility } from "../../../Shared/DefaultExperienceUtili
|
|||||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
|
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||||
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
|
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import {
|
import {
|
||||||
@@ -17,14 +18,12 @@ import {
|
|||||||
} from "../GenericRightPaneComponent/GenericRightPaneComponent";
|
} from "../GenericRightPaneComponent/GenericRightPaneComponent";
|
||||||
export interface DeleteCollectionConfirmationPaneProps {
|
export interface DeleteCollectionConfirmationPaneProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
collectionName: string;
|
|
||||||
closePanel: () => void;
|
closePanel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectionConfirmationPaneProps> = ({
|
export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectionConfirmationPaneProps> = ({
|
||||||
explorer,
|
explorer,
|
||||||
closePanel,
|
closePanel,
|
||||||
collectionName,
|
|
||||||
}: DeleteCollectionConfirmationPaneProps) => {
|
}: DeleteCollectionConfirmationPaneProps) => {
|
||||||
const [deleteCollectionFeedback, setDeleteCollectionFeedback] = useState<string>("");
|
const [deleteCollectionFeedback, setDeleteCollectionFeedback] = useState<string>("");
|
||||||
const [inputCollectionName, setInputCollectionName] = useState<string>("");
|
const [inputCollectionName, setInputCollectionName] = useState<string>("");
|
||||||
@@ -34,6 +33,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
|||||||
const shouldRecordFeedback = (): boolean => {
|
const shouldRecordFeedback = (): boolean => {
|
||||||
return explorer.isLastCollection() && !explorer.isSelectedDatabaseShared();
|
return explorer.isLastCollection() && !explorer.isSelectedDatabaseShared();
|
||||||
};
|
};
|
||||||
|
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||||
const paneTitle = "Delete " + collectionName;
|
const paneTitle = "Delete " + collectionName;
|
||||||
const submit = async (): Promise<void> => {
|
const submit = async (): Promise<void> => {
|
||||||
const collection = explorer.findSelectedCollection();
|
const collection = explorer.findSelectedCollection();
|
||||||
@@ -101,7 +101,6 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: explorer,
|
|
||||||
formError: formError,
|
formError: formError,
|
||||||
formErrorDetail: formError,
|
formErrorDetail: formError,
|
||||||
id: "deleteCollectionpane",
|
id: "deleteCollectionpane",
|
||||||
@@ -110,6 +109,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
|||||||
submitButtonText: "OK",
|
submitButtonText: "OK",
|
||||||
onClose: closePanel,
|
onClose: closePanel,
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
|
expandConsole: () => explorer.expandConsole(),
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<GenericRightPaneComponent {...genericPaneProps}>
|
<GenericRightPaneComponent {...genericPaneProps}>
|
||||||
|
|||||||
@@ -16,16 +16,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<GenericRightPaneComponent
|
<GenericRightPaneComponent
|
||||||
container={
|
expandConsole={[Function]}
|
||||||
Object {
|
|
||||||
"findSelectedCollection": [Function],
|
|
||||||
"isLastCollection": [Function],
|
|
||||||
"isSelectedDatabaseShared": [Function],
|
|
||||||
"refreshAllDatabases": [Function],
|
|
||||||
"selectedCollectionId": [Function],
|
|
||||||
"selectedNode": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="deleteCollectionpane"
|
id="deleteCollectionpane"
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||||
import { ExecuteSprocParamsPane } from "./ExecuteSprocParamsPane";
|
import { ExecuteSprocParamsPane } from "./ExecuteSprocParamsPane";
|
||||||
|
|
||||||
describe("Excute Sproc Param Pane", () => {
|
describe("Excute Sproc Param Pane", () => {
|
||||||
const fakeExplorer = {} as Explorer;
|
|
||||||
const fakeSproc = {} as StoredProcedure;
|
const fakeSproc = {} as StoredProcedure;
|
||||||
const props = {
|
const props = {
|
||||||
explorer: fakeExplorer,
|
|
||||||
storedProcedure: fakeSproc,
|
storedProcedure: fakeSproc,
|
||||||
|
expandConsole: (): void => undefined,
|
||||||
closePanel: (): void => undefined,
|
closePanel: (): void => undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { useBoolean } from "@uifabric/react-hooks";
|
|||||||
import { IDropdownOption, IImageProps, Image, Stack, Text } from "office-ui-fabric-react";
|
import { IDropdownOption, IImageProps, Image, Stack, Text } from "office-ui-fabric-react";
|
||||||
import React, { FunctionComponent, useState } from "react";
|
import React, { FunctionComponent, useState } from "react";
|
||||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||||
import {
|
import {
|
||||||
GenericRightPaneComponent,
|
GenericRightPaneComponent,
|
||||||
@@ -11,7 +10,7 @@ import {
|
|||||||
import { InputParameter } from "./InputParameter";
|
import { InputParameter } from "./InputParameter";
|
||||||
|
|
||||||
interface ExecuteSprocParamsPaneProps {
|
interface ExecuteSprocParamsPaneProps {
|
||||||
explorer: Explorer;
|
expandConsole: () => void;
|
||||||
storedProcedure: StoredProcedure;
|
storedProcedure: StoredProcedure;
|
||||||
closePanel: () => void;
|
closePanel: () => void;
|
||||||
}
|
}
|
||||||
@@ -27,7 +26,7 @@ interface UnwrappedExecuteSprocParam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
|
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
|
||||||
explorer,
|
expandConsole,
|
||||||
storedProcedure,
|
storedProcedure,
|
||||||
closePanel,
|
closePanel,
|
||||||
}: ExecuteSprocParamsPaneProps): JSX.Element => {
|
}: ExecuteSprocParamsPaneProps): JSX.Element => {
|
||||||
@@ -43,7 +42,7 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
|||||||
};
|
};
|
||||||
|
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: explorer,
|
expandConsole,
|
||||||
formError: formError,
|
formError: formError,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "executesprocparamspane",
|
id: "executesprocparamspane",
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
exports[`Excute Sproc Param Pane should render Default properly 1`] = `
|
exports[`Excute Sproc Param Pane should render Default properly 1`] = `
|
||||||
<ExecuteSprocParamsPane
|
<ExecuteSprocParamsPane
|
||||||
closePanel={[Function]}
|
closePanel={[Function]}
|
||||||
explorer={Object {}}
|
expandConsole={[Function]}
|
||||||
storedProcedure={Object {}}
|
storedProcedure={Object {}}
|
||||||
>
|
>
|
||||||
<GenericRightPaneComponent
|
<GenericRightPaneComponent
|
||||||
container={Object {}}
|
expandConsole={[Function]}
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="executesprocparamspane"
|
id="executesprocparamspane"
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import React, { FunctionComponent, ReactNode } from "react";
|
|||||||
import ErrorRedIcon from "../../../../images/error_red.svg";
|
import ErrorRedIcon from "../../../../images/error_red.svg";
|
||||||
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
|
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
|
||||||
import { KeyCodes } from "../../../Common/Constants";
|
import { KeyCodes } from "../../../Common/Constants";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
|
|
||||||
export interface GenericRightPaneProps {
|
export interface GenericRightPaneProps {
|
||||||
container: Explorer;
|
expandConsole: () => void;
|
||||||
formError: string;
|
formError: string;
|
||||||
formErrorDetail: string;
|
formErrorDetail: string;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -20,7 +19,7 @@ export interface GenericRightPaneProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps> = ({
|
export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps> = ({
|
||||||
container,
|
expandConsole,
|
||||||
formError,
|
formError,
|
||||||
formErrorDetail,
|
formErrorDetail,
|
||||||
id,
|
id,
|
||||||
@@ -68,7 +67,7 @@ export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps>
|
|||||||
<span className="formErrors" title={formError}>
|
<span className="formErrors" title={formError}>
|
||||||
{formError}
|
{formError}
|
||||||
</span>
|
</span>
|
||||||
<a className="errorLink" role="link" hidden={!formErrorDetail} onClick={showErrorDetail}>
|
<a className="errorLink" role="link" hidden={!formErrorDetail} onClick={expandConsole}>
|
||||||
More details
|
More details
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@@ -110,10 +109,6 @@ export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showErrorDetail = (): void => {
|
|
||||||
container.expandConsole();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div tabIndex={-1} onKeyDown={onKeyDown}>
|
<div tabIndex={-1} onKeyDown={onKeyDown}>
|
||||||
<div className="contextual-pane-out" onClick={onClose}></div>
|
<div className="contextual-pane-out" onClick={onClose}></div>
|
||||||
|
|||||||
@@ -1,14 +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" id="gitHubReposPane">
|
|
||||||
<div class="contextual-pane-in">
|
|
||||||
<div class="paneContentContainer" data-bind="react: gitHubReposAdapter" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Loader - Start -->
|
|
||||||
<div class="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer" data-bind="visible: isExecuting">
|
|
||||||
<img class="dataExplorerLoader" alt="loading indicator image" src="/LoadingIndicator_3Squares.gif" />
|
|
||||||
</div>
|
|
||||||
<!-- Loader - End -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { shallow } from "enzyme";
|
||||||
|
import React from "react";
|
||||||
|
import { GitHubClient } from "../../../GitHub/GitHubClient";
|
||||||
|
import { JunoClient } from "../../../Juno/JunoClient";
|
||||||
|
import Explorer from "../../Explorer";
|
||||||
|
import { GitHubReposPanel } from "./GitHubReposPanel";
|
||||||
|
const props = {
|
||||||
|
explorer: new Explorer(),
|
||||||
|
closePanel: (): void => undefined,
|
||||||
|
gitHubClientProp: new GitHubClient((): void => undefined),
|
||||||
|
junoClientProp: new JunoClient(),
|
||||||
|
openNotificationConsole: (): void => undefined,
|
||||||
|
};
|
||||||
|
describe("GitHub Repos Panel", () => {
|
||||||
|
it("should render Default properly", () => {
|
||||||
|
const wrapper = shallow(<GitHubReposPanel {...props} />);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,27 +1,42 @@
|
|||||||
import _ from "underscore";
|
import React from "react";
|
||||||
import { Areas, HttpStatusCodes } from "../../Common/Constants";
|
import { Areas, HttpStatusCodes } from "../../../Common/Constants";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import { handleError } from "../../../Common/ErrorHandlingUtils";
|
||||||
import { GitHubClient, IGitHubPageInfo, IGitHubRepo } from "../../GitHub/GitHubClient";
|
import { GitHubClient, IGitHubPageInfo, IGitHubRepo } from "../../../GitHub/GitHubClient";
|
||||||
import { IPinnedRepo, JunoClient } from "../../Juno/JunoClient";
|
import { IPinnedRepo, JunoClient } from "../../../Juno/JunoClient";
|
||||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
import * as GitHubUtils from "../../../Utils/GitHubUtils";
|
||||||
import * as JunoUtils from "../../Utils/JunoUtils";
|
import * as JunoUtils from "../../../Utils/JunoUtils";
|
||||||
import { AuthorizeAccessComponent } from "../Controls/GitHub/AuthorizeAccessComponent";
|
import { AuthorizeAccessComponent } from "../../Controls/GitHub/AuthorizeAccessComponent";
|
||||||
import { GitHubReposComponent, GitHubReposComponentProps, RepoListItem } from "../Controls/GitHub/GitHubReposComponent";
|
import {
|
||||||
import { GitHubReposComponentAdapter } from "../Controls/GitHub/GitHubReposComponentAdapter";
|
GitHubReposComponent,
|
||||||
import { BranchesProps, PinnedReposProps, UnpinnedReposProps } from "../Controls/GitHub/ReposListComponent";
|
GitHubReposComponentProps,
|
||||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
RepoListItem,
|
||||||
import { handleError } from "../../Common/ErrorHandlingUtils";
|
} from "../../Controls/GitHub/GitHubReposComponent";
|
||||||
|
import { ContentMainStyle } from "../../Controls/GitHub/GitHubStyleConstants";
|
||||||
|
import { BranchesProps, PinnedReposProps, UnpinnedReposProps } from "../../Controls/GitHub/ReposListComponent";
|
||||||
|
import Explorer from "../../Explorer";
|
||||||
|
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||||
|
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
||||||
|
|
||||||
interface GitHubReposPaneOptions extends ViewModels.PaneOptions {
|
interface IGitHubReposPanelProps {
|
||||||
gitHubClient: GitHubClient;
|
explorer: Explorer;
|
||||||
junoClient: JunoClient;
|
closePanel: () => void;
|
||||||
|
gitHubClientProp: GitHubClient;
|
||||||
|
junoClientProp: JunoClient;
|
||||||
|
openNotificationConsole: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GitHubReposPane extends ContextualPaneBase {
|
interface IGitHubReposPanelState {
|
||||||
|
showAuthorizationAcessState: boolean;
|
||||||
|
isExecuting: boolean;
|
||||||
|
errorMessage: string;
|
||||||
|
showErrorDetails: boolean;
|
||||||
|
gitHubReposState: GitHubReposComponentProps;
|
||||||
|
}
|
||||||
|
export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IGitHubReposPanelState> {
|
||||||
private static readonly PageSize = 30;
|
private static readonly PageSize = 30;
|
||||||
|
private isAddedRepo = false;
|
||||||
private gitHubClient: GitHubClient;
|
private gitHubClient: GitHubClient;
|
||||||
private junoClient: JunoClient;
|
private junoClient: JunoClient;
|
||||||
|
|
||||||
@@ -29,32 +44,35 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
private pinnedReposProps: PinnedReposProps;
|
private pinnedReposProps: PinnedReposProps;
|
||||||
private unpinnedReposProps: UnpinnedReposProps;
|
private unpinnedReposProps: UnpinnedReposProps;
|
||||||
|
|
||||||
private gitHubReposProps: GitHubReposComponentProps;
|
|
||||||
private gitHubReposAdapter: GitHubReposComponentAdapter;
|
|
||||||
|
|
||||||
private allGitHubRepos: IGitHubRepo[];
|
private allGitHubRepos: IGitHubRepo[];
|
||||||
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
||||||
private pinnedReposUpdated: boolean;
|
private pinnedReposUpdated: boolean;
|
||||||
|
|
||||||
constructor(options: GitHubReposPaneOptions) {
|
constructor(props: IGitHubReposPanelProps) {
|
||||||
super(options);
|
super(props);
|
||||||
|
|
||||||
this.gitHubClient = options.gitHubClient;
|
|
||||||
this.junoClient = options.junoClient;
|
|
||||||
|
|
||||||
this.branchesProps = {};
|
|
||||||
this.pinnedReposProps = {
|
|
||||||
repos: [],
|
|
||||||
};
|
|
||||||
this.unpinnedReposProps = {
|
this.unpinnedReposProps = {
|
||||||
repos: [],
|
repos: [],
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
loadMore: (): Promise<void> => this.loadMoreUnpinnedRepos(),
|
loadMore: (): Promise<void> => this.loadMoreUnpinnedRepos(),
|
||||||
};
|
};
|
||||||
|
this.branchesProps = {};
|
||||||
|
this.pinnedReposProps = {
|
||||||
|
repos: [],
|
||||||
|
};
|
||||||
|
|
||||||
this.gitHubReposProps = {
|
this.allGitHubRepos = [];
|
||||||
showAuthorizeAccess: true,
|
this.allGitHubReposLastPageInfo = undefined;
|
||||||
|
this.pinnedReposUpdated = false;
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
showAuthorizationAcessState: true,
|
||||||
|
isExecuting: false,
|
||||||
|
errorMessage: "",
|
||||||
|
showErrorDetails: false,
|
||||||
|
gitHubReposState: {
|
||||||
|
showAuthorizeAccess: !this.props.explorer.notebookManager?.gitHubOAuthService.isLoggedIn(),
|
||||||
authorizeAccessProps: {
|
authorizeAccessProps: {
|
||||||
scope: this.getOAuthScope(),
|
scope: this.getOAuthScope(),
|
||||||
authorizeAccess: (scope): void => this.connectToGitHub(scope),
|
authorizeAccess: (scope): void => this.connectToGitHub(scope),
|
||||||
@@ -67,35 +85,32 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
unpinRepo: (item): Promise<void> => this.unpinRepo(item),
|
unpinRepo: (item): Promise<void> => this.unpinRepo(item),
|
||||||
},
|
},
|
||||||
addRepoProps: {
|
addRepoProps: {
|
||||||
container: this.container,
|
container: this.props.explorer,
|
||||||
getRepo: (owner, repo): Promise<IGitHubRepo> => this.getRepo(owner, repo),
|
getRepo: (owner, repo): Promise<IGitHubRepo> => this.getRepo(owner, repo),
|
||||||
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
||||||
},
|
},
|
||||||
resetConnection: (): void => this.setup(true),
|
resetConnection: (): void => this.setup(true),
|
||||||
onOkClick: (): Promise<void> => this.submit(),
|
onOkClick: (): Promise<void> => this.submit(),
|
||||||
onCancelClick: (): void => this.cancel(),
|
onCancelClick: (): void => this.props.closePanel(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
this.gitHubReposAdapter = new GitHubReposComponentAdapter(this.gitHubReposProps);
|
this.gitHubClient = this.props.gitHubClientProp;
|
||||||
|
this.junoClient = this.props.junoClientProp;
|
||||||
|
}
|
||||||
|
|
||||||
this.allGitHubRepos = [];
|
componentDidMount(): void {
|
||||||
this.allGitHubReposLastPageInfo = undefined;
|
this.open();
|
||||||
this.pinnedReposUpdated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public open(): void {
|
public open(): void {
|
||||||
this.resetData();
|
this.resetData();
|
||||||
this.setup();
|
this.setup();
|
||||||
|
|
||||||
super.open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async submit(): Promise<void> {
|
public async submit(): Promise<void> {
|
||||||
const pinnedReposUpdated = this.pinnedReposUpdated;
|
const pinnedReposUpdated = this.pinnedReposUpdated;
|
||||||
const reposToPin: IPinnedRepo[] = this.pinnedReposProps.repos.map((repo) => JunoUtils.toPinnedRepo(repo));
|
const reposToPin: IPinnedRepo[] = this.pinnedReposProps.repos.map((repo) => JunoUtils.toPinnedRepo(repo));
|
||||||
|
|
||||||
// Submit resets data too
|
|
||||||
super.submit();
|
|
||||||
|
|
||||||
if (pinnedReposUpdated) {
|
if (pinnedReposUpdated) {
|
||||||
try {
|
try {
|
||||||
const response = await this.junoClient.updatePinnedRepos(reposToPin);
|
const response = await this.junoClient.updatePinnedRepos(reposToPin);
|
||||||
@@ -109,57 +124,44 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public resetData(): void {
|
public resetData(): void {
|
||||||
// Reset cached branches
|
|
||||||
this.branchesProps = {};
|
this.branchesProps = {};
|
||||||
this.gitHubReposProps.reposListProps.branchesProps = this.branchesProps;
|
|
||||||
|
|
||||||
// Reset cached pinned and unpinned repos
|
|
||||||
this.pinnedReposProps.repos = [];
|
this.pinnedReposProps.repos = [];
|
||||||
this.unpinnedReposProps.repos = [];
|
this.unpinnedReposProps.repos = [];
|
||||||
|
|
||||||
// Reset cached repos
|
|
||||||
this.allGitHubRepos = [];
|
this.allGitHubRepos = [];
|
||||||
this.allGitHubReposLastPageInfo = undefined;
|
this.allGitHubReposLastPageInfo = undefined;
|
||||||
|
|
||||||
// Reset flags
|
|
||||||
this.pinnedReposUpdated = false;
|
this.pinnedReposUpdated = false;
|
||||||
this.unpinnedReposProps.hasMore = true;
|
this.unpinnedReposProps.hasMore = true;
|
||||||
this.unpinnedReposProps.isLoading = true;
|
this.unpinnedReposProps.isLoading = true;
|
||||||
|
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
super.resetData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOAuthScope(): string {
|
private getOAuthScope(): string {
|
||||||
return (
|
return (
|
||||||
this.container.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope ||
|
this.props.explorer.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope ||
|
||||||
AuthorizeAccessComponent.Scopes.Public.key
|
AuthorizeAccessComponent.Scopes.Public.key
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setup(forceShowConnectToGitHub = false): void {
|
private setup(forceShowConnectToGitHub = false): void {
|
||||||
forceShowConnectToGitHub || !this.container.notebookManager?.gitHubOAuthService.isLoggedIn()
|
forceShowConnectToGitHub || !this.props.explorer.notebookManager?.gitHubOAuthService.isLoggedIn()
|
||||||
? this.setupForConnectToGitHub()
|
? this.setupForConnectToGitHub()
|
||||||
: this.setupForManageRepos();
|
: this.setupForManageRepos();
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupForConnectToGitHub(): void {
|
private setupForConnectToGitHub(): void {
|
||||||
this.gitHubReposProps.showAuthorizeAccess = true;
|
this.setState({
|
||||||
this.gitHubReposProps.authorizeAccessProps.scope = this.getOAuthScope();
|
isExecuting: false,
|
||||||
this.isExecuting(false);
|
});
|
||||||
this.title(GitHubReposComponent.ConnectToGitHubTitle); // Used for telemetry
|
|
||||||
this.triggerRender();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupForManageRepos(): Promise<void> {
|
private async setupForManageRepos(): Promise<void> {
|
||||||
this.gitHubReposProps.showAuthorizeAccess = false;
|
this.setState({
|
||||||
this.isExecuting(false);
|
isExecuting: false,
|
||||||
this.title(GitHubReposComponent.ManageGitHubRepoTitle); // Used for telemetry
|
});
|
||||||
TelemetryProcessor.trace(Action.NotebooksGitHubManageRepo, ActionModifiers.Mark, {
|
TelemetryProcessor.trace(Action.NotebooksGitHubManageRepo, ActionModifiers.Mark, {
|
||||||
dataExplorerArea: Areas.Notebook,
|
dataExplorerArea: Areas.Notebook,
|
||||||
});
|
});
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
this.refreshManageReposComponent();
|
this.refreshManageReposComponent();
|
||||||
}
|
}
|
||||||
@@ -182,15 +184,15 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
const branchesProps = this.branchesProps[GitHubUtils.toRepoFullName(repo.owner, repo.name)];
|
const branchesProps = this.branchesProps[GitHubUtils.toRepoFullName(repo.owner, repo.name)];
|
||||||
branchesProps.hasMore = true;
|
branchesProps.hasMore = true;
|
||||||
branchesProps.isLoading = true;
|
branchesProps.isLoading = true;
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.gitHubClient.getBranchesAsync(
|
const response = await this.gitHubClient.getBranchesAsync(
|
||||||
repo.owner,
|
repo.owner,
|
||||||
repo.name,
|
repo.name,
|
||||||
GitHubReposPane.PageSize,
|
GitHubReposPanel.PageSize,
|
||||||
branchesProps.lastPageInfo?.endCursor
|
branchesProps.lastPageInfo?.endCursor
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== HttpStatusCodes.OK) {
|
if (response.status !== HttpStatusCodes.OK) {
|
||||||
throw new Error(`Received HTTP ${response.status} when fetching branches`);
|
throw new Error(`Received HTTP ${response.status} when fetching branches`);
|
||||||
}
|
}
|
||||||
@@ -205,19 +207,37 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
|
|
||||||
branchesProps.isLoading = false;
|
branchesProps.isLoading = false;
|
||||||
branchesProps.hasMore = branchesProps.lastPageInfo?.hasNextPage;
|
branchesProps.hasMore = branchesProps.lastPageInfo?.hasNextPage;
|
||||||
this.triggerRender();
|
this.setState({
|
||||||
|
gitHubReposState: {
|
||||||
|
...this.state.gitHubReposState,
|
||||||
|
reposListProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps,
|
||||||
|
branchesProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.branchesProps,
|
||||||
|
[GitHubUtils.toRepoFullName(repo.owner, repo.name)]: branchesProps,
|
||||||
|
},
|
||||||
|
pinnedReposProps: {
|
||||||
|
repos: this.pinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
unpinnedReposProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.unpinnedReposProps,
|
||||||
|
repos: this.unpinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadMoreUnpinnedRepos(): Promise<void> {
|
private async loadMoreUnpinnedRepos(): Promise<void> {
|
||||||
this.unpinnedReposProps.isLoading = true;
|
this.unpinnedReposProps.isLoading = true;
|
||||||
this.unpinnedReposProps.hasMore = true;
|
this.unpinnedReposProps.hasMore = true;
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.gitHubClient.getReposAsync(
|
const response = await this.gitHubClient.getReposAsync(
|
||||||
GitHubReposPane.PageSize,
|
GitHubReposPanel.PageSize,
|
||||||
this.allGitHubReposLastPageInfo?.endCursor
|
this.allGitHubReposLastPageInfo?.endCursor
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== HttpStatusCodes.OK) {
|
if (response.status !== HttpStatusCodes.OK) {
|
||||||
throw new Error(`Received HTTP ${response.status} when fetching unpinned repos`);
|
throw new Error(`Received HTTP ${response.status} when fetching unpinned repos`);
|
||||||
}
|
}
|
||||||
@@ -233,7 +253,21 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
|
|
||||||
this.unpinnedReposProps.isLoading = false;
|
this.unpinnedReposProps.isLoading = false;
|
||||||
this.unpinnedReposProps.hasMore = this.allGitHubReposLastPageInfo?.hasNextPage;
|
this.unpinnedReposProps.hasMore = this.allGitHubReposLastPageInfo?.hasNextPage;
|
||||||
this.triggerRender();
|
|
||||||
|
this.setState({
|
||||||
|
gitHubReposState: {
|
||||||
|
...this.state.gitHubReposState,
|
||||||
|
reposListProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps,
|
||||||
|
unpinnedReposProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.unpinnedReposProps,
|
||||||
|
isLoading: this.unpinnedReposProps.isLoading,
|
||||||
|
hasMore: this.unpinnedReposProps.hasMore,
|
||||||
|
repos: this.unpinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getRepo(owner: string, repo: string): Promise<IGitHubRepo> {
|
private async getRepo(owner: string, repo: string): Promise<IGitHubRepo> {
|
||||||
@@ -242,7 +276,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
if (response.status !== HttpStatusCodes.OK) {
|
if (response.status !== HttpStatusCodes.OK) {
|
||||||
throw new Error(`Received HTTP ${response.status} when fetching repo`);
|
throw new Error(`Received HTTP ${response.status} when fetching repo`);
|
||||||
}
|
}
|
||||||
|
this.isAddedRepo = true;
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, "GitHubReposPane/getRepo", "Failed to fetch repo");
|
handleError(error, "GitHubReposPane/getRepo", "Failed to fetch repo");
|
||||||
@@ -254,7 +288,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
this.pinnedReposUpdated = true;
|
this.pinnedReposUpdated = true;
|
||||||
const initialReposLength = this.pinnedReposProps.repos.length;
|
const initialReposLength = this.pinnedReposProps.repos.length;
|
||||||
|
|
||||||
const existingRepo = _.find(this.pinnedReposProps.repos, (repo) => repo.key === item.key);
|
const existingRepo = this.pinnedReposProps.repos.find((repo) => repo.key === item.key);
|
||||||
if (existingRepo) {
|
if (existingRepo) {
|
||||||
existingRepo.branches = item.branches;
|
existingRepo.branches = item.branches;
|
||||||
} else {
|
} else {
|
||||||
@@ -262,7 +296,6 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.unpinnedReposProps.repos = this.calculateUnpinnedRepos();
|
this.unpinnedReposProps.repos = this.calculateUnpinnedRepos();
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
if (this.pinnedReposProps.repos.length > initialReposLength) {
|
if (this.pinnedReposProps.repos.length > initialReposLength) {
|
||||||
this.refreshBranchesForPinnedRepos();
|
this.refreshBranchesForPinnedRepos();
|
||||||
@@ -273,7 +306,22 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
this.pinnedReposUpdated = true;
|
this.pinnedReposUpdated = true;
|
||||||
this.pinnedReposProps.repos = this.pinnedReposProps.repos.filter((pinnedRepo) => pinnedRepo.key !== item.key);
|
this.pinnedReposProps.repos = this.pinnedReposProps.repos.filter((pinnedRepo) => pinnedRepo.key !== item.key);
|
||||||
this.unpinnedReposProps.repos = this.calculateUnpinnedRepos();
|
this.unpinnedReposProps.repos = this.calculateUnpinnedRepos();
|
||||||
this.triggerRender();
|
|
||||||
|
this.setState({
|
||||||
|
gitHubReposState: {
|
||||||
|
...this.state.gitHubReposState,
|
||||||
|
reposListProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps,
|
||||||
|
pinnedReposProps: {
|
||||||
|
repos: this.pinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
unpinnedReposProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.unpinnedReposProps,
|
||||||
|
repos: this.unpinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async refreshManageReposComponent(): Promise<void> {
|
private async refreshManageReposComponent(): Promise<void> {
|
||||||
@@ -284,12 +332,12 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
|
|
||||||
private async refreshPinnedRepoListItems(): Promise<void> {
|
private async refreshPinnedRepoListItems(): Promise<void> {
|
||||||
this.pinnedReposProps.repos = [];
|
this.pinnedReposProps.repos = [];
|
||||||
this.triggerRender();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.junoClient.getPinnedRepos(
|
const response = await this.junoClient.getPinnedRepos(
|
||||||
this.container.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope
|
this.props.explorer.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
||||||
throw new Error(`Received HTTP ${response.status} when fetching pinned repos`);
|
throw new Error(`Received HTTP ${response.status} when fetching pinned repos`);
|
||||||
}
|
}
|
||||||
@@ -305,7 +353,6 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.pinnedReposProps.repos = pinnedRepos;
|
this.pinnedReposProps.repos = pinnedRepos;
|
||||||
this.triggerRender();
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, "GitHubReposPane/refreshPinnedReposListItems", "Failed to fetch pinned repos");
|
handleError(error, "GitHubReposPane/refreshPinnedReposListItems", "Failed to fetch pinned repos");
|
||||||
@@ -322,28 +369,85 @@ export class GitHubReposPane extends ContextualPaneBase {
|
|||||||
isLoading: true,
|
isLoading: true,
|
||||||
loadMore: (): Promise<void> => this.loadMoreBranches(item.repo),
|
loadMore: (): Promise<void> => this.loadMoreBranches(item.repo),
|
||||||
};
|
};
|
||||||
|
this.setState({
|
||||||
|
gitHubReposState: {
|
||||||
|
...this.state.gitHubReposState,
|
||||||
|
reposListProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps,
|
||||||
|
branchesProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.branchesProps,
|
||||||
|
[GitHubUtils.toRepoFullName(item.repo.owner, item.repo.name)]: this.branchesProps[item.key],
|
||||||
|
},
|
||||||
|
pinnedReposProps: {
|
||||||
|
repos: this.pinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
unpinnedReposProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.unpinnedReposProps,
|
||||||
|
repos: this.unpinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
this.loadMoreBranches(item.repo);
|
this.loadMoreBranches(item.repo);
|
||||||
|
} else {
|
||||||
|
if (this.isAddedRepo === false) {
|
||||||
|
this.setState({
|
||||||
|
gitHubReposState: {
|
||||||
|
...this.state.gitHubReposState,
|
||||||
|
reposListProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps,
|
||||||
|
pinnedReposProps: {
|
||||||
|
repos: this.pinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
unpinnedReposProps: {
|
||||||
|
...this.state.gitHubReposState.reposListProps.unpinnedReposProps,
|
||||||
|
repos: this.unpinnedReposProps.repos,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.isAddedRepo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async refreshUnpinnedRepoListItems(): Promise<void> {
|
private async refreshUnpinnedRepoListItems(): Promise<void> {
|
||||||
this.allGitHubRepos = [];
|
this.allGitHubRepos = [];
|
||||||
this.allGitHubReposLastPageInfo = undefined;
|
this.allGitHubReposLastPageInfo = undefined;
|
||||||
this.unpinnedReposProps.repos = [];
|
this.unpinnedReposProps.repos = [];
|
||||||
|
|
||||||
this.loadMoreUnpinnedRepos();
|
this.loadMoreUnpinnedRepos();
|
||||||
}
|
}
|
||||||
|
|
||||||
private connectToGitHub(scope: string): void {
|
private connectToGitHub(scope: string): void {
|
||||||
this.isExecuting(true);
|
this.setState({
|
||||||
|
isExecuting: true,
|
||||||
|
});
|
||||||
TelemetryProcessor.trace(Action.NotebooksGitHubAuthorize, ActionModifiers.Mark, {
|
TelemetryProcessor.trace(Action.NotebooksGitHubAuthorize, ActionModifiers.Mark, {
|
||||||
dataExplorerArea: Areas.Notebook,
|
dataExplorerArea: Areas.Notebook,
|
||||||
scopesSelected: scope,
|
scopesSelected: scope,
|
||||||
});
|
});
|
||||||
this.container.notebookManager?.gitHubOAuthService.startOAuth(scope);
|
this.props.explorer.notebookManager?.gitHubOAuthService.startOAuth(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private triggerRender(): void {
|
render(): JSX.Element {
|
||||||
this.gitHubReposAdapter.triggerRender();
|
return (
|
||||||
|
<form className="panelFormWrapper">
|
||||||
|
{this.state.errorMessage && (
|
||||||
|
<PanelInfoErrorComponent
|
||||||
|
message={this.state.errorMessage}
|
||||||
|
messageType="error"
|
||||||
|
showErrorDetails={this.state.showErrorDetails}
|
||||||
|
openNotificationConsole={this.props.openNotificationConsole}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="panelMainContent" style={ContentMainStyle}>
|
||||||
|
<GitHubReposComponent {...this.state.gitHubReposState} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{this.state.isExecuting && <PanelLoadingScreen />}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ export const LoadQueryPane: FunctionComponent<LoadQueryPaneProps> = ({
|
|||||||
|
|
||||||
const title = "Load Query";
|
const title = "Load Query";
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: explorer,
|
expandConsole: () => explorer.expandConsole(),
|
||||||
formError: formError,
|
formError: formError,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "loadQueryPane",
|
id: "loadQueryPane",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
exports[`Load Query Pane should render Default properly 1`] = `
|
exports[`Load Query Pane should render Default properly 1`] = `
|
||||||
<GenericRightPaneComponent
|
<GenericRightPaneComponent
|
||||||
container={Object {}}
|
expandConsole={[Function]}
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="loadQueryPane"
|
id="loadQueryPane"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import AddCollectionPaneTemplate from "./AddCollectionPane.html";
|
import AddCollectionPaneTemplate from "./AddCollectionPane.html";
|
||||||
import AddDatabasePaneTemplate from "./AddDatabasePane.html";
|
import AddDatabasePaneTemplate from "./AddDatabasePane.html";
|
||||||
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
|
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
|
||||||
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
|
||||||
import GraphStylingPaneTemplate from "./GraphStylingPane.html";
|
import GraphStylingPaneTemplate from "./GraphStylingPane.html";
|
||||||
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html";
|
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html";
|
||||||
import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html";
|
import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html";
|
||||||
@@ -63,12 +62,3 @@ export class CassandraAddCollectionPaneComponent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GitHubReposPaneComponent {
|
|
||||||
constructor() {
|
|
||||||
return {
|
|
||||||
viewModel: PaneComponent,
|
|
||||||
template: GitHubReposPaneTemplate,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
& > * {
|
& > :not(.collapsibleSection) {
|
||||||
margin-bottom: @DefaultSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
|
|
||||||
& > * {
|
& > :not(:last-child) {
|
||||||
margin-bottom: @SmallSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
font-size: @mediumFontSize;
|
font-size: @mediumFontSize;
|
||||||
width: @mediumFontSize;
|
width: @mediumFontSize;
|
||||||
margin: auto 0 auto @SmallSpace;
|
margin: auto 0 auto @SmallSpace;
|
||||||
color: @InfoIconColor;
|
|
||||||
cursor: default;
|
cursor: default;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
@@ -49,10 +48,6 @@
|
|||||||
font-size: @mediumFontSize;
|
font-size: @mediumFontSize;
|
||||||
padding: 0 @LargeSpace 0 @SmallSpace;
|
padding: 0 @LargeSpace 0 @SmallSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsibleSection {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +94,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panelFooter {
|
.panelFooter {
|
||||||
padding: 20px 34px;
|
padding: 16px 34px;
|
||||||
border-top: solid 1px #bbbbbb;
|
border-top: solid 1px #bbbbbb;
|
||||||
|
|
||||||
& button {
|
& button {
|
||||||
@@ -123,8 +118,8 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelGroupSpacing > * {
|
.panelGroupSpacing > :not(:last-child) {
|
||||||
margin-bottom: @SmallSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
}
|
||||||
.fileUpload {
|
.fileUpload {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@@ -170,3 +165,6 @@
|
|||||||
.column-select-view {
|
.column-select-view {
|
||||||
margin: 20px 0px 0px 0px;
|
margin: 20px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
.panelSeparator::before {
|
||||||
|
background-color: #edebe9;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
formError && (
|
formError && (
|
||||||
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="start">
|
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="center">
|
||||||
{icon}
|
{icon}
|
||||||
<span className="panelWarningErrorDetailsLinkContainer">
|
<span className="panelWarningErrorDetailsLinkContainer">
|
||||||
<Text className="panelWarningErrorMessage" variant="small" data-testid="panelmessage">
|
<Text className="panelWarningErrorMessage" variant="small" data-testid="panelmessage">
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const props: GenericRightPaneProps = {
|
const props: GenericRightPaneProps = {
|
||||||
container: container,
|
|
||||||
formError: formError,
|
formError: formError,
|
||||||
formErrorDetail: formErrorDetail,
|
formErrorDetail: formErrorDetail,
|
||||||
id: "publishnotebookpane",
|
id: "publishnotebookpane",
|
||||||
@@ -167,6 +166,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
|||||||
submitButtonText: "Publish",
|
submitButtonText: "Publish",
|
||||||
onSubmit: () => submit(),
|
onSubmit: () => submit(),
|
||||||
onClose: closePanel,
|
onClose: closePanel,
|
||||||
|
expandConsole: () => container.expandConsole(),
|
||||||
isSubmitButtonHidden: !isCodeOfConductAccepted,
|
isSubmitButtonHidden: !isCodeOfConductAccepted,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { fireEvent, render, screen } from "@testing-library/react";
|
import { fireEvent, render, screen } from "@testing-library/react";
|
||||||
import { mount, ReactWrapper } from "enzyme";
|
import { mount, ReactWrapper } from "enzyme";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { RightPaneForm } from "./RightPaneForm";
|
import { RightPaneForm } from "./RightPaneForm";
|
||||||
|
|
||||||
const onClose = jest.fn();
|
const onClose = jest.fn();
|
||||||
const onSubmit = jest.fn();
|
const onSubmit = jest.fn();
|
||||||
|
const expandConsole = jest.fn();
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
closePanel: (): void => undefined,
|
closePanel: (): void => undefined,
|
||||||
container: new Explorer(),
|
expandConsole,
|
||||||
formError: "",
|
formError: "",
|
||||||
formErrorDetail: "",
|
formErrorDetail: "",
|
||||||
id: "loadQueryPane",
|
id: "loadQueryPane",
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { IconButton } from "office-ui-fabric-react/lib/Button";
|
import { IconButton } from "office-ui-fabric-react/lib/Button";
|
||||||
import React, { FunctionComponent, ReactNode } from "react";
|
import React, { FunctionComponent, ReactNode } from "react";
|
||||||
import { KeyCodes } from "../../../Common/Constants";
|
import { KeyCodes } from "../../../Common/Constants";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { PanelFooterComponent } from "../PanelFooterComponent";
|
import { PanelFooterComponent } from "../PanelFooterComponent";
|
||||||
import { PanelInfoErrorComponent, PanelInfoErrorProps } from "../PanelInfoErrorComponent";
|
import { PanelInfoErrorComponent, PanelInfoErrorProps } from "../PanelInfoErrorComponent";
|
||||||
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
||||||
|
|
||||||
export interface RightPaneFormProps {
|
export interface RightPaneFormProps {
|
||||||
container: Explorer;
|
expandConsole: () => void;
|
||||||
formError: string;
|
formError: string;
|
||||||
formErrorDetail: string;
|
formErrorDetail: string;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -21,7 +20,7 @@ export interface RightPaneFormProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RightPaneForm: FunctionComponent<RightPaneFormProps> = ({
|
export const RightPaneForm: FunctionComponent<RightPaneFormProps> = ({
|
||||||
container,
|
expandConsole,
|
||||||
formError,
|
formError,
|
||||||
formErrorDetail,
|
formErrorDetail,
|
||||||
id,
|
id,
|
||||||
@@ -70,16 +69,12 @@ export const RightPaneForm: FunctionComponent<RightPaneFormProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showErrorDetail = (): void => {
|
|
||||||
container.expandConsole();
|
|
||||||
};
|
|
||||||
|
|
||||||
const panelInfoErrorProps: PanelInfoErrorProps = {
|
const panelInfoErrorProps: PanelInfoErrorProps = {
|
||||||
messageType: "error",
|
messageType: "error",
|
||||||
message: formError,
|
message: formError,
|
||||||
formError: formError !== "",
|
formError: formError !== "",
|
||||||
showErrorDetails: formErrorDetail !== "",
|
showErrorDetails: formErrorDetail !== "",
|
||||||
openNotificationConsole: showErrorDetail,
|
openNotificationConsole: expandConsole,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,504 +3,7 @@
|
|||||||
exports[`Load Query Pane should render Default properly 1`] = `
|
exports[`Load Query Pane should render Default properly 1`] = `
|
||||||
<RightPaneForm
|
<RightPaneForm
|
||||||
closePanel={[Function]}
|
closePanel={[Function]}
|
||||||
container={
|
expandConsole={[MockFunction]}
|
||||||
Explorer {
|
|
||||||
"_closeModalDialog": [Function],
|
|
||||||
"_closeSynapseLinkModalDialog": [Function],
|
|
||||||
"_isAfecFeatureRegistered": [Function],
|
|
||||||
"_isInitializingNotebooks": false,
|
|
||||||
"_panes": Array [
|
|
||||||
AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"_refreshSparkEnabledStateForAccount": [Function],
|
|
||||||
"_resetNotebookWorkspace": [Function],
|
|
||||||
"addCollectionPane": AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addCollectionText": [Function],
|
|
||||||
"addDatabasePane": AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addDatabaseText": [Function],
|
|
||||||
"arcadiaToken": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canSaveQueries": [Function],
|
|
||||||
"cassandraAddCollectionPane": CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"clickHostedAccountSwitch": [Function],
|
|
||||||
"clickHostedDirectorySwitch": [Function],
|
|
||||||
"closeDialog": undefined,
|
|
||||||
"closeSidePanel": undefined,
|
|
||||||
"collapsedResourceTreeWidth": 36,
|
|
||||||
"collectionCreationDefaults": Object {
|
|
||||||
"storage": "100",
|
|
||||||
"throughput": Object {
|
|
||||||
"fixed": 400,
|
|
||||||
"shared": 400,
|
|
||||||
"unlimited": 400,
|
|
||||||
"unlimitedmax": 1000000,
|
|
||||||
"unlimitedmin": 400,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"collectionTitle": [Function],
|
|
||||||
"collectionTreeNodeAltText": [Function],
|
|
||||||
"commandBarComponentAdapter": CommandBarComponentAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"isNotebookTabActive": [Function],
|
|
||||||
"parameters": [Function],
|
|
||||||
"tabsButtons": Array [],
|
|
||||||
},
|
|
||||||
"databaseAccount": [Function],
|
|
||||||
"databases": [Function],
|
|
||||||
"defaultExperience": [Function],
|
|
||||||
"deleteCollectionText": [Function],
|
|
||||||
"deleteDatabaseText": [Function],
|
|
||||||
"graphStylingPane": GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"hasStorageAnalyticsAfecFeature": [Function],
|
|
||||||
"isAccountReady": [Function],
|
|
||||||
"isAutoscaleDefaultEnabled": [Function],
|
|
||||||
"isEnableMongoCapabilityPresent": [Function],
|
|
||||||
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
|
||||||
"isGitHubPaneEnabled": [Function],
|
|
||||||
"isHostedDataExplorerEnabled": [Function],
|
|
||||||
"isLeftPaneExpanded": [Function],
|
|
||||||
"isMongoIndexingEnabled": [Function],
|
|
||||||
"isNotebookEnabled": [Function],
|
|
||||||
"isNotebooksEnabledForAccount": [Function],
|
|
||||||
"isPublishNotebookPaneEnabled": [Function],
|
|
||||||
"isResourceTokenCollectionNodeSelected": [Function],
|
|
||||||
"isRightPanelV2Enabled": [Function],
|
|
||||||
"isSchemaEnabled": [Function],
|
|
||||||
"isServerlessEnabled": [Function],
|
|
||||||
"isSparkEnabled": [Function],
|
|
||||||
"isSparkEnabledForAccount": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTabsContentExpanded": [Function],
|
|
||||||
"memoryUsageInfo": [Function],
|
|
||||||
"notebookBasePath": [Function],
|
|
||||||
"notebookServerInfo": [Function],
|
|
||||||
"onRefreshDatabasesKeyPress": [Function],
|
|
||||||
"onRefreshResourcesClick": [Function],
|
|
||||||
"onSwitchToConnectionString": [Function],
|
|
||||||
"openDialog": undefined,
|
|
||||||
"openSidePanel": undefined,
|
|
||||||
"provideFeedbackEmail": [Function],
|
|
||||||
"queriesClient": QueriesClient {
|
|
||||||
"container": [Circular],
|
|
||||||
},
|
|
||||||
"refreshDatabaseAccount": [Function],
|
|
||||||
"refreshNotebookList": [Function],
|
|
||||||
"refreshTreeTitle": [Function],
|
|
||||||
"resourceTokenCollection": [Function],
|
|
||||||
"resourceTokenCollectionId": [Function],
|
|
||||||
"resourceTokenDatabaseId": [Function],
|
|
||||||
"resourceTokenPartitionKey": [Function],
|
|
||||||
"resourceTree": ResourceTreeAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"copyNotebook": [Function],
|
|
||||||
"databaseCollectionIdMap": Map {},
|
|
||||||
"koSubsCollectionIdMap": Map {},
|
|
||||||
"koSubsDatabaseIdMap": Map {},
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {
|
|
||||||
"container": [Circular],
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"selectedDatabaseId": [Function],
|
|
||||||
"selectedNode": [Function],
|
|
||||||
"setInProgressConsoleDataIdToBeDeleted": undefined,
|
|
||||||
"setIsNotificationConsoleExpanded": undefined,
|
|
||||||
"setNotificationConsoleData": undefined,
|
|
||||||
"signInAad": [Function],
|
|
||||||
"sparkClusterConnectionInfo": [Function],
|
|
||||||
"splitter": Splitter {
|
|
||||||
"bounds": Object {
|
|
||||||
"max": 400,
|
|
||||||
"min": 240,
|
|
||||||
},
|
|
||||||
"direction": "vertical",
|
|
||||||
"isCollapsed": [Function],
|
|
||||||
"leftSideId": "resourcetree",
|
|
||||||
"onResizeStart": [Function],
|
|
||||||
"onResizeStop": [Function],
|
|
||||||
"splitterId": "h_splitter1",
|
|
||||||
},
|
|
||||||
"tabsManager": TabsManager {
|
|
||||||
"activeTab": [Function],
|
|
||||||
"openedTabs": [Function],
|
|
||||||
},
|
|
||||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="loadQueryPane"
|
id="loadQueryPane"
|
||||||
@@ -1554,7 +1057,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="Close pane"
|
aria-label="Close pane"
|
||||||
className="ms-Button ms-Button--icon closePaneBtn root-104"
|
className="ms-Button ms-Button--icon closePaneBtn root-40"
|
||||||
data-is-focusable={true}
|
data-is-focusable={true}
|
||||||
data-testid="closePaneBtn"
|
data-testid="closePaneBtn"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@@ -1568,16 +1071,16 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="ms-Button-flexContainer flexContainer-105"
|
className="ms-Button-flexContainer flexContainer-41"
|
||||||
data-automationid="splitbuttonprimary"
|
data-automationid="splitbuttonprimary"
|
||||||
>
|
>
|
||||||
<Component
|
<Component
|
||||||
className="ms-Button-icon icon-107"
|
className="ms-Button-icon icon-43"
|
||||||
iconName="Cancel"
|
iconName="Cancel"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="ms-Icon root-37 css-112 ms-Button-icon icon-107"
|
className="ms-Icon root-37 css-48 ms-Button-icon icon-43"
|
||||||
data-icon-name="Cancel"
|
data-icon-name="Cancel"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
style={
|
style={
|
||||||
@@ -1600,7 +1103,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
|||||||
formError={false}
|
formError={false}
|
||||||
message=""
|
message=""
|
||||||
messageType="error"
|
messageType="error"
|
||||||
openNotificationConsole={[Function]}
|
openNotificationConsole={[MockFunction]}
|
||||||
showErrorDetails={false}
|
showErrorDetails={false}
|
||||||
/>
|
/>
|
||||||
<form
|
<form
|
||||||
@@ -3294,7 +2797,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="Load"
|
aria-label="Load"
|
||||||
className="ms-Button ms-Button--primary root-113"
|
className="ms-Button ms-Button--primary root-49"
|
||||||
data-is-focusable={true}
|
data-is-focusable={true}
|
||||||
data-testid="submit"
|
data-testid="submit"
|
||||||
id="sidePanelOkButton"
|
id="sidePanelOkButton"
|
||||||
@@ -3307,14 +2810,14 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
|||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="ms-Button-flexContainer flexContainer-105"
|
className="ms-Button-flexContainer flexContainer-41"
|
||||||
data-automationid="splitbuttonprimary"
|
data-automationid="splitbuttonprimary"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="ms-Button-textContainer textContainer-106"
|
className="ms-Button-textContainer textContainer-42"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="ms-Button-label label-114"
|
className="ms-Button-label label-50"
|
||||||
id="id__3"
|
id="id__3"
|
||||||
key="id__3"
|
key="id__3"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const SaveQueryPane: FunctionComponent<SaveQueryPaneProps> = ({
|
|||||||
const title = "Save Query";
|
const title = "Save Query";
|
||||||
const { canSaveQueries } = explorer;
|
const { canSaveQueries } = explorer;
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: explorer,
|
expandConsole: () => explorer.expandConsole(),
|
||||||
formError: formError,
|
formError: formError,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "saveQueryPane",
|
id: "saveQueryPane",
|
||||||
|
|||||||
@@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
exports[`Save Query Pane should render Default properly 1`] = `
|
exports[`Save Query Pane should render Default properly 1`] = `
|
||||||
<GenericRightPaneComponent
|
<GenericRightPaneComponent
|
||||||
container={
|
expandConsole={[Function]}
|
||||||
Object {
|
|
||||||
"canSaveQueries": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="saveQueryPane"
|
id="saveQueryPane"
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import { shallow } from "enzyme";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { DatabaseAccount } from "../../../Contracts/DataModels";
|
import { DatabaseAccount } from "../../../Contracts/DataModels";
|
||||||
import { updateUserContext } from "../../../UserContext";
|
import { updateUserContext } from "../../../UserContext";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { SettingsPane } from "./SettingsPane";
|
import { SettingsPane } from "./SettingsPane";
|
||||||
const props = {
|
const props = {
|
||||||
explorer: new Explorer(),
|
expandConsole: (): void => undefined,
|
||||||
closePanel: (): void => undefined,
|
closePanel: (): void => undefined,
|
||||||
};
|
};
|
||||||
describe("Settings Pane", () => {
|
describe("Settings Pane", () => {
|
||||||
|
|||||||
@@ -7,16 +7,15 @@ import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility"
|
|||||||
import * as StringUtility from "../../../Shared/StringUtility";
|
import * as StringUtility from "../../../Shared/StringUtility";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
|
|
||||||
export interface SettingsPaneProps {
|
export interface SettingsPaneProps {
|
||||||
explorer: Explorer;
|
expandConsole: () => void;
|
||||||
closePanel: () => void;
|
closePanel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SettingsPane: FunctionComponent<SettingsPaneProps> = ({
|
export const SettingsPane: FunctionComponent<SettingsPaneProps> = ({
|
||||||
explorer: container,
|
expandConsole,
|
||||||
closePanel,
|
closePanel,
|
||||||
}: SettingsPaneProps) => {
|
}: SettingsPaneProps) => {
|
||||||
const [formErrors, setFormErrors] = useState<string>("");
|
const [formErrors, setFormErrors] = useState<string>("");
|
||||||
@@ -104,7 +103,7 @@ export const SettingsPane: FunctionComponent<SettingsPaneProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const genericPaneProps: RightPaneFormProps = {
|
const genericPaneProps: RightPaneFormProps = {
|
||||||
container,
|
expandConsole,
|
||||||
formError: formErrors,
|
formError: formErrors,
|
||||||
formErrorDetail: "",
|
formErrorDetail: "",
|
||||||
id: "settingspane",
|
id: "settingspane",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -92,7 +92,6 @@ export const StringInputPane: FunctionComponent<StringInputPanelProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: container,
|
|
||||||
formError: formErrors,
|
formError: formErrors,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "stringInputPane",
|
id: "stringInputPane",
|
||||||
@@ -101,6 +100,7 @@ export const StringInputPane: FunctionComponent<StringInputPanelProps> = ({
|
|||||||
submitButtonText: submitButtonLabel,
|
submitButtonText: submitButtonLabel,
|
||||||
onClose: closePanel,
|
onClose: closePanel,
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
|
expandConsole: () => container.expandConsole(),
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<GenericRightPaneComponent {...genericPaneProps}>
|
<GenericRightPaneComponent {...genericPaneProps}>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -328,7 +328,7 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
|||||||
selectedKey={entity.type}
|
selectedKey={entity.type}
|
||||||
entityPropertyPlaceHolder={detailedHelp}
|
entityPropertyPlaceHolder={detailedHelp}
|
||||||
entityValuePlaceholder={entity.entityValuePlaceholder}
|
entityValuePlaceholder={entity.entityValuePlaceholder}
|
||||||
entityValue={entity.value}
|
entityValue={entity.value?.toString()}
|
||||||
isEntityTypeDate={entity.isEntityTypeDate}
|
isEntityTypeDate={entity.isEntityTypeDate}
|
||||||
entityTimeValue={entity.entityTimeValue}
|
entityTimeValue={entity.entityTimeValue}
|
||||||
isEntityValueDisable={entity.isEntityValueDisable}
|
isEntityValueDisable={entity.isEntityValueDisable}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<GenericRightPaneComponent
|
<GenericRightPaneComponent
|
||||||
container={Object {}}
|
expandConsole={[Function]}
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="querySelectPane"
|
id="querySelectPane"
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
|
|||||||
const [isAvailableColumnChecked, setIsAvailableColumnChecked] = useState<boolean>(true);
|
const [isAvailableColumnChecked, setIsAvailableColumnChecked] = useState<boolean>(true);
|
||||||
|
|
||||||
const genericPaneProps: GenericRightPaneProps = {
|
const genericPaneProps: GenericRightPaneProps = {
|
||||||
container: explorer,
|
|
||||||
formError: "",
|
formError: "",
|
||||||
formErrorDetail: "",
|
formErrorDetail: "",
|
||||||
id: "querySelectPane",
|
id: "querySelectPane",
|
||||||
@@ -41,6 +40,7 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
|
|||||||
submitButtonText: "OK",
|
submitButtonText: "OK",
|
||||||
onClose: () => closePanel(),
|
onClose: () => closePanel(),
|
||||||
onSubmit: () => submit(),
|
onSubmit: () => submit(),
|
||||||
|
expandConsole: () => explorer.expandConsole(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = (): void => {
|
const submit = (): void => {
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
||||||
import { Upload } from "../../../Common/Upload/Upload";
|
import { Upload } from "../../../Common/Upload/Upload";
|
||||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
|
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
|
|
||||||
export interface UploadFilePanelProps {
|
export interface UploadFilePanelProps {
|
||||||
explorer: Explorer;
|
expandConsole: () => void;
|
||||||
closePanel: () => void;
|
closePanel: () => void;
|
||||||
uploadFile: (name: string, content: string) => Promise<NotebookContentItem>;
|
uploadFile: (name: string, content: string) => Promise<NotebookContentItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UploadFilePane: FunctionComponent<UploadFilePanelProps> = ({
|
export const UploadFilePane: FunctionComponent<UploadFilePanelProps> = ({
|
||||||
explorer: container,
|
expandConsole,
|
||||||
closePanel,
|
closePanel,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
}: UploadFilePanelProps) => {
|
}: UploadFilePanelProps) => {
|
||||||
@@ -90,7 +89,7 @@ export const UploadFilePane: FunctionComponent<UploadFilePanelProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const genericPaneProps: RightPaneFormProps = {
|
const genericPaneProps: RightPaneFormProps = {
|
||||||
container: container,
|
expandConsole,
|
||||||
formError: formErrors,
|
formError: formErrors,
|
||||||
formErrorDetail: formErrorsDetails,
|
formErrorDetail: formErrorsDetails,
|
||||||
id: "uploadFilePane",
|
id: "uploadFilePane",
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const genericPaneProps: RightPaneFormProps = {
|
const genericPaneProps: RightPaneFormProps = {
|
||||||
container: explorer,
|
expandConsole: () => explorer.expandConsole(),
|
||||||
formError,
|
formError,
|
||||||
formErrorDetail,
|
formErrorDetail,
|
||||||
id: "uploaditemspane",
|
id: "uploaditemspane",
|
||||||
|
|||||||
@@ -2,504 +2,7 @@
|
|||||||
|
|
||||||
exports[`Upload Items Pane should render Default properly 1`] = `
|
exports[`Upload Items Pane should render Default properly 1`] = `
|
||||||
<RightPaneForm
|
<RightPaneForm
|
||||||
container={
|
expandConsole={[Function]}
|
||||||
Explorer {
|
|
||||||
"_closeModalDialog": [Function],
|
|
||||||
"_closeSynapseLinkModalDialog": [Function],
|
|
||||||
"_isAfecFeatureRegistered": [Function],
|
|
||||||
"_isInitializingNotebooks": false,
|
|
||||||
"_panes": Array [
|
|
||||||
AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"_refreshSparkEnabledStateForAccount": [Function],
|
|
||||||
"_resetNotebookWorkspace": [Function],
|
|
||||||
"addCollectionPane": AddCollectionPane {
|
|
||||||
"_isSynapseLinkEnabled": [Function],
|
|
||||||
"autoPilotThroughput": [Function],
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
|
||||||
"collectionIdTitle": [Function],
|
|
||||||
"collectionWithThroughputInShared": [Function],
|
|
||||||
"collectionWithThroughputInSharedTitle": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNew": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseHasSharedOffer": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIds": [Function],
|
|
||||||
"dedicatedRequestUnitsUsageCost": [Function],
|
|
||||||
"displayCollectionThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"formWarnings": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "addcollectionpane",
|
|
||||||
"isAnalyticalStorageOn": [Function],
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFixedStorageSelected": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isNonTableApi": [Function],
|
|
||||||
"isPreferredApiTable": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isSynapseLinkSupported": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"isTryCosmosDBSubscription": [Function],
|
|
||||||
"isUnlimitedStorageSelected": [Function],
|
|
||||||
"largePartitionKey": [Function],
|
|
||||||
"lowerCasePartitionKeyName": [Function],
|
|
||||||
"maxCollectionsReached": [Function],
|
|
||||||
"maxCollectionsReachedMessage": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"partitionKey": [Function],
|
|
||||||
"partitionKeyName": [Function],
|
|
||||||
"partitionKeyPattern": [Function],
|
|
||||||
"partitionKeyPlaceholder": [Function],
|
|
||||||
"partitionKeyTitle": [Function],
|
|
||||||
"partitionKeyVisible": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"shouldCreateMongoWildcardIndex": [Function],
|
|
||||||
"shouldUseDatabaseThroughput": [Function],
|
|
||||||
"showAnalyticalStore": [Function],
|
|
||||||
"showEnableSynapseLink": [Function],
|
|
||||||
"showIndexingOptionsForSharedThroughput": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"storage": [Function],
|
|
||||||
"throughputDatabase": [Function],
|
|
||||||
"throughputMultiPartition": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSinglePartition": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"ttl90DaysEnabled": [Function],
|
|
||||||
"uniqueKeys": [Function],
|
|
||||||
"uniqueKeysPlaceholder": [Function],
|
|
||||||
"uniqueKeysVisible": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"useIndexingForSharedThroughput": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addCollectionText": [Function],
|
|
||||||
"addDatabasePane": AddDatabasePane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"databaseCreateNewShared": [Function],
|
|
||||||
"databaseId": [Function],
|
|
||||||
"databaseIdLabel": [Function],
|
|
||||||
"databaseIdPlaceHolder": [Function],
|
|
||||||
"databaseIdTooltipText": [Function],
|
|
||||||
"databaseLevelThroughputTooltipText": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"freeTierExceedThroughputTooltip": [Function],
|
|
||||||
"id": "adddatabasepane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"maxAutoPilotThroughputSet": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"maxThroughputRUText": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"onMoreDetailsKeyPress": [Function],
|
|
||||||
"requestUnitsUsageCost": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"showUpsellMessage": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"upsellAnchorText": [Function],
|
|
||||||
"upsellAnchorUrl": [Function],
|
|
||||||
"upsellMessage": [Function],
|
|
||||||
"upsellMessageAriaLabel": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"addDatabaseText": [Function],
|
|
||||||
"arcadiaToken": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canSaveQueries": [Function],
|
|
||||||
"cassandraAddCollectionPane": CassandraAddCollectionPane {
|
|
||||||
"autoPilotUsageCost": [Function],
|
|
||||||
"canConfigureThroughput": [Function],
|
|
||||||
"canExceedMaximumValue": [Function],
|
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
|
||||||
"costsVisible": [Function],
|
|
||||||
"createTableQuery": [Function],
|
|
||||||
"dedicateTableThroughput": [Function],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"id": "cassandraaddcollectionpane",
|
|
||||||
"isAutoPilotSelected": [Function],
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isFreeTierAccount": [Function],
|
|
||||||
"isSharedAutoPilotSelected": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"keyspaceCreateNew": [Function],
|
|
||||||
"keyspaceHasSharedOffer": [Function],
|
|
||||||
"keyspaceId": [Function],
|
|
||||||
"keyspaceIds": [Function],
|
|
||||||
"keyspaceOffers": Map {},
|
|
||||||
"keyspaceThroughput": [Function],
|
|
||||||
"maxThroughputRU": [Function],
|
|
||||||
"minThroughputRU": [Function],
|
|
||||||
"requestUnitsUsageCostDedicated": [Function],
|
|
||||||
"requestUnitsUsageCostShared": [Function],
|
|
||||||
"ruToolTipText": [Function],
|
|
||||||
"selectedAutoPilotThroughput": [Function],
|
|
||||||
"sharedAutoPilotThroughput": [Function],
|
|
||||||
"sharedThroughputRangeText": [Function],
|
|
||||||
"sharedThroughputSpendAck": [Function],
|
|
||||||
"sharedThroughputSpendAckText": [Function],
|
|
||||||
"sharedThroughputSpendAckVisible": [Function],
|
|
||||||
"tableId": [Function],
|
|
||||||
"throughput": [Function],
|
|
||||||
"throughputRangeText": [Function],
|
|
||||||
"throughputSpendAck": [Function],
|
|
||||||
"throughputSpendAckText": [Function],
|
|
||||||
"throughputSpendAckVisible": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"userTableQuery": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"clickHostedAccountSwitch": [Function],
|
|
||||||
"clickHostedDirectorySwitch": [Function],
|
|
||||||
"closeDialog": undefined,
|
|
||||||
"closeSidePanel": undefined,
|
|
||||||
"collapsedResourceTreeWidth": 36,
|
|
||||||
"collectionCreationDefaults": Object {
|
|
||||||
"storage": "100",
|
|
||||||
"throughput": Object {
|
|
||||||
"fixed": 400,
|
|
||||||
"shared": 400,
|
|
||||||
"unlimited": 400,
|
|
||||||
"unlimitedmax": 1000000,
|
|
||||||
"unlimitedmin": 400,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"collectionTitle": [Function],
|
|
||||||
"collectionTreeNodeAltText": [Function],
|
|
||||||
"commandBarComponentAdapter": CommandBarComponentAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"isNotebookTabActive": [Function],
|
|
||||||
"parameters": [Function],
|
|
||||||
"tabsButtons": Array [],
|
|
||||||
},
|
|
||||||
"databaseAccount": [Function],
|
|
||||||
"databases": [Function],
|
|
||||||
"defaultExperience": [Function],
|
|
||||||
"deleteCollectionText": [Function],
|
|
||||||
"deleteDatabaseText": [Function],
|
|
||||||
"graphStylingPane": GraphStylingPane {
|
|
||||||
"container": [Circular],
|
|
||||||
"firstFieldHasFocus": [Function],
|
|
||||||
"formErrors": [Function],
|
|
||||||
"formErrorsDetails": [Function],
|
|
||||||
"graphConfigUIData": Object {
|
|
||||||
"nodeCaptionChoice": [Function],
|
|
||||||
"nodeColorKeyChoice": [Function],
|
|
||||||
"nodeIconChoice": [Function],
|
|
||||||
"nodeIconSet": [Function],
|
|
||||||
"nodeProperties": [Function],
|
|
||||||
"nodePropertiesWithNone": [Function],
|
|
||||||
"showNeighborType": [Function],
|
|
||||||
},
|
|
||||||
"id": "graphstylingpane",
|
|
||||||
"isExecuting": [Function],
|
|
||||||
"isTemplateReady": [Function],
|
|
||||||
"title": [Function],
|
|
||||||
"visible": [Function],
|
|
||||||
},
|
|
||||||
"hasStorageAnalyticsAfecFeature": [Function],
|
|
||||||
"isAccountReady": [Function],
|
|
||||||
"isAutoscaleDefaultEnabled": [Function],
|
|
||||||
"isEnableMongoCapabilityPresent": [Function],
|
|
||||||
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
|
||||||
"isGitHubPaneEnabled": [Function],
|
|
||||||
"isHostedDataExplorerEnabled": [Function],
|
|
||||||
"isLeftPaneExpanded": [Function],
|
|
||||||
"isMongoIndexingEnabled": [Function],
|
|
||||||
"isNotebookEnabled": [Function],
|
|
||||||
"isNotebooksEnabledForAccount": [Function],
|
|
||||||
"isPublishNotebookPaneEnabled": [Function],
|
|
||||||
"isResourceTokenCollectionNodeSelected": [Function],
|
|
||||||
"isRightPanelV2Enabled": [Function],
|
|
||||||
"isSchemaEnabled": [Function],
|
|
||||||
"isServerlessEnabled": [Function],
|
|
||||||
"isSparkEnabled": [Function],
|
|
||||||
"isSparkEnabledForAccount": [Function],
|
|
||||||
"isSynapseLinkUpdating": [Function],
|
|
||||||
"isTabsContentExpanded": [Function],
|
|
||||||
"memoryUsageInfo": [Function],
|
|
||||||
"notebookBasePath": [Function],
|
|
||||||
"notebookServerInfo": [Function],
|
|
||||||
"onRefreshDatabasesKeyPress": [Function],
|
|
||||||
"onRefreshResourcesClick": [Function],
|
|
||||||
"onSwitchToConnectionString": [Function],
|
|
||||||
"openDialog": undefined,
|
|
||||||
"openSidePanel": undefined,
|
|
||||||
"provideFeedbackEmail": [Function],
|
|
||||||
"queriesClient": QueriesClient {
|
|
||||||
"container": [Circular],
|
|
||||||
},
|
|
||||||
"refreshDatabaseAccount": [Function],
|
|
||||||
"refreshNotebookList": [Function],
|
|
||||||
"refreshTreeTitle": [Function],
|
|
||||||
"resourceTokenCollection": [Function],
|
|
||||||
"resourceTokenCollectionId": [Function],
|
|
||||||
"resourceTokenDatabaseId": [Function],
|
|
||||||
"resourceTokenPartitionKey": [Function],
|
|
||||||
"resourceTree": ResourceTreeAdapter {
|
|
||||||
"container": [Circular],
|
|
||||||
"copyNotebook": [Function],
|
|
||||||
"databaseCollectionIdMap": Map {},
|
|
||||||
"koSubsCollectionIdMap": Map {},
|
|
||||||
"koSubsDatabaseIdMap": Map {},
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {
|
|
||||||
"container": [Circular],
|
|
||||||
"parameters": [Function],
|
|
||||||
},
|
|
||||||
"selectedDatabaseId": [Function],
|
|
||||||
"selectedNode": [Function],
|
|
||||||
"setInProgressConsoleDataIdToBeDeleted": undefined,
|
|
||||||
"setIsNotificationConsoleExpanded": undefined,
|
|
||||||
"setNotificationConsoleData": undefined,
|
|
||||||
"signInAad": [Function],
|
|
||||||
"sparkClusterConnectionInfo": [Function],
|
|
||||||
"splitter": Splitter {
|
|
||||||
"bounds": Object {
|
|
||||||
"max": 400,
|
|
||||||
"min": 240,
|
|
||||||
},
|
|
||||||
"direction": "vertical",
|
|
||||||
"isCollapsed": [Function],
|
|
||||||
"leftSideId": "resourcetree",
|
|
||||||
"onResizeStart": [Function],
|
|
||||||
"onResizeStop": [Function],
|
|
||||||
"splitterId": "h_splitter1",
|
|
||||||
},
|
|
||||||
"tabsManager": TabsManager {
|
|
||||||
"activeTab": [Function],
|
|
||||||
"openedTabs": [Function],
|
|
||||||
},
|
|
||||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formError=""
|
formError=""
|
||||||
formErrorDetail=""
|
formErrorDetail=""
|
||||||
id="uploaditemspane"
|
id="uploaditemspane"
|
||||||
|
|||||||
@@ -404,6 +404,773 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
|||||||
"defaultExperience": [Function],
|
"defaultExperience": [Function],
|
||||||
"deleteCollectionText": [Function],
|
"deleteCollectionText": [Function],
|
||||||
"deleteDatabaseText": [Function],
|
"deleteDatabaseText": [Function],
|
||||||
|
"gitHubClient": GitHubClient {
|
||||||
|
"errorCallback": [Function],
|
||||||
|
"ocktokit": OctokitWithDefaults {
|
||||||
|
"actions": Object {
|
||||||
|
"addSelectedRepoToOrgSecret": [Function],
|
||||||
|
"cancelWorkflowRun": [Function],
|
||||||
|
"createOrUpdateOrgSecret": [Function],
|
||||||
|
"createOrUpdateRepoSecret": [Function],
|
||||||
|
"createOrUpdateSecretForRepo": [Function],
|
||||||
|
"createRegistrationToken": [Function],
|
||||||
|
"createRegistrationTokenForOrg": [Function],
|
||||||
|
"createRegistrationTokenForRepo": [Function],
|
||||||
|
"createRemoveToken": [Function],
|
||||||
|
"createRemoveTokenForOrg": [Function],
|
||||||
|
"createRemoveTokenForRepo": [Function],
|
||||||
|
"deleteArtifact": [Function],
|
||||||
|
"deleteOrgSecret": [Function],
|
||||||
|
"deleteRepoSecret": [Function],
|
||||||
|
"deleteSecretFromRepo": [Function],
|
||||||
|
"deleteSelfHostedRunnerFromOrg": [Function],
|
||||||
|
"deleteSelfHostedRunnerFromRepo": [Function],
|
||||||
|
"deleteWorkflowRunLogs": [Function],
|
||||||
|
"downloadArtifact": [Function],
|
||||||
|
"downloadJobLogsForWorkflowRun": [Function],
|
||||||
|
"downloadWorkflowJobLogs": [Function],
|
||||||
|
"downloadWorkflowRunLogs": [Function],
|
||||||
|
"getArtifact": [Function],
|
||||||
|
"getJobForWorkflowRun": [Function],
|
||||||
|
"getOrgPublicKey": [Function],
|
||||||
|
"getOrgSecret": [Function],
|
||||||
|
"getPublicKey": [Function],
|
||||||
|
"getRepoPublicKey": [Function],
|
||||||
|
"getRepoSecret": [Function],
|
||||||
|
"getSecret": [Function],
|
||||||
|
"getSelfHostedRunner": [Function],
|
||||||
|
"getSelfHostedRunnerForOrg": [Function],
|
||||||
|
"getSelfHostedRunnerForRepo": [Function],
|
||||||
|
"getWorkflow": [Function],
|
||||||
|
"getWorkflowJob": [Function],
|
||||||
|
"getWorkflowRun": [Function],
|
||||||
|
"getWorkflowRunUsage": [Function],
|
||||||
|
"getWorkflowUsage": [Function],
|
||||||
|
"listArtifactsForRepo": [Function],
|
||||||
|
"listDownloadsForSelfHostedRunnerApplication": [Function],
|
||||||
|
"listJobsForWorkflowRun": [Function],
|
||||||
|
"listOrgSecrets": [Function],
|
||||||
|
"listRepoSecrets": [Function],
|
||||||
|
"listRepoWorkflowRuns": [Function],
|
||||||
|
"listRepoWorkflows": [Function],
|
||||||
|
"listRunnerApplicationsForOrg": [Function],
|
||||||
|
"listRunnerApplicationsForRepo": [Function],
|
||||||
|
"listSecretsForRepo": [Function],
|
||||||
|
"listSelectedReposForOrgSecret": [Function],
|
||||||
|
"listSelfHostedRunnersForOrg": [Function],
|
||||||
|
"listSelfHostedRunnersForRepo": [Function],
|
||||||
|
"listWorkflowJobLogs": [Function],
|
||||||
|
"listWorkflowRunArtifacts": [Function],
|
||||||
|
"listWorkflowRunLogs": [Function],
|
||||||
|
"listWorkflowRuns": [Function],
|
||||||
|
"listWorkflowRunsForRepo": [Function],
|
||||||
|
"reRunWorkflow": [Function],
|
||||||
|
"removeSelectedRepoFromOrgSecret": [Function],
|
||||||
|
"removeSelfHostedRunner": [Function],
|
||||||
|
"setSelectedReposForOrgSecret": [Function],
|
||||||
|
},
|
||||||
|
"activity": Object {
|
||||||
|
"checkRepoIsStarredByAuthenticatedUser": [Function],
|
||||||
|
"checkStarringRepo": [Function],
|
||||||
|
"deleteRepoSubscription": [Function],
|
||||||
|
"deleteThreadSubscription": [Function],
|
||||||
|
"getFeeds": [Function],
|
||||||
|
"getRepoSubscription": [Function],
|
||||||
|
"getThread": [Function],
|
||||||
|
"getThreadSubscription": [Function],
|
||||||
|
"getThreadSubscriptionForAuthenticatedUser": [Function],
|
||||||
|
"listEventsForAuthenticatedUser": [Function],
|
||||||
|
"listEventsForOrg": [Function],
|
||||||
|
"listEventsForUser": [Function],
|
||||||
|
"listFeeds": [Function],
|
||||||
|
"listNotifications": [Function],
|
||||||
|
"listNotificationsForAuthenticatedUser": [Function],
|
||||||
|
"listNotificationsForRepo": [Function],
|
||||||
|
"listOrgEventsForAuthenticatedUser": [Function],
|
||||||
|
"listPublicEvents": [Function],
|
||||||
|
"listPublicEventsForOrg": [Function],
|
||||||
|
"listPublicEventsForRepoNetwork": [Function],
|
||||||
|
"listPublicEventsForUser": [Function],
|
||||||
|
"listPublicOrgEvents": [Function],
|
||||||
|
"listReceivedEventsForUser": [Function],
|
||||||
|
"listReceivedPublicEventsForUser": [Function],
|
||||||
|
"listRepoEvents": [Function],
|
||||||
|
"listRepoNotificationsForAuthenticatedUser": [Function],
|
||||||
|
"listReposStarredByAuthenticatedUser": [Function],
|
||||||
|
"listReposStarredByUser": [Function],
|
||||||
|
"listReposWatchedByUser": [Function],
|
||||||
|
"listStargazersForRepo": [Function],
|
||||||
|
"listWatchedReposForAuthenticatedUser": [Function],
|
||||||
|
"listWatchersForRepo": [Function],
|
||||||
|
"markAsRead": [Function],
|
||||||
|
"markNotificationsAsRead": [Function],
|
||||||
|
"markNotificationsAsReadForRepo": [Function],
|
||||||
|
"markRepoNotificationsAsRead": [Function],
|
||||||
|
"markThreadAsRead": [Function],
|
||||||
|
"setRepoSubscription": [Function],
|
||||||
|
"setThreadSubscription": [Function],
|
||||||
|
"starRepo": [Function],
|
||||||
|
"starRepoForAuthenticatedUser": [Function],
|
||||||
|
"unstarRepo": [Function],
|
||||||
|
"unstarRepoForAuthenticatedUser": [Function],
|
||||||
|
},
|
||||||
|
"apps": Object {
|
||||||
|
"addRepoToInstallation": [Function],
|
||||||
|
"checkAccountIsAssociatedWithAny": [Function],
|
||||||
|
"checkAccountIsAssociatedWithAnyStubbed": [Function],
|
||||||
|
"checkToken": [Function],
|
||||||
|
"createContentAttachment": [Function],
|
||||||
|
"createFromManifest": [Function],
|
||||||
|
"createInstallationAccessToken": [Function],
|
||||||
|
"createInstallationToken": [Function],
|
||||||
|
"deleteAuthorization": [Function],
|
||||||
|
"deleteInstallation": [Function],
|
||||||
|
"deleteToken": [Function],
|
||||||
|
"getAuthenticated": [Function],
|
||||||
|
"getBySlug": [Function],
|
||||||
|
"getInstallation": [Function],
|
||||||
|
"getOrgInstallation": [Function],
|
||||||
|
"getRepoInstallation": [Function],
|
||||||
|
"getSubscriptionPlanForAccount": [Function],
|
||||||
|
"getSubscriptionPlanForAccountStubbed": [Function],
|
||||||
|
"getUserInstallation": [Function],
|
||||||
|
"listAccountsForPlan": [Function],
|
||||||
|
"listAccountsForPlanStubbed": [Function],
|
||||||
|
"listAccountsUserOrOrgOnPlan": [Function],
|
||||||
|
"listAccountsUserOrOrgOnPlanStubbed": [Function],
|
||||||
|
"listInstallationReposForAuthenticatedUser": [Function],
|
||||||
|
"listInstallations": [Function],
|
||||||
|
"listInstallationsForAuthenticatedUser": [Function],
|
||||||
|
"listMarketplacePurchasesForAuthenticatedUser": [Function],
|
||||||
|
"listMarketplacePurchasesForAuthenticatedUserStubbed": [Function],
|
||||||
|
"listPlans": [Function],
|
||||||
|
"listPlansStubbed": [Function],
|
||||||
|
"listRepos": [Function],
|
||||||
|
"listReposAccessibleToInstallation": [Function],
|
||||||
|
"listSubscriptionsForAuthenticatedUser": [Function],
|
||||||
|
"listSubscriptionsForAuthenticatedUserStubbed": [Function],
|
||||||
|
"removeRepoFromInstallation": [Function],
|
||||||
|
"resetToken": [Function],
|
||||||
|
"revokeInstallationAccessToken": [Function],
|
||||||
|
"revokeInstallationToken": [Function],
|
||||||
|
"suspendInstallation": [Function],
|
||||||
|
"unsuspendInstallation": [Function],
|
||||||
|
},
|
||||||
|
"auth": [Function],
|
||||||
|
"checks": Object {
|
||||||
|
"create": [Function],
|
||||||
|
"createSuite": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getSuite": [Function],
|
||||||
|
"listAnnotations": [Function],
|
||||||
|
"listForRef": [Function],
|
||||||
|
"listForSuite": [Function],
|
||||||
|
"listSuitesForRef": [Function],
|
||||||
|
"rerequestSuite": [Function],
|
||||||
|
"setSuitesPreferences": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
},
|
||||||
|
"codeScanning": Object {
|
||||||
|
"getAlert": [Function],
|
||||||
|
"listAlertsForRepo": [Function],
|
||||||
|
},
|
||||||
|
"codesOfConduct": Object {
|
||||||
|
"getAllCodesOfConduct": [Function],
|
||||||
|
"getConductCode": [Function],
|
||||||
|
"getForRepo": [Function],
|
||||||
|
"listConductCodes": [Function],
|
||||||
|
},
|
||||||
|
"emojis": Object {
|
||||||
|
"get": [Function],
|
||||||
|
},
|
||||||
|
"gists": Object {
|
||||||
|
"checkIsStarred": [Function],
|
||||||
|
"create": [Function],
|
||||||
|
"createComment": [Function],
|
||||||
|
"delete": [Function],
|
||||||
|
"deleteComment": [Function],
|
||||||
|
"fork": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getComment": [Function],
|
||||||
|
"getRevision": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listComments": [Function],
|
||||||
|
"listCommits": [Function],
|
||||||
|
"listForUser": [Function],
|
||||||
|
"listForks": [Function],
|
||||||
|
"listPublic": [Function],
|
||||||
|
"listPublicForUser": [Function],
|
||||||
|
"listStarred": [Function],
|
||||||
|
"star": [Function],
|
||||||
|
"unstar": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateComment": [Function],
|
||||||
|
},
|
||||||
|
"git": Object {
|
||||||
|
"createBlob": [Function],
|
||||||
|
"createCommit": [Function],
|
||||||
|
"createRef": [Function],
|
||||||
|
"createTag": [Function],
|
||||||
|
"createTree": [Function],
|
||||||
|
"deleteRef": [Function],
|
||||||
|
"getBlob": [Function],
|
||||||
|
"getCommit": [Function],
|
||||||
|
"getRef": [Function],
|
||||||
|
"getTag": [Function],
|
||||||
|
"getTree": [Function],
|
||||||
|
"listMatchingRefs": [Function],
|
||||||
|
"updateRef": [Function],
|
||||||
|
},
|
||||||
|
"gitignore": Object {
|
||||||
|
"getAllTemplates": [Function],
|
||||||
|
"getTemplate": [Function],
|
||||||
|
"listTemplates": [Function],
|
||||||
|
},
|
||||||
|
"graphql": [Function],
|
||||||
|
"hook": [Function],
|
||||||
|
"interactions": Object {
|
||||||
|
"addOrUpdateRestrictionsForOrg": [Function],
|
||||||
|
"addOrUpdateRestrictionsForRepo": [Function],
|
||||||
|
"getRestrictionsForOrg": [Function],
|
||||||
|
"getRestrictionsForRepo": [Function],
|
||||||
|
"removeRestrictionsForOrg": [Function],
|
||||||
|
"removeRestrictionsForRepo": [Function],
|
||||||
|
"setRestrictionsForOrg": [Function],
|
||||||
|
"setRestrictionsForRepo": [Function],
|
||||||
|
},
|
||||||
|
"issues": Object {
|
||||||
|
"addAssignees": [Function],
|
||||||
|
"addLabels": [Function],
|
||||||
|
"checkAssignee": [Function],
|
||||||
|
"checkUserCanBeAssigned": [Function],
|
||||||
|
"create": [Function],
|
||||||
|
"createComment": [Function],
|
||||||
|
"createLabel": [Function],
|
||||||
|
"createMilestone": [Function],
|
||||||
|
"deleteComment": [Function],
|
||||||
|
"deleteLabel": [Function],
|
||||||
|
"deleteMilestone": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getComment": [Function],
|
||||||
|
"getEvent": [Function],
|
||||||
|
"getLabel": [Function],
|
||||||
|
"getMilestone": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listAssignees": [Function],
|
||||||
|
"listComments": [Function],
|
||||||
|
"listCommentsForRepo": [Function],
|
||||||
|
"listEvents": [Function],
|
||||||
|
"listEventsForRepo": [Function],
|
||||||
|
"listEventsForTimeline": [Function],
|
||||||
|
"listForAuthenticatedUser": [Function],
|
||||||
|
"listForOrg": [Function],
|
||||||
|
"listForRepo": [Function],
|
||||||
|
"listLabelsForMilestone": [Function],
|
||||||
|
"listLabelsForRepo": [Function],
|
||||||
|
"listLabelsOnIssue": [Function],
|
||||||
|
"listMilestones": [Function],
|
||||||
|
"listMilestonesForRepo": [Function],
|
||||||
|
"lock": [Function],
|
||||||
|
"removeAllLabels": [Function],
|
||||||
|
"removeAssignees": [Function],
|
||||||
|
"removeLabel": [Function],
|
||||||
|
"removeLabels": [Function],
|
||||||
|
"replaceAllLabels": [Function],
|
||||||
|
"replaceLabels": [Function],
|
||||||
|
"setLabels": [Function],
|
||||||
|
"unlock": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateComment": [Function],
|
||||||
|
"updateLabel": [Function],
|
||||||
|
"updateMilestone": [Function],
|
||||||
|
},
|
||||||
|
"licenses": Object {
|
||||||
|
"get": [Function],
|
||||||
|
"getAllCommonlyUsed": [Function],
|
||||||
|
"getForRepo": [Function],
|
||||||
|
"listCommonlyUsed": [Function],
|
||||||
|
},
|
||||||
|
"log": Object {
|
||||||
|
"debug": [Function],
|
||||||
|
"error": [Function],
|
||||||
|
"info": [Function],
|
||||||
|
"warn": [Function],
|
||||||
|
},
|
||||||
|
"markdown": Object {
|
||||||
|
"render": [Function],
|
||||||
|
"renderRaw": [Function],
|
||||||
|
},
|
||||||
|
"meta": Object {
|
||||||
|
"get": [Function],
|
||||||
|
},
|
||||||
|
"migrations": Object {
|
||||||
|
"cancelImport": [Function],
|
||||||
|
"deleteArchiveForAuthenticatedUser": [Function],
|
||||||
|
"deleteArchiveForOrg": [Function],
|
||||||
|
"downloadArchiveForOrg": [Function],
|
||||||
|
"getArchiveForAuthenticatedUser": [Function],
|
||||||
|
"getCommitAuthors": [Function],
|
||||||
|
"getImportProgress": [Function],
|
||||||
|
"getImportStatus": [Function],
|
||||||
|
"getLargeFiles": [Function],
|
||||||
|
"getStatusForAuthenticatedUser": [Function],
|
||||||
|
"getStatusForOrg": [Function],
|
||||||
|
"listForAuthenticatedUser": [Function],
|
||||||
|
"listForOrg": [Function],
|
||||||
|
"listReposForOrg": [Function],
|
||||||
|
"listReposForUser": [Function],
|
||||||
|
"mapCommitAuthor": [Function],
|
||||||
|
"setLfsPreference": [Function],
|
||||||
|
"startForAuthenticatedUser": [Function],
|
||||||
|
"startForOrg": [Function],
|
||||||
|
"startImport": [Function],
|
||||||
|
"unlockRepoForAuthenticatedUser": [Function],
|
||||||
|
"unlockRepoForOrg": [Function],
|
||||||
|
"updateImport": [Function],
|
||||||
|
},
|
||||||
|
"orgs": Object {
|
||||||
|
"addOrUpdateMembership": [Function],
|
||||||
|
"blockUser": [Function],
|
||||||
|
"checkBlockedUser": [Function],
|
||||||
|
"checkMembership": [Function],
|
||||||
|
"checkMembershipForUser": [Function],
|
||||||
|
"checkPublicMembership": [Function],
|
||||||
|
"checkPublicMembershipForUser": [Function],
|
||||||
|
"concealMembership": [Function],
|
||||||
|
"convertMemberToOutsideCollaborator": [Function],
|
||||||
|
"createHook": [Function],
|
||||||
|
"createInvitation": [Function],
|
||||||
|
"createWebhook": [Function],
|
||||||
|
"deleteHook": [Function],
|
||||||
|
"deleteWebhook": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getHook": [Function],
|
||||||
|
"getMembership": [Function],
|
||||||
|
"getMembershipForAuthenticatedUser": [Function],
|
||||||
|
"getMembershipForUser": [Function],
|
||||||
|
"getWebhook": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listAppInstallations": [Function],
|
||||||
|
"listBlockedUsers": [Function],
|
||||||
|
"listForAuthenticatedUser": [Function],
|
||||||
|
"listForUser": [Function],
|
||||||
|
"listHooks": [Function],
|
||||||
|
"listInstallations": [Function],
|
||||||
|
"listInvitationTeams": [Function],
|
||||||
|
"listMembers": [Function],
|
||||||
|
"listMemberships": [Function],
|
||||||
|
"listMembershipsForAuthenticatedUser": [Function],
|
||||||
|
"listOutsideCollaborators": [Function],
|
||||||
|
"listPendingInvitations": [Function],
|
||||||
|
"listPublicMembers": [Function],
|
||||||
|
"listWebhooks": [Function],
|
||||||
|
"pingHook": [Function],
|
||||||
|
"pingWebhook": [Function],
|
||||||
|
"publicizeMembership": [Function],
|
||||||
|
"removeMember": [Function],
|
||||||
|
"removeMembership": [Function],
|
||||||
|
"removeMembershipForUser": [Function],
|
||||||
|
"removeOutsideCollaborator": [Function],
|
||||||
|
"removePublicMembershipForAuthenticatedUser": [Function],
|
||||||
|
"setMembershipForUser": [Function],
|
||||||
|
"setPublicMembershipForAuthenticatedUser": [Function],
|
||||||
|
"unblockUser": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateHook": [Function],
|
||||||
|
"updateMembership": [Function],
|
||||||
|
"updateMembershipForAuthenticatedUser": [Function],
|
||||||
|
"updateWebhook": [Function],
|
||||||
|
},
|
||||||
|
"paginate": [Function],
|
||||||
|
"projects": Object {
|
||||||
|
"addCollaborator": [Function],
|
||||||
|
"createCard": [Function],
|
||||||
|
"createColumn": [Function],
|
||||||
|
"createForAuthenticatedUser": [Function],
|
||||||
|
"createForOrg": [Function],
|
||||||
|
"createForRepo": [Function],
|
||||||
|
"delete": [Function],
|
||||||
|
"deleteCard": [Function],
|
||||||
|
"deleteColumn": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getCard": [Function],
|
||||||
|
"getColumn": [Function],
|
||||||
|
"getPermissionForUser": [Function],
|
||||||
|
"listCards": [Function],
|
||||||
|
"listCollaborators": [Function],
|
||||||
|
"listColumns": [Function],
|
||||||
|
"listForOrg": [Function],
|
||||||
|
"listForRepo": [Function],
|
||||||
|
"listForUser": [Function],
|
||||||
|
"moveCard": [Function],
|
||||||
|
"moveColumn": [Function],
|
||||||
|
"removeCollaborator": [Function],
|
||||||
|
"reviewUserPermissionLevel": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateCard": [Function],
|
||||||
|
"updateColumn": [Function],
|
||||||
|
},
|
||||||
|
"pulls": Object {
|
||||||
|
"checkIfMerged": [Function],
|
||||||
|
"create": [Function],
|
||||||
|
"createComment": [Function],
|
||||||
|
"createReplyForReviewComment": [Function],
|
||||||
|
"createReview": [Function],
|
||||||
|
"createReviewComment": [Function],
|
||||||
|
"createReviewCommentReply": [Function],
|
||||||
|
"createReviewRequest": [Function],
|
||||||
|
"deleteComment": [Function],
|
||||||
|
"deletePendingReview": [Function],
|
||||||
|
"deleteReviewComment": [Function],
|
||||||
|
"deleteReviewRequest": [Function],
|
||||||
|
"dismissReview": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getComment": [Function],
|
||||||
|
"getCommentsForReview": [Function],
|
||||||
|
"getReview": [Function],
|
||||||
|
"getReviewComment": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listComments": [Function],
|
||||||
|
"listCommentsForRepo": [Function],
|
||||||
|
"listCommentsForReview": [Function],
|
||||||
|
"listCommits": [Function],
|
||||||
|
"listFiles": [Function],
|
||||||
|
"listRequestedReviewers": [Function],
|
||||||
|
"listReviewComments": [Function],
|
||||||
|
"listReviewCommentsForRepo": [Function],
|
||||||
|
"listReviewRequests": [Function],
|
||||||
|
"listReviews": [Function],
|
||||||
|
"merge": [Function],
|
||||||
|
"removeRequestedReviewers": [Function],
|
||||||
|
"requestReviewers": [Function],
|
||||||
|
"submitReview": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateBranch": [Function],
|
||||||
|
"updateComment": [Function],
|
||||||
|
"updateReview": [Function],
|
||||||
|
"updateReviewComment": [Function],
|
||||||
|
},
|
||||||
|
"rateLimit": Object {
|
||||||
|
"get": [Function],
|
||||||
|
},
|
||||||
|
"reactions": Object {
|
||||||
|
"createForCommitComment": [Function],
|
||||||
|
"createForIssue": [Function],
|
||||||
|
"createForIssueComment": [Function],
|
||||||
|
"createForPullRequestReviewComment": [Function],
|
||||||
|
"createForTeamDiscussionCommentInOrg": [Function],
|
||||||
|
"createForTeamDiscussionInOrg": [Function],
|
||||||
|
"delete": [Function],
|
||||||
|
"deleteForCommitComment": [Function],
|
||||||
|
"deleteForIssue": [Function],
|
||||||
|
"deleteForIssueComment": [Function],
|
||||||
|
"deleteForPullRequestComment": [Function],
|
||||||
|
"deleteForTeamDiscussion": [Function],
|
||||||
|
"deleteForTeamDiscussionComment": [Function],
|
||||||
|
"deleteLegacy": [Function],
|
||||||
|
"listForCommitComment": [Function],
|
||||||
|
"listForIssue": [Function],
|
||||||
|
"listForIssueComment": [Function],
|
||||||
|
"listForPullRequestReviewComment": [Function],
|
||||||
|
"listForTeamDiscussionCommentInOrg": [Function],
|
||||||
|
"listForTeamDiscussionInOrg": [Function],
|
||||||
|
},
|
||||||
|
"repos": Object {
|
||||||
|
"acceptInvitation": [Function],
|
||||||
|
"addAppAccessRestrictions": [Function],
|
||||||
|
"addCollaborator": [Function],
|
||||||
|
"addDeployKey": [Function],
|
||||||
|
"addProtectedBranchAdminEnforcement": [Function],
|
||||||
|
"addProtectedBranchAppRestrictions": [Function],
|
||||||
|
"addProtectedBranchRequiredSignatures": [Function],
|
||||||
|
"addProtectedBranchRequiredStatusChecksContexts": [Function],
|
||||||
|
"addProtectedBranchTeamRestrictions": [Function],
|
||||||
|
"addProtectedBranchUserRestrictions": [Function],
|
||||||
|
"addStatusCheckContexts": [Function],
|
||||||
|
"addTeamAccessRestrictions": [Function],
|
||||||
|
"addUserAccessRestrictions": [Function],
|
||||||
|
"checkCollaborator": [Function],
|
||||||
|
"checkVulnerabilityAlerts": [Function],
|
||||||
|
"compareCommits": [Function],
|
||||||
|
"createCommitComment": [Function],
|
||||||
|
"createCommitSignatureProtection": [Function],
|
||||||
|
"createCommitStatus": [Function],
|
||||||
|
"createDeployKey": [Function],
|
||||||
|
"createDeployment": [Function],
|
||||||
|
"createDeploymentStatus": [Function],
|
||||||
|
"createDispatchEvent": [Function],
|
||||||
|
"createForAuthenticatedUser": [Function],
|
||||||
|
"createFork": [Function],
|
||||||
|
"createHook": [Function],
|
||||||
|
"createInOrg": [Function],
|
||||||
|
"createOrUpdateFile": [Function],
|
||||||
|
"createOrUpdateFileContents": [Function],
|
||||||
|
"createPagesSite": [Function],
|
||||||
|
"createRelease": [Function],
|
||||||
|
"createStatus": [Function],
|
||||||
|
"createUsingTemplate": [Function],
|
||||||
|
"createWebhook": [Function],
|
||||||
|
"declineInvitation": [Function],
|
||||||
|
"delete": [Function],
|
||||||
|
"deleteAccessRestrictions": [Function],
|
||||||
|
"deleteAdminBranchProtection": [Function],
|
||||||
|
"deleteBranchProtection": [Function],
|
||||||
|
"deleteCommitComment": [Function],
|
||||||
|
"deleteCommitSignatureProtection": [Function],
|
||||||
|
"deleteDeployKey": [Function],
|
||||||
|
"deleteDeployment": [Function],
|
||||||
|
"deleteDownload": [Function],
|
||||||
|
"deleteFile": [Function],
|
||||||
|
"deleteHook": [Function],
|
||||||
|
"deleteInvitation": [Function],
|
||||||
|
"deletePagesSite": [Function],
|
||||||
|
"deletePullRequestReviewProtection": [Function],
|
||||||
|
"deleteRelease": [Function],
|
||||||
|
"deleteReleaseAsset": [Function],
|
||||||
|
"deleteWebhook": [Function],
|
||||||
|
"disableAutomatedSecurityFixes": [Function],
|
||||||
|
"disablePagesSite": [Function],
|
||||||
|
"disableVulnerabilityAlerts": [Function],
|
||||||
|
"downloadArchive": [Function],
|
||||||
|
"enableAutomatedSecurityFixes": [Function],
|
||||||
|
"enablePagesSite": [Function],
|
||||||
|
"enableVulnerabilityAlerts": [Function],
|
||||||
|
"get": [Function],
|
||||||
|
"getAccessRestrictions": [Function],
|
||||||
|
"getAdminBranchProtection": [Function],
|
||||||
|
"getAllStatusCheckContexts": [Function],
|
||||||
|
"getAllTopics": [Function],
|
||||||
|
"getAppsWithAccessToProtectedBranch": [Function],
|
||||||
|
"getArchiveLink": [Function],
|
||||||
|
"getBranch": [Function],
|
||||||
|
"getBranchProtection": [Function],
|
||||||
|
"getClones": [Function],
|
||||||
|
"getCodeFrequencyStats": [Function],
|
||||||
|
"getCollaboratorPermissionLevel": [Function],
|
||||||
|
"getCombinedStatusForRef": [Function],
|
||||||
|
"getCommit": [Function],
|
||||||
|
"getCommitActivityStats": [Function],
|
||||||
|
"getCommitComment": [Function],
|
||||||
|
"getCommitSignatureProtection": [Function],
|
||||||
|
"getCommunityProfileMetrics": [Function],
|
||||||
|
"getContent": [Function],
|
||||||
|
"getContents": [Function],
|
||||||
|
"getContributorsStats": [Function],
|
||||||
|
"getDeployKey": [Function],
|
||||||
|
"getDeployment": [Function],
|
||||||
|
"getDeploymentStatus": [Function],
|
||||||
|
"getDownload": [Function],
|
||||||
|
"getHook": [Function],
|
||||||
|
"getLatestPagesBuild": [Function],
|
||||||
|
"getLatestRelease": [Function],
|
||||||
|
"getPages": [Function],
|
||||||
|
"getPagesBuild": [Function],
|
||||||
|
"getParticipationStats": [Function],
|
||||||
|
"getProtectedBranchAdminEnforcement": [Function],
|
||||||
|
"getProtectedBranchPullRequestReviewEnforcement": [Function],
|
||||||
|
"getProtectedBranchRequiredSignatures": [Function],
|
||||||
|
"getProtectedBranchRequiredStatusChecks": [Function],
|
||||||
|
"getProtectedBranchRestrictions": [Function],
|
||||||
|
"getPullRequestReviewProtection": [Function],
|
||||||
|
"getPunchCardStats": [Function],
|
||||||
|
"getReadme": [Function],
|
||||||
|
"getRelease": [Function],
|
||||||
|
"getReleaseAsset": [Function],
|
||||||
|
"getReleaseByTag": [Function],
|
||||||
|
"getStatusChecksProtection": [Function],
|
||||||
|
"getTeamsWithAccessToProtectedBranch": [Function],
|
||||||
|
"getTopPaths": [Function],
|
||||||
|
"getTopReferrers": [Function],
|
||||||
|
"getUsersWithAccessToProtectedBranch": [Function],
|
||||||
|
"getViews": [Function],
|
||||||
|
"getWebhook": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listAssetsForRelease": [Function],
|
||||||
|
"listBranches": [Function],
|
||||||
|
"listBranchesForHeadCommit": [Function],
|
||||||
|
"listCollaborators": [Function],
|
||||||
|
"listCommentsForCommit": [Function],
|
||||||
|
"listCommitComments": [Function],
|
||||||
|
"listCommitCommentsForRepo": [Function],
|
||||||
|
"listCommitStatusesForRef": [Function],
|
||||||
|
"listCommits": [Function],
|
||||||
|
"listContributors": [Function],
|
||||||
|
"listDeployKeys": [Function],
|
||||||
|
"listDeploymentStatuses": [Function],
|
||||||
|
"listDeployments": [Function],
|
||||||
|
"listDownloads": [Function],
|
||||||
|
"listForAuthenticatedUser": [Function],
|
||||||
|
"listForOrg": [Function],
|
||||||
|
"listForUser": [Function],
|
||||||
|
"listForks": [Function],
|
||||||
|
"listHooks": [Function],
|
||||||
|
"listInvitations": [Function],
|
||||||
|
"listInvitationsForAuthenticatedUser": [Function],
|
||||||
|
"listLanguages": [Function],
|
||||||
|
"listPagesBuilds": [Function],
|
||||||
|
"listProtectedBranchRequiredStatusChecksContexts": [Function],
|
||||||
|
"listPublic": [Function],
|
||||||
|
"listPullRequestsAssociatedWithCommit": [Function],
|
||||||
|
"listReleaseAssets": [Function],
|
||||||
|
"listReleases": [Function],
|
||||||
|
"listStatusesForRef": [Function],
|
||||||
|
"listTags": [Function],
|
||||||
|
"listTeams": [Function],
|
||||||
|
"listTopics": [Function],
|
||||||
|
"listWebhooks": [Function],
|
||||||
|
"merge": [Function],
|
||||||
|
"pingHook": [Function],
|
||||||
|
"pingWebhook": [Function],
|
||||||
|
"removeAppAccessRestrictions": [Function],
|
||||||
|
"removeBranchProtection": [Function],
|
||||||
|
"removeCollaborator": [Function],
|
||||||
|
"removeDeployKey": [Function],
|
||||||
|
"removeProtectedBranchAdminEnforcement": [Function],
|
||||||
|
"removeProtectedBranchAppRestrictions": [Function],
|
||||||
|
"removeProtectedBranchPullRequestReviewEnforcement": [Function],
|
||||||
|
"removeProtectedBranchRequiredSignatures": [Function],
|
||||||
|
"removeProtectedBranchRequiredStatusChecks": [Function],
|
||||||
|
"removeProtectedBranchRequiredStatusChecksContexts": [Function],
|
||||||
|
"removeProtectedBranchRestrictions": [Function],
|
||||||
|
"removeProtectedBranchTeamRestrictions": [Function],
|
||||||
|
"removeProtectedBranchUserRestrictions": [Function],
|
||||||
|
"removeStatusCheckContexts": [Function],
|
||||||
|
"removeStatusCheckProtection": [Function],
|
||||||
|
"removeTeamAccessRestrictions": [Function],
|
||||||
|
"removeUserAccessRestrictions": [Function],
|
||||||
|
"replaceAllTopics": [Function],
|
||||||
|
"replaceProtectedBranchAppRestrictions": [Function],
|
||||||
|
"replaceProtectedBranchRequiredStatusChecksContexts": [Function],
|
||||||
|
"replaceProtectedBranchTeamRestrictions": [Function],
|
||||||
|
"replaceProtectedBranchUserRestrictions": [Function],
|
||||||
|
"replaceTopics": [Function],
|
||||||
|
"requestPageBuild": [Function],
|
||||||
|
"requestPagesBuild": [Function],
|
||||||
|
"retrieveCommunityProfileMetrics": [Function],
|
||||||
|
"setAdminBranchProtection": [Function],
|
||||||
|
"setAppAccessRestrictions": [Function],
|
||||||
|
"setStatusCheckContexts": [Function],
|
||||||
|
"setTeamAccessRestrictions": [Function],
|
||||||
|
"setUserAccessRestrictions": [Function],
|
||||||
|
"testPushHook": [Function],
|
||||||
|
"testPushWebhook": [Function],
|
||||||
|
"transfer": [Function],
|
||||||
|
"update": [Function],
|
||||||
|
"updateBranchProtection": [Function],
|
||||||
|
"updateCommitComment": [Function],
|
||||||
|
"updateHook": [Function],
|
||||||
|
"updateInformationAboutPagesSite": [Function],
|
||||||
|
"updateInvitation": [Function],
|
||||||
|
"updateProtectedBranchPullRequestReviewEnforcement": [Function],
|
||||||
|
"updateProtectedBranchRequiredStatusChecks": [Function],
|
||||||
|
"updatePullRequestReviewProtection": [Function],
|
||||||
|
"updateRelease": [Function],
|
||||||
|
"updateReleaseAsset": [Function],
|
||||||
|
"updateStatusCheckPotection": [Function],
|
||||||
|
"updateWebhook": [Function],
|
||||||
|
"uploadReleaseAsset": [Function],
|
||||||
|
},
|
||||||
|
"request": [Function],
|
||||||
|
"search": Object {
|
||||||
|
"code": [Function],
|
||||||
|
"commits": [Function],
|
||||||
|
"issuesAndPullRequests": [Function],
|
||||||
|
"labels": [Function],
|
||||||
|
"repos": [Function],
|
||||||
|
"topics": [Function],
|
||||||
|
"users": [Function],
|
||||||
|
},
|
||||||
|
"teams": Object {
|
||||||
|
"addOrUpdateMembershipForUserInOrg": [Function],
|
||||||
|
"addOrUpdateMembershipInOrg": [Function],
|
||||||
|
"addOrUpdateProjectInOrg": [Function],
|
||||||
|
"addOrUpdateProjectPermissionsInOrg": [Function],
|
||||||
|
"addOrUpdateRepoInOrg": [Function],
|
||||||
|
"addOrUpdateRepoPermissionsInOrg": [Function],
|
||||||
|
"checkManagesRepoInOrg": [Function],
|
||||||
|
"checkPermissionsForProjectInOrg": [Function],
|
||||||
|
"checkPermissionsForRepoInOrg": [Function],
|
||||||
|
"create": [Function],
|
||||||
|
"createDiscussionCommentInOrg": [Function],
|
||||||
|
"createDiscussionInOrg": [Function],
|
||||||
|
"deleteDiscussionCommentInOrg": [Function],
|
||||||
|
"deleteDiscussionInOrg": [Function],
|
||||||
|
"deleteInOrg": [Function],
|
||||||
|
"getByName": [Function],
|
||||||
|
"getDiscussionCommentInOrg": [Function],
|
||||||
|
"getDiscussionInOrg": [Function],
|
||||||
|
"getMembershipForUserInOrg": [Function],
|
||||||
|
"getMembershipInOrg": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listChildInOrg": [Function],
|
||||||
|
"listDiscussionCommentsInOrg": [Function],
|
||||||
|
"listDiscussionsInOrg": [Function],
|
||||||
|
"listForAuthenticatedUser": [Function],
|
||||||
|
"listMembersInOrg": [Function],
|
||||||
|
"listPendingInvitationsInOrg": [Function],
|
||||||
|
"listProjectsInOrg": [Function],
|
||||||
|
"listReposInOrg": [Function],
|
||||||
|
"removeMembershipForUserInOrg": [Function],
|
||||||
|
"removeMembershipInOrg": [Function],
|
||||||
|
"removeProjectInOrg": [Function],
|
||||||
|
"removeRepoInOrg": [Function],
|
||||||
|
"reviewProjectInOrg": [Function],
|
||||||
|
"updateDiscussionCommentInOrg": [Function],
|
||||||
|
"updateDiscussionInOrg": [Function],
|
||||||
|
"updateInOrg": [Function],
|
||||||
|
},
|
||||||
|
"users": Object {
|
||||||
|
"addEmailForAuthenticated": [Function],
|
||||||
|
"addEmails": [Function],
|
||||||
|
"block": [Function],
|
||||||
|
"checkBlocked": [Function],
|
||||||
|
"checkFollowing": [Function],
|
||||||
|
"checkFollowingForUser": [Function],
|
||||||
|
"checkPersonIsFollowedByAuthenticated": [Function],
|
||||||
|
"createGpgKey": [Function],
|
||||||
|
"createGpgKeyForAuthenticated": [Function],
|
||||||
|
"createPublicKey": [Function],
|
||||||
|
"createPublicSshKeyForAuthenticated": [Function],
|
||||||
|
"deleteEmailForAuthenticated": [Function],
|
||||||
|
"deleteEmails": [Function],
|
||||||
|
"deleteGpgKey": [Function],
|
||||||
|
"deleteGpgKeyForAuthenticated": [Function],
|
||||||
|
"deletePublicKey": [Function],
|
||||||
|
"deletePublicSshKeyForAuthenticated": [Function],
|
||||||
|
"follow": [Function],
|
||||||
|
"getAuthenticated": [Function],
|
||||||
|
"getByUsername": [Function],
|
||||||
|
"getContextForUser": [Function],
|
||||||
|
"getGpgKey": [Function],
|
||||||
|
"getGpgKeyForAuthenticated": [Function],
|
||||||
|
"getPublicKey": [Function],
|
||||||
|
"getPublicSshKeyForAuthenticated": [Function],
|
||||||
|
"list": [Function],
|
||||||
|
"listBlocked": [Function],
|
||||||
|
"listBlockedByAuthenticated": [Function],
|
||||||
|
"listEmails": [Function],
|
||||||
|
"listEmailsForAuthenticated": [Function],
|
||||||
|
"listFollowedByAuthenticated": [Function],
|
||||||
|
"listFollowersForAuthenticatedUser": [Function],
|
||||||
|
"listFollowersForUser": [Function],
|
||||||
|
"listFollowingForAuthenticatedUser": [Function],
|
||||||
|
"listFollowingForUser": [Function],
|
||||||
|
"listGpgKeys": [Function],
|
||||||
|
"listGpgKeysForAuthenticated": [Function],
|
||||||
|
"listGpgKeysForUser": [Function],
|
||||||
|
"listPublicEmails": [Function],
|
||||||
|
"listPublicEmailsForAuthenticated": [Function],
|
||||||
|
"listPublicKeys": [Function],
|
||||||
|
"listPublicKeysForUser": [Function],
|
||||||
|
"listPublicSshKeysForAuthenticated": [Function],
|
||||||
|
"setPrimaryEmailVisibilityForAuthenticated": [Function],
|
||||||
|
"togglePrimaryEmailVisibility": [Function],
|
||||||
|
"unblock": [Function],
|
||||||
|
"unfollow": [Function],
|
||||||
|
"updateAuthenticated": [Function],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"graphStylingPane": GraphStylingPane {
|
"graphStylingPane": GraphStylingPane {
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"firstFieldHasFocus": [Function],
|
"firstFieldHasFocus": [Function],
|
||||||
@@ -429,7 +1196,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
|||||||
"isAutoscaleDefaultEnabled": [Function],
|
"isAutoscaleDefaultEnabled": [Function],
|
||||||
"isEnableMongoCapabilityPresent": [Function],
|
"isEnableMongoCapabilityPresent": [Function],
|
||||||
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
||||||
"isGitHubPaneEnabled": [Function],
|
|
||||||
"isHostedDataExplorerEnabled": [Function],
|
"isHostedDataExplorerEnabled": [Function],
|
||||||
"isLastCollection": [Function],
|
"isLastCollection": [Function],
|
||||||
"isLastNonEmptyDatabase": [Function],
|
"isLastNonEmptyDatabase": [Function],
|
||||||
@@ -447,9 +1213,14 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
|||||||
"isSparkEnabledForAccount": [Function],
|
"isSparkEnabledForAccount": [Function],
|
||||||
"isSynapseLinkUpdating": [Function],
|
"isSynapseLinkUpdating": [Function],
|
||||||
"isTabsContentExpanded": [Function],
|
"isTabsContentExpanded": [Function],
|
||||||
|
"junoClient": JunoClient {
|
||||||
|
"cachedPinnedRepos": [Function],
|
||||||
|
"databaseAccount": undefined,
|
||||||
|
},
|
||||||
"memoryUsageInfo": [Function],
|
"memoryUsageInfo": [Function],
|
||||||
"notebookBasePath": [Function],
|
"notebookBasePath": [Function],
|
||||||
"notebookServerInfo": [Function],
|
"notebookServerInfo": [Function],
|
||||||
|
"onGitHubClientError": [Function],
|
||||||
"onRefreshDatabasesKeyPress": [Function],
|
"onRefreshDatabasesKeyPress": [Function],
|
||||||
"onRefreshResourcesClick": [Function],
|
"onRefreshResourcesClick": [Function],
|
||||||
"onSwitchToConnectionString": [Function],
|
"onSwitchToConnectionString": [Function],
|
||||||
@@ -525,7 +1296,7 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
|||||||
<Stack
|
<Stack
|
||||||
className="panelInfoErrorContainer"
|
className="panelInfoErrorContainer"
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
verticalAlign="start"
|
verticalAlign="center"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="ms-Stack panelInfoErrorContainer css-140"
|
className="ms-Stack panelInfoErrorContainer css-140"
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ export function convertEntityToNewDocument(entity: Entities.ITableEntityForTable
|
|||||||
$id: entity.RowKey._,
|
$id: entity.RowKey._,
|
||||||
id: entity.RowKey._,
|
id: entity.RowKey._,
|
||||||
};
|
};
|
||||||
for (var property in entity) {
|
for (const property in entity) {
|
||||||
if (
|
if (
|
||||||
property !== Constants.EntityKeyNames.PartitionKey &&
|
property !== Constants.EntityKeyNames.PartitionKey &&
|
||||||
property !== Constants.EntityKeyNames.RowKey &&
|
property !== Constants.EntityKeyNames.RowKey &&
|
||||||
@@ -176,18 +176,30 @@ export function convertEntityToNewDocument(entity: Entities.ITableEntityForTable
|
|||||||
property !== keyProperties.attachments &&
|
property !== keyProperties.attachments &&
|
||||||
property !== keyProperties.Id2
|
property !== keyProperties.Id2
|
||||||
) {
|
) {
|
||||||
if (entity[property].$ === Constants.TableType.DateTime) {
|
const propertyValue = entity[property]._;
|
||||||
// Convert javascript date back to ticks with 20 zeros padding
|
let parsedValue;
|
||||||
document[property] = {
|
switch (entity[property].$) {
|
||||||
$t: (<any>DataTypes)[entity[property].$],
|
case Constants.TableType.DateTime:
|
||||||
$v: DateTimeUtilities.convertJSDateToTicksWithPadding(entity[property]._),
|
parsedValue = DateTimeUtilities.convertJSDateToTicksWithPadding(propertyValue);
|
||||||
};
|
break;
|
||||||
} else {
|
case Constants.TableType.Boolean:
|
||||||
document[property] = {
|
parsedValue = propertyValue.toLowerCase() === "true";
|
||||||
$t: (<any>DataTypes)[entity[property].$],
|
break;
|
||||||
$v: entity[property]._,
|
case Constants.TableType.Int32:
|
||||||
};
|
case Constants.TableType.Int64:
|
||||||
|
parsedValue = parseInt(propertyValue, 10);
|
||||||
|
break;
|
||||||
|
case Constants.TableType.Double:
|
||||||
|
parsedValue = parseFloat(propertyValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parsedValue = propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document[property] = {
|
||||||
|
$t: (<any>DataTypes)[entity[property].$],
|
||||||
|
$v: parsedValue,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return document;
|
return document;
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ import StyleIcon from "../../../images/Style.svg";
|
|||||||
import { DatabaseAccount } from "../../Contracts/DataModels";
|
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { GraphAccessor, GraphExplorerError } from "../Graph/GraphExplorerComponent/GraphExplorer";
|
import {
|
||||||
import { GraphExplorerAdapter } from "../Graph/GraphExplorerComponent/GraphExplorerAdapter";
|
GraphAccessor,
|
||||||
|
GraphExplorer,
|
||||||
|
GraphExplorerError,
|
||||||
|
GraphExplorerProps,
|
||||||
|
} from "../Graph/GraphExplorerComponent/GraphExplorer";
|
||||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||||
import GraphStylingPane from "../Panes/GraphStylingPane";
|
import GraphStylingPane from "../Panes/GraphStylingPane";
|
||||||
import { NewVertexPanel } from "../Panes/NewVertexPanel/NewVertexPanel";
|
import { NewVertexPanel } from "../Panes/NewVertexPanel/NewVertexPanel";
|
||||||
@@ -36,15 +40,13 @@ interface GraphTabOptions extends ViewModels.TabOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class GraphTab extends TabsBase {
|
export default class GraphTab extends TabsBase {
|
||||||
public readonly html =
|
|
||||||
'<div class="graphExplorerContainer" role="tabpanel" data-bind="react:graphExplorerAdapter, attr: {id: tabId}"></div>';
|
|
||||||
// Graph default configuration
|
// Graph default configuration
|
||||||
public static readonly DEFAULT_NODE_CAPTION = "id";
|
public static readonly DEFAULT_NODE_CAPTION = "id";
|
||||||
private static readonly LINK_COLOR = "#aaa";
|
private static readonly LINK_COLOR = "#aaa";
|
||||||
private static readonly NODE_SIZE = 10;
|
private static readonly NODE_SIZE = 10;
|
||||||
private static readonly NODE_COLOR = "orange";
|
private static readonly NODE_COLOR = "orange";
|
||||||
private static readonly LINK_WIDTH = 1;
|
private static readonly LINK_WIDTH = 1;
|
||||||
private graphExplorerAdapter: GraphExplorerAdapter;
|
private graphExplorerProps: GraphExplorerProps;
|
||||||
private isNewVertexDisabled: ko.Observable<boolean>;
|
private isNewVertexDisabled: ko.Observable<boolean>;
|
||||||
private isPropertyEditing: ko.Observable<boolean>;
|
private isPropertyEditing: ko.Observable<boolean>;
|
||||||
private isGraphDisplayed: ko.Observable<boolean>;
|
private isGraphDisplayed: ko.Observable<boolean>;
|
||||||
@@ -70,7 +72,7 @@ export default class GraphTab extends TabsBase {
|
|||||||
this.graphConfig = GraphTab.createGraphConfig();
|
this.graphConfig = GraphTab.createGraphConfig();
|
||||||
// TODO Merge this with this.graphConfig
|
// TODO Merge this with this.graphConfig
|
||||||
this.graphConfigUiData = GraphTab.createGraphConfigUiData(this.graphConfig);
|
this.graphConfigUiData = GraphTab.createGraphConfigUiData(this.graphConfig);
|
||||||
this.graphExplorerAdapter = new GraphExplorerAdapter({
|
this.graphExplorerProps = {
|
||||||
onGraphAccessorCreated: (instance: GraphAccessor): void => {
|
onGraphAccessorCreated: (instance: GraphAccessor): void => {
|
||||||
this.graphAccessor = instance;
|
this.graphAccessor = instance;
|
||||||
},
|
},
|
||||||
@@ -89,8 +91,9 @@ export default class GraphTab extends TabsBase {
|
|||||||
onResetDefaultGraphConfigValues: () => this.setDefaultGraphConfigValues(),
|
onResetDefaultGraphConfigValues: () => this.setDefaultGraphConfigValues(),
|
||||||
graphConfig: this.graphConfig,
|
graphConfig: this.graphConfig,
|
||||||
graphConfigUiData: this.graphConfigUiData,
|
graphConfigUiData: this.graphConfigUiData,
|
||||||
onIsFilterQueryLoading: (isFilterQueryLoading: boolean): void => this.isFilterQueryLoading(isFilterQueryLoading),
|
onIsFilterQueryLoadingChange: (isFilterQueryLoading: boolean): void =>
|
||||||
onIsValidQuery: (isValidQuery: boolean): void => this.isValidQuery(isValidQuery),
|
this.isFilterQueryLoading(isFilterQueryLoading),
|
||||||
|
onIsValidQueryChange: (isValidQuery: boolean): void => this.isValidQuery(isValidQuery),
|
||||||
collectionPartitionKeyProperty: options.collectionPartitionKeyProperty,
|
collectionPartitionKeyProperty: options.collectionPartitionKeyProperty,
|
||||||
graphBackendEndpoint: GraphTab.getGremlinEndpoint(options.account),
|
graphBackendEndpoint: GraphTab.getGremlinEndpoint(options.account),
|
||||||
databaseId: options.databaseId,
|
databaseId: options.databaseId,
|
||||||
@@ -103,7 +106,7 @@ export default class GraphTab extends TabsBase {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resourceId: options.account.id,
|
resourceId: options.account.id,
|
||||||
});
|
};
|
||||||
|
|
||||||
this.isFilterQueryLoading = ko.observable(false);
|
this.isFilterQueryLoading = ko.observable(false);
|
||||||
this.isValidQuery = ko.observable(true);
|
this.isValidQuery = ko.observable(true);
|
||||||
@@ -115,6 +118,14 @@ export default class GraphTab extends TabsBase {
|
|||||||
: `${account.name}.graphs.azure.com:443/`;
|
: `${account.name}.graphs.azure.com:443/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div className="graphExplorerContainer" role="tabpanel" id={this.tabId}>
|
||||||
|
<GraphExplorer {...this.graphExplorerProps} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public onTabClick(): void {
|
public onTabClick(): void {
|
||||||
super.onTabClick();
|
super.onTabClick();
|
||||||
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Graph);
|
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Graph);
|
||||||
|
|||||||
@@ -205,9 +205,8 @@ export default class Database implements ViewModels.Database {
|
|||||||
this.deleteCollectionsFromList(deltaCollections.toDelete);
|
this.deleteCollectionsFromList(deltaCollections.toDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public openAddCollection(database: Database, event: MouseEvent) {
|
public openAddCollection(database: Database) {
|
||||||
database.container.addCollectionPane.databaseId(database.id());
|
database.container.openAddCollectionPanel(database.id());
|
||||||
database.container.addCollectionPane.open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public findCollectionWithId(collectionId: string): ViewModels.Collection {
|
public findCollectionWithId(collectionId: string): ViewModels.Collection {
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||||||
className: "databaseHeader",
|
className: "databaseHeader",
|
||||||
children: [],
|
children: [],
|
||||||
isSelected: () => this.isDataNodeSelected(database.id()),
|
isSelected: () => this.isDataNodeSelected(database.id()),
|
||||||
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(this.container),
|
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(this.container, database.id()),
|
||||||
onClick: async (isExpanded) => {
|
onClick: async (isExpanded) => {
|
||||||
// Rewritten version of expandCollapseDatabase():
|
// Rewritten version of expandCollapseDatabase():
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
@@ -607,7 +607,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||||||
gitHubNotebooksTree.contextMenu = [
|
gitHubNotebooksTree.contextMenu = [
|
||||||
{
|
{
|
||||||
label: "Manage GitHub settings",
|
label: "Manage GitHub settings",
|
||||||
onClick: () => this.container.gitHubReposPane.open(),
|
onClick: () => this.container.openGitHubReposPanel("Manage GitHub settings"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Disconnect from GitHub",
|
label: "Disconnect from GitHub",
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import { useConfig } from "./hooks/useConfig";
|
|||||||
import { useKnockoutExplorer } from "./hooks/useKnockoutExplorer";
|
import { useKnockoutExplorer } from "./hooks/useKnockoutExplorer";
|
||||||
import { useSidePanel } from "./hooks/useSidePanel";
|
import { useSidePanel } from "./hooks/useSidePanel";
|
||||||
import { useTabs } from "./hooks/useTabs";
|
import { useTabs } from "./hooks/useTabs";
|
||||||
import { KOCommentEnd, KOCommentIfStart } from "./koComment";
|
|
||||||
import "./Libs/jquery";
|
import "./Libs/jquery";
|
||||||
import "./Shared/appInsights";
|
import "./Shared/appInsights";
|
||||||
import { userContext } from "./UserContext";
|
import { userContext } from "./UserContext";
|
||||||
@@ -231,9 +230,6 @@ const App: React.FunctionComponent = () => {
|
|||||||
<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: "graph-styling-pane", params: { data: graphStylingPane} }' />
|
<div data-bind='component: { name: "graph-styling-pane", params: { data: graphStylingPane} }' />
|
||||||
<div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' />
|
<div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' />
|
||||||
<KOCommentIfStart if="isGitHubPaneEnabled" />
|
|
||||||
<div data-bind='component: { name: "github-repos-pane", params: { data: gitHubReposPane } }' />
|
|
||||||
<KOCommentEnd />
|
|
||||||
{showDialog && <Dialog {...dialogProps} />}
|
{showDialog && <Dialog {...dialogProps} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ export enum Action {
|
|||||||
NotebooksGalleryFavoritesCount,
|
NotebooksGalleryFavoritesCount,
|
||||||
NotebooksGalleryPublishedCount,
|
NotebooksGalleryPublishedCount,
|
||||||
SelfServe,
|
SelfServe,
|
||||||
|
ExpandAddCollectionPaneAdvancedSection,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ActionModifiers = {
|
export const ActionModifiers = {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface UserContext {
|
|||||||
readonly quotaId?: string;
|
readonly quotaId?: string;
|
||||||
// API Type is not yet provided by ARM. You need to manually inspect all the capabilities+kind so we abstract that logic in userContext
|
// API Type is not yet provided by ARM. You need to manually inspect all the capabilities+kind so we abstract that logic in userContext
|
||||||
// This is coming in a future Cosmos ARM API version as a prperty on databaseAccount
|
// This is coming in a future Cosmos ARM API version as a prperty on databaseAccount
|
||||||
apiType?: ApiType;
|
apiType: ApiType;
|
||||||
readonly isTryCosmosDBSubscription?: boolean;
|
readonly isTryCosmosDBSubscription?: boolean;
|
||||||
readonly portalEnv?: PortalEnv;
|
readonly portalEnv?: PortalEnv;
|
||||||
readonly features: Features;
|
readonly features: Features;
|
||||||
|
|||||||
30
src/Utils/APITypeUtils.ts
Normal file
30
src/Utils/APITypeUtils.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { userContext } from "../UserContext";
|
||||||
|
|
||||||
|
export const getCollectionName = (isPlural?: boolean): string => {
|
||||||
|
let collectionName: string;
|
||||||
|
let unknownApiType: never;
|
||||||
|
switch (userContext.apiType) {
|
||||||
|
case "SQL":
|
||||||
|
collectionName = "Container";
|
||||||
|
break;
|
||||||
|
case "Mongo":
|
||||||
|
collectionName = "Collection";
|
||||||
|
break;
|
||||||
|
case "Cassandra":
|
||||||
|
case "Tables":
|
||||||
|
collectionName = "Table";
|
||||||
|
break;
|
||||||
|
case "Gremlin":
|
||||||
|
collectionName = "Graph";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unknownApiType = userContext.apiType;
|
||||||
|
throw new Error(`Unknown API type: ${unknownApiType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPlural) {
|
||||||
|
collectionName += "s";
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectionName;
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as Constants from "../Shared/Constants";
|
import * as Constants from "../Shared/Constants";
|
||||||
|
import { getCollectionName } from "../Utils/APITypeUtils";
|
||||||
import * as AutoPilotUtils from "../Utils/AutoPilotUtils";
|
import * as AutoPilotUtils from "../Utils/AutoPilotUtils";
|
||||||
|
|
||||||
interface ComputeRUUsagePriceHourlyArgs {
|
interface ComputeRUUsagePriceHourlyArgs {
|
||||||
@@ -10,7 +11,7 @@ interface ComputeRUUsagePriceHourlyArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const estimatedCostDisclaimer =
|
export const estimatedCostDisclaimer =
|
||||||
"*This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account";
|
"This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anything that is not a number should return 0
|
* Anything that is not a number should return 0
|
||||||
@@ -161,7 +162,7 @@ export function getAutoPilotV3SpendHtml(maxAutoPilotThroughputSet: number, isDat
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource: string = isDatabaseThroughput ? "database" : "container";
|
const resource: string = isDatabaseThroughput ? "database" : getCollectionName().toLocaleLowerCase();
|
||||||
return `Your ${resource} throughput will automatically scale from <b>${AutoPilotUtils.getMinRUsBasedOnUserInput(
|
return `Your ${resource} throughput will automatically scale from <b>${AutoPilotUtils.getMinRUsBasedOnUserInput(
|
||||||
maxAutoPilotThroughputSet
|
maxAutoPilotThroughputSet
|
||||||
)} RU/s (10% of max RU/s) - ${maxAutoPilotThroughputSet} RU/s</b> based on usage. <br /><br />After the first ${AutoPilotUtils.getStorageBasedOnUserInput(
|
)} RU/s (10% of max RU/s) - ${maxAutoPilotThroughputSet} RU/s</b> based on usage. <br /><br />After the first ${AutoPilotUtils.getStorageBasedOnUserInput(
|
||||||
@@ -227,7 +228,7 @@ export function getEstimatedSpendHtml(
|
|||||||
`${currencySign}${calculateEstimateNumber(monthlyPrice)} monthly </b> ` +
|
`${currencySign}${calculateEstimateNumber(monthlyPrice)} monthly </b> ` +
|
||||||
`(${regions} ${regions === 1 ? "region" : "regions"}, ${throughput}RU/s, ${currencySign}${pricePerRu}/RU)` +
|
`(${regions} ${regions === 1 ? "region" : "regions"}, ${throughput}RU/s, ${currencySign}${pricePerRu}/RU)` +
|
||||||
`<p style='padding: 10px 0px 0px 0px;'>` +
|
`<p style='padding: 10px 0px 0px 0px;'>` +
|
||||||
`<em>${estimatedCostDisclaimer}</em></p>`
|
`<em>*${estimatedCostDisclaimer}</em></p>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,11 +262,10 @@ export function getUpsellMessage(
|
|||||||
serverId = "default",
|
serverId = "default",
|
||||||
isFreeTier = false,
|
isFreeTier = false,
|
||||||
isFirstResourceCreated = false,
|
isFirstResourceCreated = false,
|
||||||
defaultExperience: string,
|
|
||||||
isCollection: boolean
|
isCollection: boolean
|
||||||
): string {
|
): string {
|
||||||
if (isFreeTier) {
|
if (isFreeTier) {
|
||||||
const collectionName = getCollectionName(defaultExperience);
|
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||||
const resourceType = isCollection ? collectionName : "database";
|
const resourceType = isCollection ? collectionName : "database";
|
||||||
return isFirstResourceCreated
|
return isFirstResourceCreated
|
||||||
? `The free tier discount of 400 RU/s has already been applied to a database or ${collectionName} in this account. Billing will apply to this ${resourceType} after it is created.`
|
? `The free tier discount of 400 RU/s has already been applied to a database or ${collectionName} in this account. Billing will apply to this ${resourceType} after it is created.`
|
||||||
@@ -277,22 +277,8 @@ export function getUpsellMessage(
|
|||||||
price = Constants.OfferPricing.MonthlyPricing.mooncake.Standard.StartingPrice;
|
price = Constants.OfferPricing.MonthlyPricing.mooncake.Standard.StartingPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Start at ${getCurrencySign(serverId)}${price}/mo per database, multiple containers included`;
|
return `Start at ${getCurrencySign(serverId)}${price}/mo per database, multiple ${getCollectionName(
|
||||||
}
|
true
|
||||||
}
|
).toLocaleLowerCase()} included`;
|
||||||
|
|
||||||
export function getCollectionName(defaultExperience: string): string {
|
|
||||||
switch (defaultExperience) {
|
|
||||||
case "SQL":
|
|
||||||
return "container";
|
|
||||||
case "Mongo":
|
|
||||||
return "collection";
|
|
||||||
case "Tables":
|
|
||||||
case "Cassandra":
|
|
||||||
return "table";
|
|
||||||
case "Gremlin":
|
|
||||||
return "graph";
|
|
||||||
default:
|
|
||||||
throw Error("unknown API type");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
/* eslint-disable react/prop-types */
|
|
||||||
import React, { useEffect, useRef } from "react";
|
|
||||||
|
|
||||||
export const KOCommentIfStart: React.FunctionComponent<{ if: string }> = (props) => {
|
|
||||||
const el = useRef();
|
|
||||||
useEffect(() => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(el.current as any).outerHTML = `<!-- ko if: ${props.if} -->`;
|
|
||||||
}, []);
|
|
||||||
return <div ref={el} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const KOCommentEnd: React.FunctionComponent = () => {
|
|
||||||
const el = useRef();
|
|
||||||
useEffect(() => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(el.current as any).outerHTML = `<!-- /ko -->`;
|
|
||||||
}, []);
|
|
||||||
return <div ref={el} />;
|
|
||||||
};
|
|
||||||
@@ -16,15 +16,10 @@ test("Mongo CRUD", async () => {
|
|||||||
|
|
||||||
// Create new database and collection
|
// Create new database and collection
|
||||||
await explorer.click('[data-test="New Collection"]');
|
await explorer.click('[data-test="New Collection"]');
|
||||||
await explorer.click('[data-test="addCollection-newDatabaseId"]');
|
await explorer.fill('[aria-label="New database id"]', databaseId);
|
||||||
await explorer.fill('[data-test="addCollection-newDatabaseId"]', databaseId);
|
await explorer.fill('[aria-label="Collection id"]', containerId);
|
||||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
await explorer.fill('[aria-label="Shard key"]', "/pk");
|
||||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
await explorer.click("#sidePanelOkButton");
|
||||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
|
||||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
|
||||||
await explorer.click('[data-test="addCollection-partitionKeyValue"]');
|
|
||||||
await explorer.fill('[data-test="addCollection-partitionKeyValue"]', "/pk");
|
|
||||||
await explorer.click('[data-test="addCollection-createCollection"]');
|
|
||||||
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
||||||
await safeClick(explorer, `.nodeItem >> text=${containerId}`);
|
await safeClick(explorer, `.nodeItem >> text=${containerId}`);
|
||||||
// Create indexing policy
|
// Create indexing policy
|
||||||
|
|||||||
@@ -15,15 +15,10 @@ test("SQL CRUD", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await explorer.click('[data-test="New Container"]');
|
await explorer.click('[data-test="New Container"]');
|
||||||
await explorer.click('[data-test="addCollection-newDatabaseId"]');
|
await explorer.fill('[aria-label="New database id"]', databaseId);
|
||||||
await explorer.fill('[data-test="addCollection-newDatabaseId"]', databaseId);
|
await explorer.fill('[aria-label="Container id"]', containerId);
|
||||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
await explorer.fill('[aria-label="Partition key"]', "/pk");
|
||||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
await explorer.click("#sidePanelOkButton");
|
||||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
|
||||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
|
||||||
await explorer.click('[data-test="addCollection-partitionKeyValue"]');
|
|
||||||
await explorer.fill('[data-test="addCollection-partitionKeyValue"]', "/pk");
|
|
||||||
await explorer.click('[data-test="addCollection-createCollection"]');
|
|
||||||
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
||||||
await safeClick(explorer, `[data-test="${containerId}"] [aria-label="More"]`);
|
await safeClick(explorer, `[data-test="${containerId}"] [aria-label="More"]`);
|
||||||
await safeClick(explorer, 'button[role="menuitem"]:has-text("Delete Container")');
|
await safeClick(explorer, 'button[role="menuitem"]:has-text("Delete Container")');
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ test("Tables CRUD", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await explorer.click('[data-test="New Table"]');
|
await explorer.click('[data-test="New Table"]');
|
||||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
await explorer.fill('[aria-label="Table id"]', tableId);
|
||||||
await explorer.fill('[data-test="addCollection-collectionId"]', tableId);
|
await explorer.click("#sidePanelOkButton");
|
||||||
await explorer.click('[data-test="addCollection-createCollection"]');
|
|
||||||
await safeClick(explorer, `[data-test="TablesDB"]`);
|
await safeClick(explorer, `[data-test="TablesDB"]`);
|
||||||
await safeClick(explorer, `[data-test="${tableId}"] [aria-label="More"]`);
|
await safeClick(explorer, `[data-test="${tableId}"] [aria-label="More"]`);
|
||||||
await safeClick(explorer, 'button[role="menuitem"]:has-text("Delete Table")');
|
await safeClick(explorer, 'button[role="menuitem"]:has-text("Delete Table")');
|
||||||
|
|||||||
Reference in New Issue
Block a user