mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +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-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent());
|
||||
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)
|
||||
*/
|
||||
export class ResourceTreeContextMenuButtonFactory {
|
||||
public static createDatabaseContextMenu(container: Explorer): TreeNodeMenuItem[] {
|
||||
public static createDatabaseContextMenu(container: Explorer, databaseId: string): TreeNodeMenuItem[] {
|
||||
const items: TreeNodeMenuItem[] = [
|
||||
{
|
||||
iconSrc: AddCollectionIcon,
|
||||
onClick: () => container.onNewCollectionClicked(),
|
||||
onClick: () => container.onNewCollectionClicked(databaseId),
|
||||
label: container.addCollectionText(),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -5,6 +5,7 @@ import { accordionStackTokens } from "../Settings/SettingsRenderUtils";
|
||||
export interface CollapsibleSectionProps {
|
||||
title: string;
|
||||
isExpandedByDefault: boolean;
|
||||
onExpand?: () => void;
|
||||
}
|
||||
|
||||
export interface CollapsibleSectionState {
|
||||
@@ -23,6 +24,12 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
|
||||
this.setState({ isExpanded: !this.state.isExpanded });
|
||||
};
|
||||
|
||||
public componentDidUpdate(): void {
|
||||
if (this.state.isExpanded && this.props.onExpand) {
|
||||
this.props.onExpand();
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -23,8 +23,6 @@ export interface RepoListItem {
|
||||
}
|
||||
|
||||
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 =
|
||||
"Select your GitHub repos and branch(es) to pin to your notebooks workspace.";
|
||||
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";
|
||||
|
||||
public render(): JSX.Element {
|
||||
const header: JSX.Element = (
|
||||
<p>
|
||||
{this.props.showAuthorizeAccess
|
||||
? GitHubReposComponent.ConnectToGitHubTitle
|
||||
: GitHubReposComponent.ManageGitHubRepoTitle}
|
||||
</p>
|
||||
);
|
||||
|
||||
const content: JSX.Element = this.props.showAuthorizeAccess ? (
|
||||
<AuthorizeAccessComponent {...this.props.authorizeAccessProps} />
|
||||
) : (
|
||||
@@ -66,9 +56,6 @@ export class GitHubReposComponent extends React.Component<GitHubReposComponentPr
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={"firstdivbg headerline"} role="heading" aria-level={2}>
|
||||
{header}
|
||||
</div>
|
||||
<div className={"paneMainContent"}>{content}</div>
|
||||
{!this.props.showAuthorizeAccess && (
|
||||
<>
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import {
|
||||
IStyleFunctionOrObject,
|
||||
ICheckboxStyleProps,
|
||||
ICheckboxStyles,
|
||||
IDropdownStyles,
|
||||
IDropdownStyleProps,
|
||||
IDropdownStyles,
|
||||
IStyleFunctionOrObject,
|
||||
} from "office-ui-fabric-react";
|
||||
|
||||
export const ButtonsFooterStyle: React.CSSProperties = {
|
||||
padding: 14,
|
||||
paddingTop: 14,
|
||||
height: "auto",
|
||||
borderTop: "2px solid lightGray",
|
||||
};
|
||||
|
||||
export const ContentFooterStyle: React.CSSProperties = {
|
||||
padding: "10px 24px 10px 24px",
|
||||
paddingTop: "10px",
|
||||
height: "auto",
|
||||
borderTop: "2px solid lightGray",
|
||||
};
|
||||
|
||||
export const ChildrenMargin = 10;
|
||||
@@ -53,6 +55,11 @@ export const BranchesDropdownOptionContainerStyle: React.CSSProperties = {
|
||||
padding: 8,
|
||||
};
|
||||
|
||||
export const ContentMainStyle: React.CSSProperties = {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
};
|
||||
|
||||
export const ReposListRepoColumnMinWidth = 192;
|
||||
export const ReposListBranchesColumnWidth = 116;
|
||||
export const BranchesDropdownWidth = 200;
|
||||
|
||||
@@ -415,7 +415,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
|
||||
</Text>
|
||||
<Text>
|
||||
<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>
|
||||
</Text>
|
||||
</Stack>
|
||||
@@ -689,7 +689,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
|
||||
</Text>
|
||||
<Text>
|
||||
<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>
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -150,7 +150,7 @@ exports[`SettingsUtils functions render 1`] = `
|
||||
</Text>
|
||||
<Text>
|
||||
<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>
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
import { CostEstimateText } from ".";
|
||||
import { CostEstimateText } from "./CostEstimateText";
|
||||
const props = {
|
||||
requestUnits: 5,
|
||||
isAutoscale: false,
|
||||
@@ -1,8 +1,17 @@
|
||||
import { Text } from "office-ui-fabric-react";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { Tooltip } from "../../../../Common/Tooltip/Tooltip";
|
||||
import * as SharedConstants from "../../../../Shared/Constants";
|
||||
import { userContext } from "../../../../UserContext";
|
||||
import * as PricingUtils from "../../../../Utils/PricingUtils";
|
||||
import {
|
||||
calculateEstimateNumber,
|
||||
computeRUUsagePriceHourly,
|
||||
getAutoscalePricePerRu,
|
||||
getCurrencySign,
|
||||
getMultimasterMultiplier,
|
||||
getPriceCurrency,
|
||||
getPricePerRu,
|
||||
} from "../../../../Utils/PricingUtils";
|
||||
|
||||
interface CostEstimateTextProps {
|
||||
requestUnits: number;
|
||||
@@ -13,15 +22,15 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
||||
requestUnits,
|
||||
isAutoscale,
|
||||
}: CostEstimateTextProps) => {
|
||||
const databaseAccount = userContext.databaseAccount;
|
||||
if (!databaseAccount || !databaseAccount.properties) {
|
||||
const { databaseAccount } = userContext;
|
||||
if (!databaseAccount?.properties) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const serverId: string = userContext.portalEnv;
|
||||
const numberOfRegions: number = databaseAccount.properties.readLocations?.length || 1;
|
||||
const multimasterEnabled: boolean = databaseAccount.properties.enableMultipleWriteLocations;
|
||||
const hourlyPrice: number = PricingUtils.computeRUUsagePriceHourly({
|
||||
const hourlyPrice: number = computeRUUsagePriceHourly({
|
||||
serverId,
|
||||
requestUnits,
|
||||
numberOfRegions,
|
||||
@@ -30,20 +39,22 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
||||
});
|
||||
const dailyPrice: number = hourlyPrice * 24;
|
||||
const monthlyPrice: number = hourlyPrice * SharedConstants.hoursInAMonth;
|
||||
const currency: string = PricingUtils.getPriceCurrency(serverId);
|
||||
const currencySign: string = PricingUtils.getCurrencySign(serverId);
|
||||
const multiplier = PricingUtils.getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
||||
const currency: string = getPriceCurrency(serverId);
|
||||
const currencySign: string = getCurrencySign(serverId);
|
||||
const multiplier = getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
||||
const pricePerRu = isAutoscale
|
||||
? PricingUtils.getAutoscalePricePerRu(serverId, multiplier) * multiplier
|
||||
: PricingUtils.getPricePerRu(serverId) * multiplier;
|
||||
? getAutoscalePricePerRu(serverId, multiplier) * multiplier
|
||||
: getPricePerRu(serverId) * multiplier;
|
||||
|
||||
const iconWithEstimatedCostDisclaimer: JSX.Element = <Tooltip>PricingUtils.estimatedCostDisclaimer</Tooltip>;
|
||||
|
||||
if (isAutoscale) {
|
||||
return (
|
||||
<Text variant="small">
|
||||
Estimated monthly cost ({currency}):{" "}
|
||||
Estimated monthly cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||
<b>
|
||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice)}{" "}
|
||||
{currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
||||
{currencySign + calculateEstimateNumber(monthlyPrice)}{" "}
|
||||
</b>
|
||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits / 10} - {requestUnits}{" "}
|
||||
RU/s, {currencySign + pricePerRu}/RU)
|
||||
@@ -53,16 +64,14 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
||||
|
||||
return (
|
||||
<Text variant="small">
|
||||
Cost ({currency}):{" "}
|
||||
Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||
<b>
|
||||
{currencySign + PricingUtils.calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
||||
{currencySign + PricingUtils.calculateEstimateNumber(dailyPrice)} daily /{" "}
|
||||
{currencySign + PricingUtils.calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
||||
{currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
||||
{currencySign + calculateEstimateNumber(dailyPrice)} daily /{" "}
|
||||
{currencySign + calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
||||
</b>
|
||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits}RU/s,{" "}
|
||||
{currencySign + pricePerRu}/RU)
|
||||
<br />
|
||||
<em>{PricingUtils.estimatedCostDisclaimer}</em>
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
@@ -11,6 +11,6 @@
|
||||
padding: 0 @LargeSpace 0 @SmallSpace;
|
||||
}
|
||||
|
||||
.throughputInputSpacing {
|
||||
margin-bottom: @SmallSpace;
|
||||
.throughputInputSpacing > :not(:last-child) {
|
||||
margin-bottom: @DefaultSpace;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { ThroughputInput } from "./ThroughputInput";
|
||||
const props = {
|
||||
isDatabase: false,
|
||||
showFreeTierExceedThroughputTooltip: true,
|
||||
isSharded: false,
|
||||
setThroughputValue: () => jest.fn(),
|
||||
setIsAutoscale: () => jest.fn(),
|
||||
onCostAcknowledgeChange: () => jest.fn(),
|
||||
@@ -22,7 +23,7 @@ describe("ThroughputInput Pane", () => {
|
||||
it("test Autoscale Mode select", () => {
|
||||
wrapper.setProps({ isAutoscaleSelected: true });
|
||||
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");
|
||||
});
|
||||
|
||||
@@ -14,13 +14,15 @@ import * as Constants from "../../../Common/Constants";
|
||||
import { Tooltip } from "../../../Common/Tooltip/Tooltip";
|
||||
import * as SharedConstants from "../../../Shared/Constants";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
||||
import { CostEstimateText } from "./CostEstimateText";
|
||||
import "./styles.less";
|
||||
import { CostEstimateText } from "./CostEstimateText/CostEstimateText";
|
||||
import "./ThroughputInput.less";
|
||||
|
||||
export interface ThroughputInputProps {
|
||||
isDatabase: boolean;
|
||||
isSharded: boolean;
|
||||
showFreeTierExceedThroughputTooltip: boolean;
|
||||
setThroughputValue: (throughput: number) => void;
|
||||
setIsAutoscale: (isAutoscale: boolean) => void;
|
||||
@@ -34,32 +36,40 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
showFreeTierExceedThroughputTooltip,
|
||||
setThroughputValue,
|
||||
setIsAutoscale,
|
||||
isSharded,
|
||||
isAutoscaleSelected = true,
|
||||
throughput = AutoPilotUtils.minAutoPilotThroughput,
|
||||
onCostAcknowledgeChange,
|
||||
}: ThroughputInputProps) => {
|
||||
const [isCostAcknowledged, setIsCostAcknowledged] = useState<boolean>(false);
|
||||
|
||||
const [throughputError, setThroughputError] = useState<string>("");
|
||||
const getThroughputLabelText = (): string => {
|
||||
let throughputHeaderText: string;
|
||||
if (isAutoscaleSelected) {
|
||||
return AutoPilotUtils.getAutoPilotHeaderText();
|
||||
throughputHeaderText = AutoPilotUtils.getAutoPilotHeaderText().toLocaleLowerCase();
|
||||
} else {
|
||||
const minRU: string = SharedConstants.CollectionCreation.DefaultCollectionRUs400.toLocaleString();
|
||||
const maxRU: string = userContext.isTryCosmosDBSubscription
|
||||
? Constants.TryCosmosExperience.maxRU.toLocaleString()
|
||||
: "unlimited";
|
||||
throughputHeaderText = `throughput (${minRU} - ${maxRU} RU/s)`;
|
||||
}
|
||||
const minRU: string = SharedConstants.CollectionCreation.DefaultCollectionRUs400.toLocaleString();
|
||||
const maxRU: string = userContext.isTryCosmosDBSubscription
|
||||
? Constants.TryCosmosExperience.maxRU.toLocaleString()
|
||||
: "unlimited";
|
||||
return isAutoscaleSelected ? AutoPilotUtils.getAutoPilotHeaderText() : `Throughput (${minRU} - ${maxRU} RU/s)`;
|
||||
return `${isDatabase ? "Database" : getCollectionName()} ${throughputHeaderText}`;
|
||||
};
|
||||
|
||||
const onThroughputValueChange = (newInput: string): void => {
|
||||
const newThroughput = parseInt(newInput);
|
||||
setThroughputValue(newThroughput);
|
||||
setIsAutoscale(isAutoscaleSelected);
|
||||
if (!isSharded && newThroughput > 10000) {
|
||||
setThroughputError("Unsharded collections support up to 10,000 RUs");
|
||||
} else {
|
||||
setThroughputError("");
|
||||
}
|
||||
};
|
||||
|
||||
const getAutoScaleTooltip = (): string => {
|
||||
return `After the first ${AutoPilotUtils.getStorageBasedOnUserInput(throughput)} GB of data stored, the max
|
||||
RU/s will be automatically upgraded based on the new storage value.`;
|
||||
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||
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 => {
|
||||
@@ -98,13 +108,13 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
<div className="throughputInputContainer throughputInputSpacing">
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text variant="small" style={{ lineHeight: "20px" }}>
|
||||
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}>
|
||||
{getThroughputLabelText()}
|
||||
</Text>
|
||||
<Tooltip>{PricingUtils.getRuToolTipText()}</Tooltip>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Stack horizontal verticalAlign="center">
|
||||
<ChoiceGroup
|
||||
selectedKey={"" + isAutoscaleSelected}
|
||||
options={optionList}
|
||||
@@ -116,7 +126,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
{isAutoscaleSelected && (
|
||||
<Stack className="throughputInputSpacing">
|
||||
<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">
|
||||
capacity calculator
|
||||
</Link>
|
||||
@@ -124,8 +134,8 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
</Text>
|
||||
|
||||
<Stack horizontal>
|
||||
<Text variant="small" style={{ lineHeight: "20px" }} data-testid="maxRUDescription">
|
||||
Max RU/s
|
||||
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }} data-testid="maxRUDescription">
|
||||
{isDatabase ? "Database" : getCollectionName()} Max RU/s
|
||||
</Text>
|
||||
<Tooltip>{getAutoScaleTooltip()}</Tooltip>
|
||||
</Stack>
|
||||
@@ -142,10 +152,12 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
value={throughput.toString()}
|
||||
aria-label="Max request units per second"
|
||||
required={true}
|
||||
errorMessage={throughputError}
|
||||
/>
|
||||
|
||||
<Text variant="small">
|
||||
Your {isDatabase ? "database" : "container"} throughput will automatically scale from{" "}
|
||||
Your {isDatabase ? "database" : getCollectionName().toLocaleLowerCase()} throughput will automatically scale
|
||||
from{" "}
|
||||
<b>
|
||||
{AutoPilotUtils.getMinRUsBasedOnUserInput(throughput)} RU/s (10% of max RU/s) - {throughput} RU/s
|
||||
</b>{" "}
|
||||
@@ -186,6 +198,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
value={throughput.toString()}
|
||||
aria-label="Max request units per second"
|
||||
required={true}
|
||||
errorMessage={throughputError}
|
||||
/>
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
<ThroughputInput
|
||||
isDatabase={false}
|
||||
isSharded={false}
|
||||
onCostAcknowledgeChange={[Function]}
|
||||
setIsAutoscale={[Function]}
|
||||
setThroughputValue={[Function]}
|
||||
@@ -27,6 +28,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
key=".0:$.1"
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": 600,
|
||||
"lineHeight": "20px",
|
||||
}
|
||||
}
|
||||
@@ -36,11 +38,12 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
className="css-41"
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": 600,
|
||||
"lineHeight": "20px",
|
||||
}
|
||||
}
|
||||
>
|
||||
Throughput (autoscale)
|
||||
Container throughput (autoscale)
|
||||
</span>
|
||||
</Text>
|
||||
<Tooltip
|
||||
@@ -1423,7 +1426,10 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Stack
|
||||
horizontal={true}
|
||||
verticalAlign="center"
|
||||
>
|
||||
<div
|
||||
className="ms-Stack css-51"
|
||||
>
|
||||
@@ -2426,7 +2432,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
className="throughputInputSpacing"
|
||||
>
|
||||
<div
|
||||
className="ms-Stack throughputInputSpacing css-51"
|
||||
className="ms-Stack throughputInputSpacing css-63"
|
||||
>
|
||||
<Text
|
||||
data-testid="ruDescription"
|
||||
@@ -2437,7 +2443,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
className="css-41"
|
||||
data-testid="ruDescription"
|
||||
>
|
||||
Provision maximum RU/s required by this resource. Estimate your required RU/s with
|
||||
Estimate your required RU/s with
|
||||
<StyledLinkBase
|
||||
data-testid="ruDescription"
|
||||
href="https://cosmos.azure.com/capacitycalculator/"
|
||||
@@ -2723,7 +2729,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="ms-Link root-63"
|
||||
className="ms-Link root-64"
|
||||
data-testid="ruDescription"
|
||||
href="https://cosmos.azure.com/capacitycalculator/"
|
||||
onClick={[Function]}
|
||||
@@ -2748,6 +2754,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
key=".0:$.0"
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": 600,
|
||||
"lineHeight": "20px",
|
||||
}
|
||||
}
|
||||
@@ -2758,11 +2765,13 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
data-testid="maxRUDescription"
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": 600,
|
||||
"lineHeight": "20px",
|
||||
}
|
||||
}
|
||||
>
|
||||
Max RU/s
|
||||
Container
|
||||
Max RU/s
|
||||
</span>
|
||||
</Text>
|
||||
<Tooltip
|
||||
@@ -2775,8 +2784,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
"gapSpace": 0,
|
||||
}
|
||||
}
|
||||
content="After the first 40 GB of data stored, the max
|
||||
RU/s will be automatically upgraded based on the new storage value."
|
||||
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."
|
||||
id="tooltip8"
|
||||
styles={
|
||||
Object {
|
||||
@@ -2792,8 +2800,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
"gapSpace": 0,
|
||||
}
|
||||
}
|
||||
content="After the first 40 GB of data stored, the max
|
||||
RU/s will be automatically upgraded based on the new storage value."
|
||||
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."
|
||||
delay={1}
|
||||
id="tooltip8"
|
||||
styles={[Function]}
|
||||
@@ -4149,6 +4156,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
</Stack>
|
||||
<StyledTextFieldBase
|
||||
aria-label="Max request units per second"
|
||||
errorMessage=""
|
||||
key=".0:$.2"
|
||||
min={4000}
|
||||
onChange={[Function]}
|
||||
@@ -4172,6 +4180,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
aria-label="Max request units per second"
|
||||
canRevealPassword={false}
|
||||
deferredValidationTime={200}
|
||||
errorMessage=""
|
||||
min={4000}
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
@@ -4456,17 +4465,17 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
value="4000"
|
||||
>
|
||||
<div
|
||||
className="ms-TextField is-required root-65"
|
||||
className="ms-TextField is-required root-66"
|
||||
>
|
||||
<div
|
||||
className="ms-TextField-wrapper"
|
||||
>
|
||||
<div
|
||||
className="ms-TextField-fieldGroup fieldGroup-66"
|
||||
className="ms-TextField-fieldGroup fieldGroup-67"
|
||||
>
|
||||
<input
|
||||
aria-invalid={false}
|
||||
className="ms-TextField-field field-67"
|
||||
className="ms-TextField-field field-68"
|
||||
id="TextField14"
|
||||
min={4000}
|
||||
onBlur={[Function]}
|
||||
|
||||
@@ -7,7 +7,7 @@ import _ from "underscore";
|
||||
import { AuthType } from "../AuthType";
|
||||
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
||||
import * as Constants from "../Common/Constants";
|
||||
import { ExplorerMetrics } from "../Common/Constants";
|
||||
import { ExplorerMetrics, HttpStatusCodes } from "../Common/Constants";
|
||||
import { readCollection } from "../Common/dataAccess/readCollection";
|
||||
import { readDatabases } from "../Common/dataAccess/readDatabases";
|
||||
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
||||
@@ -19,7 +19,9 @@ import { configContext, Platform } from "../ConfigContext";
|
||||
import * as DataModels from "../Contracts/DataModels";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
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 { ResourceProviderClientFactory } from "../ResourceProvider/ResourceProviderClientFactory";
|
||||
import { RouteHandler } from "../RouteHandlers/RouteHandler";
|
||||
@@ -30,12 +32,12 @@ import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants"
|
||||
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
||||
import { ArcadiaResourceManager } from "../SparkClusterManager/ArcadiaResourceManager";
|
||||
import { userContext } from "../UserContext";
|
||||
import { getCollectionName } from "../Utils/APITypeUtils";
|
||||
import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||
import { stringToBlob } from "../Utils/BlobUtils";
|
||||
import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils";
|
||||
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils";
|
||||
import * as PricingUtils from "../Utils/PricingUtils";
|
||||
import * as ComponentRegisterer from "./ComponentRegisterer";
|
||||
import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker";
|
||||
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
||||
@@ -58,6 +60,7 @@ import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
||||
import { DeleteCollectionConfirmationPane } from "./Panes/DeleteCollectionConfirmationPane/DeleteCollectionConfirmationPane";
|
||||
import { DeleteDatabaseConfirmationPanel } from "./Panes/DeleteDatabaseConfirmationPanel";
|
||||
import { ExecuteSprocParamsPane } from "./Panes/ExecuteSprocParamsPane/ExecuteSprocParamsPane";
|
||||
import { GitHubReposPanel } from "./Panes/GitHubReposPanel/GitHubReposPanel";
|
||||
import GraphStylingPane from "./Panes/GraphStylingPane";
|
||||
import { LoadQueryPane } from "./Panes/LoadQueryPane/LoadQueryPane";
|
||||
import { SaveQueryPane } from "./Panes/SaveQueryPane/SaveQueryPane";
|
||||
@@ -167,10 +170,11 @@ export default class Explorer {
|
||||
public addCollectionPane: AddCollectionPane;
|
||||
public graphStylingPane: GraphStylingPane;
|
||||
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
||||
public gitHubReposPane: ContextualPaneBase;
|
||||
private gitHubClient: GitHubClient;
|
||||
public gitHubOAuthService: GitHubOAuthService;
|
||||
public junoClient: JunoClient;
|
||||
|
||||
// features
|
||||
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
||||
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
||||
public isHostedDataExplorerEnabled: ko.Computed<boolean>;
|
||||
public isRightPanelV2Enabled: ko.Computed<boolean>;
|
||||
@@ -212,6 +216,8 @@ export default class Explorer {
|
||||
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
||||
|
||||
constructor(params?: ExplorerParams) {
|
||||
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
||||
this.junoClient = new JunoClient();
|
||||
this.setIsNotificationConsoleExpanded = params?.setIsNotificationConsoleExpanded;
|
||||
this.setNotificationConsoleData = params?.setNotificationConsoleData;
|
||||
this.setInProgressConsoleDataIdToBeDeleted = params?.setInProgressConsoleDataIdToBeDeleted;
|
||||
@@ -318,7 +324,6 @@ export default class Explorer {
|
||||
this.resourceTokenCollectionId = ko.observable<string>();
|
||||
this.resourceTokenCollection = ko.observable<ViewModels.CollectionBase>();
|
||||
this.resourceTokenPartitionKey = ko.observable<string>();
|
||||
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
||||
this.isMongoIndexingEnabled = ko.observable<boolean>(false);
|
||||
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||
|
||||
@@ -598,9 +603,6 @@ export default class Explorer {
|
||||
refreshCommandBarButtons: () => this.refreshCommandBarButtons(),
|
||||
refreshNotebookList: () => this.refreshNotebookList(),
|
||||
});
|
||||
|
||||
this.gitHubReposPane = this.notebookManager.gitHubReposPane;
|
||||
this.isGitHubPaneEnabled(true);
|
||||
}
|
||||
|
||||
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 {
|
||||
const addSynapseLinkDialogProps: DialogProps = {
|
||||
linkProps: {
|
||||
@@ -1951,14 +1970,14 @@ export default class Explorer {
|
||||
}
|
||||
}
|
||||
|
||||
public onNewCollectionClicked(): void {
|
||||
public onNewCollectionClicked(databaseId?: string): void {
|
||||
if (userContext.apiType === "Cassandra") {
|
||||
this.cassandraAddCollectionPane.open();
|
||||
} else if (userContext.features.enableReactPane) {
|
||||
this.openAddCollectionPanel();
|
||||
} else {
|
||||
} else if (userContext.features.enableKOPanel) {
|
||||
this.addCollectionPane.open(this.selectedDatabaseId());
|
||||
document.getElementById("linkAddCollection").focus();
|
||||
} else {
|
||||
this.openAddCollectionPanel(databaseId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2062,14 +2081,9 @@ export default class Explorer {
|
||||
}
|
||||
|
||||
public openDeleteCollectionConfirmationPane(): void {
|
||||
let collectionName = PricingUtils.getCollectionName(userContext.apiType);
|
||||
this.openSidePanel(
|
||||
"Delete " + collectionName,
|
||||
<DeleteCollectionConfirmationPane
|
||||
explorer={this}
|
||||
collectionName={collectionName}
|
||||
closePanel={this.closeSidePanel}
|
||||
/>
|
||||
"Delete " + getCollectionName(),
|
||||
<DeleteCollectionConfirmationPane explorer={this} closePanel={this.closeSidePanel} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2090,28 +2104,32 @@ export default class Explorer {
|
||||
}
|
||||
|
||||
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 {
|
||||
this.openSidePanel(
|
||||
"Input parameters",
|
||||
<ExecuteSprocParamsPane
|
||||
explorer={this}
|
||||
storedProcedure={storedProcedure}
|
||||
expandConsole={() => this.expandConsole()}
|
||||
closePanel={() => this.closeSidePanel()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public async openAddCollectionPanel(): Promise<void> {
|
||||
public async openAddCollectionPanel(databaseId?: string): Promise<void> {
|
||||
await this.loadDatabaseOffers();
|
||||
this.openSidePanel(
|
||||
"New Collection",
|
||||
"New " + getCollectionName(),
|
||||
<AddCollectionPanel
|
||||
explorer={this}
|
||||
closePanel={() => this.closeSidePanel()}
|
||||
openNotificationConsole={() => this.expandConsole()}
|
||||
databaseId={databaseId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -2148,13 +2166,26 @@ export default class Explorer {
|
||||
this.openSidePanel(
|
||||
"Upload File",
|
||||
<UploadFilePane
|
||||
explorer={this}
|
||||
expandConsole={() => this.expandConsole()}
|
||||
closePanel={this.closeSidePanel}
|
||||
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 {
|
||||
this.openSidePanel(
|
||||
"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 { AuthType } from "../../../AuthType";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { Areas } from "../../../Common/Constants";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
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 { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "../../Explorer";
|
||||
@@ -537,14 +534,7 @@ function createManageGitHubAccountButton(container: Explorer): CommandButtonComp
|
||||
return {
|
||||
iconSrc: GitHubIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (!connectedToGitHub) {
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubConnect, ActionModifiers.Mark, {
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
}
|
||||
container.gitHubReposPane.open();
|
||||
},
|
||||
onCommandClick: () => container.openGitHubReposPanel(label),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
|
||||
@@ -21,7 +21,7 @@ import { getFullName } from "../../Utils/UserUtils";
|
||||
import Explorer from "../Explorer";
|
||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||
import { CopyNotebookPane } from "../Panes/CopyNotebookPane/CopyNotebookPane";
|
||||
import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
||||
// import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
||||
import { PublishNotebookPane } from "../Panes/PublishNotebookPane/PublishNotebookPane";
|
||||
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
||||
import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProvider";
|
||||
@@ -50,7 +50,7 @@ export default class NotebookManager {
|
||||
|
||||
private gitHubContentProvider: GitHubContentProvider;
|
||||
public gitHubOAuthService: GitHubOAuthService;
|
||||
private gitHubClient: GitHubClient;
|
||||
public gitHubClient: GitHubClient;
|
||||
|
||||
public gitHubReposPane: ContextualPaneBase;
|
||||
|
||||
@@ -60,13 +60,6 @@ export default class NotebookManager {
|
||||
|
||||
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
|
||||
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({
|
||||
gitHubClient: this.gitHubClient,
|
||||
@@ -92,9 +85,9 @@ export default class NotebookManager {
|
||||
|
||||
this.gitHubOAuthService.getTokenObservable().subscribe((token) => {
|
||||
this.gitHubClient.setToken(token?.access_token);
|
||||
|
||||
if (this.gitHubReposPane.visible()) {
|
||||
this.gitHubReposPane.open();
|
||||
if (this?.gitHubOAuthService.isLoggedIn()) {
|
||||
this.params.container.closeSidePanel();
|
||||
this.params.container.openGitHubReposPanel("Manager GitHub settings", this.junoClient);
|
||||
}
|
||||
|
||||
this.params.refreshCommandBarButtons();
|
||||
@@ -163,7 +156,7 @@ export default class NotebookManager {
|
||||
undefined,
|
||||
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||
"Connect to GitHub",
|
||||
() => this.gitHubReposPane.open(),
|
||||
() => this.params.container.openGitHubReposPanel("Connect to GitHub"),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
|
||||
@@ -3,7 +3,6 @@ import { ActionContracts } from "../Contracts/ExplorerContracts";
|
||||
import * as ViewModels from "../Contracts/ViewModels";
|
||||
import Explorer from "./Explorer";
|
||||
import { handleOpenAction } from "./OpenActions";
|
||||
import AddCollectionPane from "./Panes/AddCollectionPane";
|
||||
import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
|
||||
|
||||
describe("OpenActions", () => {
|
||||
@@ -15,8 +14,7 @@ describe("OpenActions", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
explorer = {} as Explorer;
|
||||
explorer.addCollectionPane = {} as AddCollectionPane;
|
||||
explorer.addCollectionPane.open = jest.fn();
|
||||
explorer.onNewCollectionClicked = jest.fn();
|
||||
explorer.cassandraAddCollectionPane = {} as CassandraAddCollectionPane;
|
||||
explorer.cassandraAddCollectionPane.open = jest.fn();
|
||||
explorer.closeAllPanes = () => {};
|
||||
@@ -90,24 +88,24 @@ describe("OpenActions", () => {
|
||||
});
|
||||
|
||||
describe("AddCollection pane kind", () => {
|
||||
it("string value should call addCollectionPane.open", () => {
|
||||
it("string value should call explorer.onNewCollectionClicked", () => {
|
||||
const action = {
|
||||
actionType: "OpenPane",
|
||||
paneKind: "AddCollection",
|
||||
};
|
||||
|
||||
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 = {
|
||||
actionType: "OpenPane",
|
||||
paneKind: ActionContracts.PaneKind.AddCollection,
|
||||
};
|
||||
|
||||
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]
|
||||
) {
|
||||
explorer.closeAllPanes();
|
||||
explorer.addCollectionPane.open();
|
||||
explorer.onNewCollectionClicked();
|
||||
} else if (
|
||||
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
||||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
||||
|
||||
@@ -143,7 +143,6 @@
|
||||
size="40"
|
||||
class="collid"
|
||||
data-bind="visible: databaseCreateNew, textInput: databaseId, hasFocus: firstFieldHasFocus"
|
||||
aria-label="Database id"
|
||||
autofocus
|
||||
/>
|
||||
|
||||
@@ -161,7 +160,6 @@
|
||||
size="40"
|
||||
class="collid"
|
||||
data-bind="visible: !databaseCreateNew(), textInput: databaseId, hasFocus: firstFieldHasFocus"
|
||||
aria-label="Database id"
|
||||
/>
|
||||
|
||||
<datalist id="databasesList" data-bind="foreach: databaseIds" data-bind="visible: databaseCreateNew">
|
||||
@@ -246,7 +244,7 @@
|
||||
placeholder="e.g., Container1"
|
||||
size="40"
|
||||
class="textfontclr collid"
|
||||
data-bind="value: collectionId, attr: { 'aria-label': collectionIdTitle }"
|
||||
data-bind="value: collectionId"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -352,7 +350,6 @@
|
||||
attr: {
|
||||
placeholder: partitionKeyPlaceholder,
|
||||
required: partitionKeyVisible(),
|
||||
'aria-label': partitionKeyName,
|
||||
pattern: partitionKeyPattern,
|
||||
title: partitionKeyTitle
|
||||
}"
|
||||
|
||||
@@ -476,7 +476,6 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
userContext.portalEnv,
|
||||
this.isFreeTierAccount(),
|
||||
this.container.isFirstResourceCreated(),
|
||||
userContext.apiType,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
IconButton,
|
||||
IDropdownOption,
|
||||
Link,
|
||||
Separator,
|
||||
Stack,
|
||||
Text,
|
||||
TooltipHost,
|
||||
@@ -23,6 +24,7 @@ import { CollectionCreation, IndexingPolicies } from "../../Shared/Constants";
|
||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { getCollectionName } from "../../Utils/APITypeUtils";
|
||||
import { getUpsellMessage } from "../../Utils/PricingUtils";
|
||||
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
||||
@@ -35,6 +37,7 @@ export interface AddCollectionPanelProps {
|
||||
explorer: Explorer;
|
||||
closePanel: () => void;
|
||||
openNotificationConsole: () => void;
|
||||
databaseId?: string;
|
||||
}
|
||||
|
||||
export interface AddCollectionPanelState {
|
||||
@@ -48,7 +51,7 @@ export interface AddCollectionPanelState {
|
||||
partitionKey: string;
|
||||
enableDedicatedThroughput: boolean;
|
||||
createMongoWildCardIndex: boolean;
|
||||
useHashV1: boolean;
|
||||
useHashV2: boolean;
|
||||
enableAnalyticalStore: boolean;
|
||||
uniqueKeys: string[];
|
||||
errorMessage: string;
|
||||
@@ -67,17 +70,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
createNewDatabase: userContext.apiType !== "Tables",
|
||||
createNewDatabase: userContext.apiType !== "Tables" && !this.props.databaseId,
|
||||
newDatabaseId: "",
|
||||
isSharedThroughputChecked: this.getSharedThroughputDefault(),
|
||||
selectedDatabaseId: userContext.apiType === "Tables" ? CollectionCreation.TablesAPIDefaultDatabase : undefined,
|
||||
selectedDatabaseId:
|
||||
userContext.apiType === "Tables" ? CollectionCreation.TablesAPIDefaultDatabase : this.props.databaseId,
|
||||
collectionId: "",
|
||||
enableIndexing: true,
|
||||
isSharded: userContext.apiType !== "Tables",
|
||||
partitionKey: "",
|
||||
enableDedicatedThroughput: false,
|
||||
createMongoWildCardIndex: true,
|
||||
useHashV1: false,
|
||||
useHashV2: false,
|
||||
enableAnalyticalStore: false,
|
||||
uniqueKeys: [],
|
||||
errorMessage: "",
|
||||
@@ -100,13 +104,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
|
||||
{!this.state.errorMessage && this.isFreeTierAccount() && (
|
||||
<PanelInfoErrorComponent
|
||||
message={getUpsellMessage(
|
||||
userContext.portalEnv,
|
||||
true,
|
||||
this.props.explorer.isFirstResourceCreated(),
|
||||
userContext.apiType,
|
||||
true
|
||||
)}
|
||||
message={getUpsellMessage(userContext.portalEnv, true, this.props.explorer.isFirstResourceCreated(), true)}
|
||||
messageType="info"
|
||||
showErrorDetails={false}
|
||||
openNotificationConsole={this.props.openNotificationConsole}
|
||||
@@ -120,13 +118,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Database id
|
||||
Database {userContext.apiType === "Mongo" ? "name" : "id"}
|
||||
</Text>
|
||||
<TooltipHost
|
||||
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>
|
||||
</Stack>
|
||||
|
||||
@@ -140,7 +140,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="databaseCreateNew"
|
||||
data-test="addCollection-createNewDatabase"
|
||||
tabIndex={0}
|
||||
onChange={this.onCreateNewDatabaseRadioBtnChange.bind(this)}
|
||||
/>
|
||||
@@ -154,8 +153,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
name="databaseType"
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="databaseUseExisting"
|
||||
data-test="addCollection-existingDatabase"
|
||||
tabIndex={0}
|
||||
onChange={this.onUseExistingDatabaseRadioBtnChange.bind(this)}
|
||||
/>
|
||||
@@ -166,8 +163,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
<Stack className="panelGroupSpacing">
|
||||
<input
|
||||
name="newDatabaseId"
|
||||
id="databaseId"
|
||||
data-test="addCollection-newDatabaseId"
|
||||
id="newDatabaseId"
|
||||
aria-required
|
||||
required
|
||||
type="text"
|
||||
@@ -177,7 +173,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
placeholder="Type a new database id"
|
||||
size={40}
|
||||
className="panelTextField"
|
||||
aria-label="Database id"
|
||||
aria-label="New database id"
|
||||
autoFocus
|
||||
value={this.state.newDatabaseId}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||
@@ -188,7 +184,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
{!this.isServerlessAccount() && (
|
||||
<Stack horizontal>
|
||||
<Checkbox
|
||||
label="Provision database throughput"
|
||||
label={`Share throughput across ${getCollectionName(true).toLocaleLowerCase()}`}
|
||||
checked={this.state.isSharedThroughputChecked}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
@@ -201,9 +197,11 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
/>
|
||||
<TooltipHost
|
||||
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>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -216,6 +214,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
isDatabase={true}
|
||||
isAutoscaleSelected={this.isNewDatabaseAutoscale}
|
||||
throughput={this.newDatabaseThroughput}
|
||||
isSharded={this.state.isSharded}
|
||||
setThroughputValue={(throughput: number) => (this.newDatabaseThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (this.isNewDatabaseAutoscale = isAutoscale)}
|
||||
onCostAcknowledgeChange={(isAcknowledge: boolean) => (this.isCostAcknowledged = isAcknowledge)}
|
||||
@@ -232,38 +231,40 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
onChange={(event: React.FormEvent<HTMLDivElement>, database: IDropdownOption) =>
|
||||
this.setState({ selectedDatabaseId: database.key as string })
|
||||
}
|
||||
defaultSelectedKey={this.props.databaseId}
|
||||
responsiveMode={999}
|
||||
/>
|
||||
)}
|
||||
<Separator className="panelSeparator" />
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
{`${this.getCollectionName()} id`}
|
||||
{`${getCollectionName()} ${userContext.apiType === "Mongo" ? "name" : "id"}`}
|
||||
</Text>
|
||||
<TooltipHost
|
||||
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>
|
||||
</Stack>
|
||||
|
||||
<input
|
||||
name="collectionId"
|
||||
id="containerId"
|
||||
data-test="addCollection-collectionId"
|
||||
id="collectionId"
|
||||
type="text"
|
||||
aria-required
|
||||
required
|
||||
autoComplete="off"
|
||||
pattern="[^/?#\\]*[^/?# \\]"
|
||||
title="May not end with space nor contain characters '\' '/' '#' '?'"
|
||||
placeholder={`e.g., ${this.getCollectionName()}1`}
|
||||
placeholder={`e.g., ${getCollectionName()}1`}
|
||||
size={40}
|
||||
className="panelTextField"
|
||||
aria-label={`${this.getCollectionName()} id`}
|
||||
aria-label={`${getCollectionName()} id`}
|
||||
value={this.state.collectionId}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||
this.setState({ collectionId: event.target.value })
|
||||
@@ -322,13 +323,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Sharding options
|
||||
Sharding
|
||||
</Text>
|
||||
<TooltipHost
|
||||
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>
|
||||
</Stack>
|
||||
|
||||
@@ -373,18 +376,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
</Text>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content={`The ${this.getPartitionKeyName()} is used to automatically partition data among
|
||||
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.`}
|
||||
content={this.getPartitionKeyTooltipText()}
|
||||
>
|
||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
||||
<Icon iconName="Info" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="addCollection-partitionKeyValue"
|
||||
data-test="addCollection-partitionKeyValue"
|
||||
aria-required
|
||||
required
|
||||
size={40}
|
||||
@@ -394,9 +394,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
pattern={userContext.apiType === "Gremlin" ? "^/[^/]*" : ".*"}
|
||||
title={userContext.apiType === "Gremlin" ? "May not use composite partition key" : ""}
|
||||
value={this.state.partitionKey}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||
this.setState({ partitionKey: event.target.value })
|
||||
}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
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>
|
||||
)}
|
||||
@@ -404,7 +412,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
{!this.isServerlessAccount() && !this.state.createNewDatabase && this.isSelectedDatabaseSharedThroughput() && (
|
||||
<Stack horizontal verticalAlign="center">
|
||||
<Checkbox
|
||||
label={`Provision dedicated throughput for this ${this.getCollectionName()}`}
|
||||
label={`Provision dedicated throughput for this ${getCollectionName().toLocaleLowerCase()}`}
|
||||
checked={this.state.enableDedicatedThroughput}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
@@ -417,12 +425,14 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
/>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content="You can optionally provision dedicated throughput for a container within a database that has throughput
|
||||
provisioned. This dedicated throughput amount will not be shared with other containers in the database and
|
||||
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 ${getCollectionName(
|
||||
true
|
||||
).toLocaleLowerCase()} in the database and
|
||||
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>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -435,6 +445,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
isDatabase={false}
|
||||
isAutoscaleSelected={this.isCollectionAutoscale}
|
||||
throughput={this.collectionThroughput}
|
||||
isSharded={this.state.isSharded}
|
||||
setThroughputValue={(throughput: number) => (this.collectionThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (this.isCollectionAutoscale = isAutoscale)}
|
||||
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
|
||||
per partition key."
|
||||
>
|
||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
||||
<Icon iconName="Info" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
@@ -508,134 +519,129 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
<CollapsibleSectionComponent title="Advanced" isExpandedByDefault={false}>
|
||||
<Stack className="panelGroupSpacing">
|
||||
{this.props.explorer.isEnableMongoCapabilityPresent() && (
|
||||
<Stack>
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Indexing
|
||||
</Text>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content="By default, only the field _id is indexed. Creating a wildcard index on all fields will quickly optimize
|
||||
query performance and is recommended during development."
|
||||
>
|
||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
{userContext.apiType !== "Tables" && (
|
||||
<CollapsibleSectionComponent
|
||||
title="Advanced"
|
||||
isExpandedByDefault={false}
|
||||
onExpand={() => {
|
||||
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||
this.scrollToAdvancedSection();
|
||||
}}
|
||||
>
|
||||
<Stack className="panelGroupSpacing" id="collapsibleSectionContent">
|
||||
{this.props.explorer.isEnableMongoCapabilityPresent() && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal>
|
||||
<span className="mandatoryStar">* </span>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Indexing
|
||||
</Text>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
|
||||
>
|
||||
<Icon iconName="Info" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
<Checkbox
|
||||
label="Create a Wildcard Index on all fields"
|
||||
checked={this.state.createMongoWildCardIndex}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center" },
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ createMongoWildCardIndex: isChecked })
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{userContext.apiType === "SQL" && (
|
||||
<Checkbox
|
||||
label="Create a Wildcard Index on all fields"
|
||||
checked={this.state.createMongoWildCardIndex}
|
||||
label="My partition key is larger than 100 bytes"
|
||||
checked={this.state.useHashV2}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center" },
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ createMongoWildCardIndex: isChecked })
|
||||
this.setState({ useHashV2: isChecked })
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
)}
|
||||
)}
|
||||
|
||||
{userContext.apiType === "SQL" && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal verticalAlign="start">
|
||||
<Checkbox
|
||||
checked={this.state.useHashV1}
|
||||
styles={{
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, margin: "4px 4px 0 0" },
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ useHashV1: 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() && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Analytical store
|
||||
</Text>
|
||||
<TooltipHost
|
||||
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"
|
||||
>
|
||||
<Icon iconName="InfoSolid" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
<Stack horizontal verticalAlign="center">
|
||||
<input
|
||||
className="panelRadioBtn"
|
||||
checked={this.state.enableAnalyticalStore}
|
||||
disabled={!this.isSynapseLinkEnabled()}
|
||||
aria-label="Enable analytical store"
|
||||
aria-checked={this.state.enableAnalyticalStore}
|
||||
name="analyticalStore"
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="enableAnalyticalStoreBtn"
|
||||
tabIndex={0}
|
||||
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
|
||||
/>
|
||||
<span className="panelRadioBtnLabel">On</span>
|
||||
|
||||
<input
|
||||
className="panelRadioBtn"
|
||||
checked={!this.state.enableAnalyticalStore}
|
||||
disabled={!this.isSynapseLinkEnabled()}
|
||||
aria-label="Disable analytical store"
|
||||
aria-checked={!this.state.enableAnalyticalStore}
|
||||
name="analyticalStore"
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="disableAnalyticalStoreBtn"
|
||||
tabIndex={0}
|
||||
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
|
||||
/>
|
||||
<span className="panelRadioBtnLabel">Off</span>
|
||||
</Stack>
|
||||
|
||||
{!this.isSynapseLinkEnabled() && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Text variant="small">
|
||||
Azure Synapse Link is required for creating an analytical store container. Enable Synapse Link
|
||||
for this Cosmos DB account.{" "}
|
||||
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
|
||||
Learn more
|
||||
</Link>
|
||||
{this.shouldShowAnalyticalStoreOptions() && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Stack horizontal>
|
||||
<Text className="panelTextBold" variant="small">
|
||||
Analytical store
|
||||
</Text>
|
||||
<DefaultButton
|
||||
text="Enable"
|
||||
onClick={() => this.props.explorer.openEnableSynapseLinkDialog()}
|
||||
style={{ height: 27, width: 80 }}
|
||||
styles={{ label: { fontSize: 12 } }}
|
||||
/>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content={this.getAnalyticalStorageTooltipContent()}
|
||||
>
|
||||
<Icon iconName="Info" className="panelInfoIcon" />
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</CollapsibleSectionComponent>
|
||||
|
||||
<Stack horizontal verticalAlign="center">
|
||||
<input
|
||||
className="panelRadioBtn"
|
||||
checked={this.state.enableAnalyticalStore}
|
||||
disabled={!this.isSynapseLinkEnabled()}
|
||||
aria-label="Enable analytical store"
|
||||
aria-checked={this.state.enableAnalyticalStore}
|
||||
name="analyticalStore"
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="enableAnalyticalStoreBtn"
|
||||
tabIndex={0}
|
||||
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
|
||||
/>
|
||||
<span className="panelRadioBtnLabel">On</span>
|
||||
|
||||
<input
|
||||
className="panelRadioBtn"
|
||||
checked={!this.state.enableAnalyticalStore}
|
||||
disabled={!this.isSynapseLinkEnabled()}
|
||||
aria-label="Disable analytical store"
|
||||
aria-checked={!this.state.enableAnalyticalStore}
|
||||
name="analyticalStore"
|
||||
type="radio"
|
||||
role="radio"
|
||||
id="disableAnalyticalStoreBtn"
|
||||
tabIndex={0}
|
||||
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
|
||||
/>
|
||||
<span className="panelRadioBtnLabel">Off</span>
|
||||
</Stack>
|
||||
|
||||
{!this.isSynapseLinkEnabled() && (
|
||||
<Stack className="panelGroupSpacing">
|
||||
<Text variant="small">
|
||||
Azure Synapse Link is required for creating an analytical store{" "}
|
||||
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.{" "}
|
||||
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
|
||||
Learn more
|
||||
</Link>
|
||||
</Text>
|
||||
<DefaultButton
|
||||
text="Enable"
|
||||
onClick={() => this.props.explorer.openEnableSynapseLinkDialog()}
|
||||
style={{ height: 27, width: 80 }}
|
||||
styles={{ label: { fontSize: 12 } }}
|
||||
/>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</CollapsibleSectionComponent>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<PanelFooterComponent buttonLabel="OK" />
|
||||
@@ -652,24 +658,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}));
|
||||
}
|
||||
|
||||
private getCollectionName(): string {
|
||||
switch (userContext.apiType) {
|
||||
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(isLowerCase?: boolean): string {
|
||||
const partitionKeyName = userContext.apiType === "Mongo" ? "Shard key" : "Partition key";
|
||||
|
||||
private getPartitionKeyName(): string {
|
||||
return userContext.apiType === "Mongo" ? "Shard key" : "Partition key";
|
||||
return isLowerCase ? partitionKeyName.toLocaleLowerCase() : partitionKeyName;
|
||||
}
|
||||
|
||||
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.";
|
||||
}
|
||||
|
||||
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 {
|
||||
if (this.isServerlessAccount()) {
|
||||
return false;
|
||||
@@ -883,6 +903,11 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (throughput > CollectionCreation.MaxRUPerPartition && !this.state.isSharded) {
|
||||
this.setState({ errorMessage: "Unsharded collections support up to 10,000 RUs" });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
userContext.apiType === "Gremlin" &&
|
||||
(this.state.partitionKey === "/id" || this.state.partitionKey === "/label")
|
||||
@@ -909,6 +934,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
return Constants.AnalyticalStorageTtl.Disabled;
|
||||
}
|
||||
|
||||
private scrollToAdvancedSection(): void {
|
||||
document.getElementById("collapsibleSectionContent")?.scrollIntoView();
|
||||
}
|
||||
|
||||
private async submit(event: React.FormEvent<HTMLFormElement>): Promise<void> {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -927,7 +956,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
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
|
||||
? {
|
||||
paths: [partitionKeyString],
|
||||
|
||||
@@ -238,7 +238,6 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
||||
userContext.portalEnv,
|
||||
this.isFreeTierAccount(),
|
||||
this.container.isFirstResourceCreated(),
|
||||
userContext.apiType,
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
@@ -15,11 +15,8 @@ import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
||||
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
|
||||
import Explorer from "../../Explorer";
|
||||
import {
|
||||
GenericRightPaneComponent,
|
||||
GenericRightPaneProps,
|
||||
} from "../GenericRightPaneComponent/GenericRightPaneComponent";
|
||||
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
||||
export interface AddDatabasePaneProps {
|
||||
explorer: Explorer;
|
||||
@@ -85,7 +82,6 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
userContext.portalEnv,
|
||||
isFreeTierAccount,
|
||||
container.isFirstResourceCreated(),
|
||||
userContext.apiType,
|
||||
false
|
||||
);
|
||||
|
||||
@@ -254,8 +250,8 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container,
|
||||
const genericPaneProps: RightPaneFormProps = {
|
||||
expandConsole: container.expandConsole,
|
||||
formError: formErrors,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "add-database-inputs",
|
||||
@@ -267,7 +263,7 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<GenericRightPaneComponent {...genericPaneProps}>
|
||||
<RightPaneForm {...genericPaneProps}>
|
||||
<form style={{ height: "100%" }}>
|
||||
<div className="paneContentContainer" role="dialog" aria-labelledby="databaseTitle">
|
||||
{showUpsellMessage && formErrors === "" && (
|
||||
@@ -327,6 +323,7 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
<ThroughputInput
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !container?.isFirstResourceCreated()}
|
||||
isDatabase={true}
|
||||
isSharded={databaseCreateNewShared}
|
||||
isAutoscaleSelected={isAutoPilotSelected}
|
||||
throughput={throughput}
|
||||
setThroughputValue={(throughput: number) => setThroughput(throughput)}
|
||||
@@ -348,6 +345,6 @@ export const AddDatabasePanelF: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</GenericRightPaneComponent>
|
||||
</RightPaneForm>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,505 +1,8 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||
<GenericRightPaneComponent
|
||||
container={
|
||||
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],
|
||||
}
|
||||
}
|
||||
<RightPaneForm
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
id="add-database-inputs"
|
||||
isExecuting={false}
|
||||
@@ -598,6 +101,7 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||
<ThroughputInput
|
||||
isAutoscaleSelected={false}
|
||||
isDatabase={true}
|
||||
isSharded={true}
|
||||
onCostAcknowledgeChange={[Function]}
|
||||
setIsAutoscale={[Function]}
|
||||
setThroughputValue={[Function]}
|
||||
@@ -608,5 +112,5 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</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 = {
|
||||
container,
|
||||
formError,
|
||||
formErrorDetail,
|
||||
id: "copynotebookpane",
|
||||
@@ -140,6 +139,7 @@ export const CopyNotebookPane: FunctionComponent<CopyNotebookPanelProps> = ({
|
||||
submitButtonText: "OK",
|
||||
onClose: closePanel,
|
||||
onSubmit: () => submit(),
|
||||
expandConsole: () => container.expandConsole(),
|
||||
};
|
||||
|
||||
const copyNotebookPaneProps: CopyNotebookPaneProps = {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DefaultExperienceUtility } from "../../../Shared/DefaultExperienceUtili
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
|
||||
import Explorer from "../../Explorer";
|
||||
import {
|
||||
@@ -17,14 +18,12 @@ import {
|
||||
} from "../GenericRightPaneComponent/GenericRightPaneComponent";
|
||||
export interface DeleteCollectionConfirmationPaneProps {
|
||||
explorer: Explorer;
|
||||
collectionName: string;
|
||||
closePanel: () => void;
|
||||
}
|
||||
|
||||
export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectionConfirmationPaneProps> = ({
|
||||
explorer,
|
||||
closePanel,
|
||||
collectionName,
|
||||
}: DeleteCollectionConfirmationPaneProps) => {
|
||||
const [deleteCollectionFeedback, setDeleteCollectionFeedback] = useState<string>("");
|
||||
const [inputCollectionName, setInputCollectionName] = useState<string>("");
|
||||
@@ -34,6 +33,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
const shouldRecordFeedback = (): boolean => {
|
||||
return explorer.isLastCollection() && !explorer.isSelectedDatabaseShared();
|
||||
};
|
||||
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||
const paneTitle = "Delete " + collectionName;
|
||||
const submit = async (): Promise<void> => {
|
||||
const collection = explorer.findSelectedCollection();
|
||||
@@ -101,7 +101,6 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
}
|
||||
};
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container: explorer,
|
||||
formError: formError,
|
||||
formErrorDetail: formError,
|
||||
id: "deleteCollectionpane",
|
||||
@@ -110,6 +109,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
submitButtonText: "OK",
|
||||
onClose: closePanel,
|
||||
onSubmit: submit,
|
||||
expandConsole: () => explorer.expandConsole(),
|
||||
};
|
||||
return (
|
||||
<GenericRightPaneComponent {...genericPaneProps}>
|
||||
|
||||
@@ -16,16 +16,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
|
||||
}
|
||||
>
|
||||
<GenericRightPaneComponent
|
||||
container={
|
||||
Object {
|
||||
"findSelectedCollection": [Function],
|
||||
"isLastCollection": [Function],
|
||||
"isSelectedDatabaseShared": [Function],
|
||||
"refreshAllDatabases": [Function],
|
||||
"selectedCollectionId": [Function],
|
||||
"selectedNode": [Function],
|
||||
}
|
||||
}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="deleteCollectionpane"
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { mount } from "enzyme";
|
||||
import React from "react";
|
||||
import Explorer from "../../Explorer";
|
||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||
import { ExecuteSprocParamsPane } from "./ExecuteSprocParamsPane";
|
||||
|
||||
describe("Excute Sproc Param Pane", () => {
|
||||
const fakeExplorer = {} as Explorer;
|
||||
const fakeSproc = {} as StoredProcedure;
|
||||
const props = {
|
||||
explorer: fakeExplorer,
|
||||
storedProcedure: fakeSproc,
|
||||
expandConsole: (): 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 React, { FunctionComponent, useState } from "react";
|
||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||
import Explorer from "../../Explorer";
|
||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||
import {
|
||||
GenericRightPaneComponent,
|
||||
@@ -11,7 +10,7 @@ import {
|
||||
import { InputParameter } from "./InputParameter";
|
||||
|
||||
interface ExecuteSprocParamsPaneProps {
|
||||
explorer: Explorer;
|
||||
expandConsole: () => void;
|
||||
storedProcedure: StoredProcedure;
|
||||
closePanel: () => void;
|
||||
}
|
||||
@@ -27,7 +26,7 @@ interface UnwrappedExecuteSprocParam {
|
||||
}
|
||||
|
||||
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
|
||||
explorer,
|
||||
expandConsole,
|
||||
storedProcedure,
|
||||
closePanel,
|
||||
}: ExecuteSprocParamsPaneProps): JSX.Element => {
|
||||
@@ -43,7 +42,7 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
||||
};
|
||||
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container: explorer,
|
||||
expandConsole,
|
||||
formError: formError,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "executesprocparamspane",
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
exports[`Excute Sproc Param Pane should render Default properly 1`] = `
|
||||
<ExecuteSprocParamsPane
|
||||
closePanel={[Function]}
|
||||
explorer={Object {}}
|
||||
expandConsole={[Function]}
|
||||
storedProcedure={Object {}}
|
||||
>
|
||||
<GenericRightPaneComponent
|
||||
container={Object {}}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="executesprocparamspane"
|
||||
|
||||
@@ -3,10 +3,9 @@ import React, { FunctionComponent, ReactNode } from "react";
|
||||
import ErrorRedIcon from "../../../../images/error_red.svg";
|
||||
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
|
||||
import { KeyCodes } from "../../../Common/Constants";
|
||||
import Explorer from "../../Explorer";
|
||||
|
||||
export interface GenericRightPaneProps {
|
||||
container: Explorer;
|
||||
expandConsole: () => void;
|
||||
formError: string;
|
||||
formErrorDetail: string;
|
||||
id: string;
|
||||
@@ -20,7 +19,7 @@ export interface GenericRightPaneProps {
|
||||
}
|
||||
|
||||
export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps> = ({
|
||||
container,
|
||||
expandConsole,
|
||||
formError,
|
||||
formErrorDetail,
|
||||
id,
|
||||
@@ -68,7 +67,7 @@ export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps>
|
||||
<span className="formErrors" title={formError}>
|
||||
{formError}
|
||||
</span>
|
||||
<a className="errorLink" role="link" hidden={!formErrorDetail} onClick={showErrorDetail}>
|
||||
<a className="errorLink" role="link" hidden={!formErrorDetail} onClick={expandConsole}>
|
||||
More details
|
||||
</a>
|
||||
</span>
|
||||
@@ -110,10 +109,6 @@ export const GenericRightPaneComponent: FunctionComponent<GenericRightPaneProps>
|
||||
}
|
||||
};
|
||||
|
||||
const showErrorDetail = (): void => {
|
||||
container.expandConsole();
|
||||
};
|
||||
|
||||
return (
|
||||
<div tabIndex={-1} onKeyDown={onKeyDown}>
|
||||
<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 { Areas, HttpStatusCodes } from "../../Common/Constants";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { GitHubClient, IGitHubPageInfo, IGitHubRepo } from "../../GitHub/GitHubClient";
|
||||
import { IPinnedRepo, JunoClient } from "../../Juno/JunoClient";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import * as JunoUtils from "../../Utils/JunoUtils";
|
||||
import { AuthorizeAccessComponent } from "../Controls/GitHub/AuthorizeAccessComponent";
|
||||
import { GitHubReposComponent, GitHubReposComponentProps, RepoListItem } from "../Controls/GitHub/GitHubReposComponent";
|
||||
import { GitHubReposComponentAdapter } from "../Controls/GitHub/GitHubReposComponentAdapter";
|
||||
import { BranchesProps, PinnedReposProps, UnpinnedReposProps } from "../Controls/GitHub/ReposListComponent";
|
||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { handleError } from "../../Common/ErrorHandlingUtils";
|
||||
import React from "react";
|
||||
import { Areas, HttpStatusCodes } from "../../../Common/Constants";
|
||||
import { handleError } from "../../../Common/ErrorHandlingUtils";
|
||||
import { GitHubClient, IGitHubPageInfo, IGitHubRepo } from "../../../GitHub/GitHubClient";
|
||||
import { IPinnedRepo, JunoClient } from "../../../Juno/JunoClient";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import * as GitHubUtils from "../../../Utils/GitHubUtils";
|
||||
import * as JunoUtils from "../../../Utils/JunoUtils";
|
||||
import { AuthorizeAccessComponent } from "../../Controls/GitHub/AuthorizeAccessComponent";
|
||||
import {
|
||||
GitHubReposComponent,
|
||||
GitHubReposComponentProps,
|
||||
RepoListItem,
|
||||
} 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 {
|
||||
gitHubClient: GitHubClient;
|
||||
junoClient: JunoClient;
|
||||
interface IGitHubReposPanelProps {
|
||||
explorer: Explorer;
|
||||
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 isAddedRepo = false;
|
||||
private gitHubClient: GitHubClient;
|
||||
private junoClient: JunoClient;
|
||||
|
||||
@@ -29,73 +44,73 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
private pinnedReposProps: PinnedReposProps;
|
||||
private unpinnedReposProps: UnpinnedReposProps;
|
||||
|
||||
private gitHubReposProps: GitHubReposComponentProps;
|
||||
private gitHubReposAdapter: GitHubReposComponentAdapter;
|
||||
|
||||
private allGitHubRepos: IGitHubRepo[];
|
||||
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
||||
private pinnedReposUpdated: boolean;
|
||||
|
||||
constructor(options: GitHubReposPaneOptions) {
|
||||
super(options);
|
||||
constructor(props: IGitHubReposPanelProps) {
|
||||
super(props);
|
||||
|
||||
this.gitHubClient = options.gitHubClient;
|
||||
this.junoClient = options.junoClient;
|
||||
|
||||
this.branchesProps = {};
|
||||
this.pinnedReposProps = {
|
||||
repos: [],
|
||||
};
|
||||
this.unpinnedReposProps = {
|
||||
repos: [],
|
||||
hasMore: true,
|
||||
isLoading: true,
|
||||
loadMore: (): Promise<void> => this.loadMoreUnpinnedRepos(),
|
||||
};
|
||||
|
||||
this.gitHubReposProps = {
|
||||
showAuthorizeAccess: true,
|
||||
authorizeAccessProps: {
|
||||
scope: this.getOAuthScope(),
|
||||
authorizeAccess: (scope): void => this.connectToGitHub(scope),
|
||||
},
|
||||
reposListProps: {
|
||||
branchesProps: this.branchesProps,
|
||||
pinnedReposProps: this.pinnedReposProps,
|
||||
unpinnedReposProps: this.unpinnedReposProps,
|
||||
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
||||
unpinRepo: (item): Promise<void> => this.unpinRepo(item),
|
||||
},
|
||||
addRepoProps: {
|
||||
container: this.container,
|
||||
getRepo: (owner, repo): Promise<IGitHubRepo> => this.getRepo(owner, repo),
|
||||
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
||||
},
|
||||
resetConnection: (): void => this.setup(true),
|
||||
onOkClick: (): Promise<void> => this.submit(),
|
||||
onCancelClick: (): void => this.cancel(),
|
||||
this.branchesProps = {};
|
||||
this.pinnedReposProps = {
|
||||
repos: [],
|
||||
};
|
||||
this.gitHubReposAdapter = new GitHubReposComponentAdapter(this.gitHubReposProps);
|
||||
|
||||
this.allGitHubRepos = [];
|
||||
this.allGitHubReposLastPageInfo = undefined;
|
||||
this.pinnedReposUpdated = false;
|
||||
|
||||
this.state = {
|
||||
showAuthorizationAcessState: true,
|
||||
isExecuting: false,
|
||||
errorMessage: "",
|
||||
showErrorDetails: false,
|
||||
gitHubReposState: {
|
||||
showAuthorizeAccess: !this.props.explorer.notebookManager?.gitHubOAuthService.isLoggedIn(),
|
||||
authorizeAccessProps: {
|
||||
scope: this.getOAuthScope(),
|
||||
authorizeAccess: (scope): void => this.connectToGitHub(scope),
|
||||
},
|
||||
reposListProps: {
|
||||
branchesProps: this.branchesProps,
|
||||
pinnedReposProps: this.pinnedReposProps,
|
||||
unpinnedReposProps: this.unpinnedReposProps,
|
||||
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
||||
unpinRepo: (item): Promise<void> => this.unpinRepo(item),
|
||||
},
|
||||
addRepoProps: {
|
||||
container: this.props.explorer,
|
||||
getRepo: (owner, repo): Promise<IGitHubRepo> => this.getRepo(owner, repo),
|
||||
pinRepo: (item): Promise<void> => this.pinRepo(item),
|
||||
},
|
||||
resetConnection: (): void => this.setup(true),
|
||||
onOkClick: (): Promise<void> => this.submit(),
|
||||
onCancelClick: (): void => this.props.closePanel(),
|
||||
},
|
||||
};
|
||||
this.gitHubClient = this.props.gitHubClientProp;
|
||||
this.junoClient = this.props.junoClientProp;
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.open();
|
||||
}
|
||||
|
||||
public open(): void {
|
||||
this.resetData();
|
||||
this.setup();
|
||||
|
||||
super.open();
|
||||
}
|
||||
|
||||
public async submit(): Promise<void> {
|
||||
const pinnedReposUpdated = this.pinnedReposUpdated;
|
||||
const reposToPin: IPinnedRepo[] = this.pinnedReposProps.repos.map((repo) => JunoUtils.toPinnedRepo(repo));
|
||||
|
||||
// Submit resets data too
|
||||
super.submit();
|
||||
|
||||
if (pinnedReposUpdated) {
|
||||
try {
|
||||
const response = await this.junoClient.updatePinnedRepos(reposToPin);
|
||||
@@ -109,57 +124,44 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
}
|
||||
|
||||
public resetData(): void {
|
||||
// Reset cached branches
|
||||
this.branchesProps = {};
|
||||
this.gitHubReposProps.reposListProps.branchesProps = this.branchesProps;
|
||||
|
||||
// Reset cached pinned and unpinned repos
|
||||
this.pinnedReposProps.repos = [];
|
||||
this.unpinnedReposProps.repos = [];
|
||||
|
||||
// Reset cached repos
|
||||
this.allGitHubRepos = [];
|
||||
this.allGitHubReposLastPageInfo = undefined;
|
||||
|
||||
// Reset flags
|
||||
this.pinnedReposUpdated = false;
|
||||
this.unpinnedReposProps.hasMore = true;
|
||||
this.unpinnedReposProps.isLoading = true;
|
||||
|
||||
this.triggerRender();
|
||||
|
||||
super.resetData();
|
||||
}
|
||||
|
||||
private getOAuthScope(): string {
|
||||
return (
|
||||
this.container.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope ||
|
||||
this.props.explorer.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope ||
|
||||
AuthorizeAccessComponent.Scopes.Public.key
|
||||
);
|
||||
}
|
||||
|
||||
private setup(forceShowConnectToGitHub = false): void {
|
||||
forceShowConnectToGitHub || !this.container.notebookManager?.gitHubOAuthService.isLoggedIn()
|
||||
forceShowConnectToGitHub || !this.props.explorer.notebookManager?.gitHubOAuthService.isLoggedIn()
|
||||
? this.setupForConnectToGitHub()
|
||||
: this.setupForManageRepos();
|
||||
}
|
||||
|
||||
private setupForConnectToGitHub(): void {
|
||||
this.gitHubReposProps.showAuthorizeAccess = true;
|
||||
this.gitHubReposProps.authorizeAccessProps.scope = this.getOAuthScope();
|
||||
this.isExecuting(false);
|
||||
this.title(GitHubReposComponent.ConnectToGitHubTitle); // Used for telemetry
|
||||
this.triggerRender();
|
||||
this.setState({
|
||||
isExecuting: false,
|
||||
});
|
||||
}
|
||||
|
||||
private async setupForManageRepos(): Promise<void> {
|
||||
this.gitHubReposProps.showAuthorizeAccess = false;
|
||||
this.isExecuting(false);
|
||||
this.title(GitHubReposComponent.ManageGitHubRepoTitle); // Used for telemetry
|
||||
this.setState({
|
||||
isExecuting: false,
|
||||
});
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubManageRepo, ActionModifiers.Mark, {
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
this.triggerRender();
|
||||
|
||||
this.refreshManageReposComponent();
|
||||
}
|
||||
@@ -182,15 +184,15 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
const branchesProps = this.branchesProps[GitHubUtils.toRepoFullName(repo.owner, repo.name)];
|
||||
branchesProps.hasMore = true;
|
||||
branchesProps.isLoading = true;
|
||||
this.triggerRender();
|
||||
|
||||
try {
|
||||
const response = await this.gitHubClient.getBranchesAsync(
|
||||
repo.owner,
|
||||
repo.name,
|
||||
GitHubReposPane.PageSize,
|
||||
GitHubReposPanel.PageSize,
|
||||
branchesProps.lastPageInfo?.endCursor
|
||||
);
|
||||
|
||||
if (response.status !== HttpStatusCodes.OK) {
|
||||
throw new Error(`Received HTTP ${response.status} when fetching branches`);
|
||||
}
|
||||
@@ -205,19 +207,37 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
|
||||
branchesProps.isLoading = false;
|
||||
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> {
|
||||
this.unpinnedReposProps.isLoading = true;
|
||||
this.unpinnedReposProps.hasMore = true;
|
||||
this.triggerRender();
|
||||
|
||||
try {
|
||||
const response = await this.gitHubClient.getReposAsync(
|
||||
GitHubReposPane.PageSize,
|
||||
GitHubReposPanel.PageSize,
|
||||
this.allGitHubReposLastPageInfo?.endCursor
|
||||
);
|
||||
|
||||
if (response.status !== HttpStatusCodes.OK) {
|
||||
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.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> {
|
||||
@@ -242,7 +276,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
if (response.status !== HttpStatusCodes.OK) {
|
||||
throw new Error(`Received HTTP ${response.status} when fetching repo`);
|
||||
}
|
||||
|
||||
this.isAddedRepo = true;
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleError(error, "GitHubReposPane/getRepo", "Failed to fetch repo");
|
||||
@@ -254,7 +288,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
this.pinnedReposUpdated = true;
|
||||
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) {
|
||||
existingRepo.branches = item.branches;
|
||||
} else {
|
||||
@@ -262,7 +296,6 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
}
|
||||
|
||||
this.unpinnedReposProps.repos = this.calculateUnpinnedRepos();
|
||||
this.triggerRender();
|
||||
|
||||
if (this.pinnedReposProps.repos.length > initialReposLength) {
|
||||
this.refreshBranchesForPinnedRepos();
|
||||
@@ -273,7 +306,22 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
this.pinnedReposUpdated = true;
|
||||
this.pinnedReposProps.repos = this.pinnedReposProps.repos.filter((pinnedRepo) => pinnedRepo.key !== item.key);
|
||||
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> {
|
||||
@@ -284,12 +332,12 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
|
||||
private async refreshPinnedRepoListItems(): Promise<void> {
|
||||
this.pinnedReposProps.repos = [];
|
||||
this.triggerRender();
|
||||
|
||||
try {
|
||||
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) {
|
||||
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.triggerRender();
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error, "GitHubReposPane/refreshPinnedReposListItems", "Failed to fetch pinned repos");
|
||||
@@ -322,28 +369,85 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
isLoading: true,
|
||||
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);
|
||||
} 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> {
|
||||
this.allGitHubRepos = [];
|
||||
this.allGitHubReposLastPageInfo = undefined;
|
||||
this.unpinnedReposProps.repos = [];
|
||||
|
||||
this.loadMoreUnpinnedRepos();
|
||||
}
|
||||
|
||||
private connectToGitHub(scope: string): void {
|
||||
this.isExecuting(true);
|
||||
this.setState({
|
||||
isExecuting: true,
|
||||
});
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubAuthorize, ActionModifiers.Mark, {
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
scopesSelected: scope,
|
||||
});
|
||||
this.container.notebookManager?.gitHubOAuthService.startOAuth(scope);
|
||||
this.props.explorer.notebookManager?.gitHubOAuthService.startOAuth(scope);
|
||||
}
|
||||
|
||||
private triggerRender(): void {
|
||||
this.gitHubReposAdapter.triggerRender();
|
||||
render(): JSX.Element {
|
||||
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 genericPaneProps: GenericRightPaneProps = {
|
||||
container: explorer,
|
||||
expandConsole: () => explorer.expandConsole(),
|
||||
formError: formError,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "loadQueryPane",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`Load Query Pane should render Default properly 1`] = `
|
||||
<GenericRightPaneComponent
|
||||
container={Object {}}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="loadQueryPane"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import AddCollectionPaneTemplate from "./AddCollectionPane.html";
|
||||
import AddDatabasePaneTemplate from "./AddDatabasePane.html";
|
||||
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
|
||||
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
||||
import GraphStylingPaneTemplate from "./GraphStylingPane.html";
|
||||
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.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;
|
||||
overflow: auto;
|
||||
|
||||
& > * {
|
||||
& > :not(.collapsibleSection) {
|
||||
margin-bottom: @DefaultSpace;
|
||||
|
||||
& > * {
|
||||
margin-bottom: @SmallSpace;
|
||||
& > :not(:last-child) {
|
||||
margin-bottom: @DefaultSpace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
font-size: @mediumFontSize;
|
||||
width: @mediumFontSize;
|
||||
margin: auto 0 auto @SmallSpace;
|
||||
color: @InfoIconColor;
|
||||
cursor: default;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@@ -49,10 +48,6 @@
|
||||
font-size: @mediumFontSize;
|
||||
padding: 0 @LargeSpace 0 @SmallSpace;
|
||||
}
|
||||
|
||||
.collapsibleSection {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +94,7 @@
|
||||
}
|
||||
|
||||
.panelFooter {
|
||||
padding: 20px 34px;
|
||||
padding: 16px 34px;
|
||||
border-top: solid 1px #bbbbbb;
|
||||
|
||||
& button {
|
||||
@@ -123,8 +118,8 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.panelGroupSpacing > * {
|
||||
margin-bottom: @SmallSpace;
|
||||
.panelGroupSpacing > :not(:last-child) {
|
||||
margin-bottom: @DefaultSpace;
|
||||
}
|
||||
.fileUpload {
|
||||
display: none !important;
|
||||
@@ -170,3 +165,6 @@
|
||||
.column-select-view {
|
||||
margin: 20px 0px 0px 0px;
|
||||
}
|
||||
.panelSeparator::before {
|
||||
background-color: #edebe9;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
|
||||
|
||||
return (
|
||||
formError && (
|
||||
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="start">
|
||||
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="center">
|
||||
{icon}
|
||||
<span className="panelWarningErrorDetailsLinkContainer">
|
||||
<Text className="panelWarningErrorMessage" variant="small" data-testid="panelmessage">
|
||||
|
||||
@@ -158,7 +158,6 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
};
|
||||
|
||||
const props: GenericRightPaneProps = {
|
||||
container: container,
|
||||
formError: formError,
|
||||
formErrorDetail: formErrorDetail,
|
||||
id: "publishnotebookpane",
|
||||
@@ -167,6 +166,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
submitButtonText: "Publish",
|
||||
onSubmit: () => submit(),
|
||||
onClose: closePanel,
|
||||
expandConsole: () => container.expandConsole(),
|
||||
isSubmitButtonHidden: !isCodeOfConductAccepted,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import React from "react";
|
||||
import Explorer from "../../Explorer";
|
||||
import { RightPaneForm } from "./RightPaneForm";
|
||||
|
||||
const onClose = jest.fn();
|
||||
const onSubmit = jest.fn();
|
||||
const expandConsole = jest.fn();
|
||||
|
||||
const props = {
|
||||
closePanel: (): void => undefined,
|
||||
container: new Explorer(),
|
||||
expandConsole,
|
||||
formError: "",
|
||||
formErrorDetail: "",
|
||||
id: "loadQueryPane",
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { IconButton } from "office-ui-fabric-react/lib/Button";
|
||||
import React, { FunctionComponent, ReactNode } from "react";
|
||||
import { KeyCodes } from "../../../Common/Constants";
|
||||
import Explorer from "../../Explorer";
|
||||
import { PanelFooterComponent } from "../PanelFooterComponent";
|
||||
import { PanelInfoErrorComponent, PanelInfoErrorProps } from "../PanelInfoErrorComponent";
|
||||
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
||||
|
||||
export interface RightPaneFormProps {
|
||||
container: Explorer;
|
||||
expandConsole: () => void;
|
||||
formError: string;
|
||||
formErrorDetail: string;
|
||||
id: string;
|
||||
@@ -21,7 +20,7 @@ export interface RightPaneFormProps {
|
||||
}
|
||||
|
||||
export const RightPaneForm: FunctionComponent<RightPaneFormProps> = ({
|
||||
container,
|
||||
expandConsole,
|
||||
formError,
|
||||
formErrorDetail,
|
||||
id,
|
||||
@@ -70,16 +69,12 @@ export const RightPaneForm: FunctionComponent<RightPaneFormProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const showErrorDetail = (): void => {
|
||||
container.expandConsole();
|
||||
};
|
||||
|
||||
const panelInfoErrorProps: PanelInfoErrorProps = {
|
||||
messageType: "error",
|
||||
message: formError,
|
||||
formError: formError !== "",
|
||||
showErrorDetails: formErrorDetail !== "",
|
||||
openNotificationConsole: showErrorDetail,
|
||||
openNotificationConsole: expandConsole,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,504 +3,7 @@
|
||||
exports[`Load Query Pane should render Default properly 1`] = `
|
||||
<RightPaneForm
|
||||
closePanel={[Function]}
|
||||
container={
|
||||
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],
|
||||
}
|
||||
}
|
||||
expandConsole={[MockFunction]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="loadQueryPane"
|
||||
@@ -1554,7 +1057,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
||||
>
|
||||
<button
|
||||
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-testid="closePaneBtn"
|
||||
onClick={[Function]}
|
||||
@@ -1568,16 +1071,16 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="ms-Button-flexContainer flexContainer-105"
|
||||
className="ms-Button-flexContainer flexContainer-41"
|
||||
data-automationid="splitbuttonprimary"
|
||||
>
|
||||
<Component
|
||||
className="ms-Button-icon icon-107"
|
||||
className="ms-Button-icon icon-43"
|
||||
iconName="Cancel"
|
||||
>
|
||||
<i
|
||||
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"
|
||||
role="presentation"
|
||||
style={
|
||||
@@ -1600,7 +1103,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
||||
formError={false}
|
||||
message=""
|
||||
messageType="error"
|
||||
openNotificationConsole={[Function]}
|
||||
openNotificationConsole={[MockFunction]}
|
||||
showErrorDetails={false}
|
||||
/>
|
||||
<form
|
||||
@@ -3294,7 +2797,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
||||
>
|
||||
<button
|
||||
aria-label="Load"
|
||||
className="ms-Button ms-Button--primary root-113"
|
||||
className="ms-Button ms-Button--primary root-49"
|
||||
data-is-focusable={true}
|
||||
data-testid="submit"
|
||||
id="sidePanelOkButton"
|
||||
@@ -3307,14 +2810,14 @@ exports[`Load Query Pane should render Default properly 1`] = `
|
||||
type="submit"
|
||||
>
|
||||
<span
|
||||
className="ms-Button-flexContainer flexContainer-105"
|
||||
className="ms-Button-flexContainer flexContainer-41"
|
||||
data-automationid="splitbuttonprimary"
|
||||
>
|
||||
<span
|
||||
className="ms-Button-textContainer textContainer-106"
|
||||
className="ms-Button-textContainer textContainer-42"
|
||||
>
|
||||
<span
|
||||
className="ms-Button-label label-114"
|
||||
className="ms-Button-label label-50"
|
||||
id="id__3"
|
||||
key="id__3"
|
||||
>
|
||||
|
||||
@@ -32,7 +32,7 @@ export const SaveQueryPane: FunctionComponent<SaveQueryPaneProps> = ({
|
||||
const title = "Save Query";
|
||||
const { canSaveQueries } = explorer;
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container: explorer,
|
||||
expandConsole: () => explorer.expandConsole(),
|
||||
formError: formError,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "saveQueryPane",
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
exports[`Save Query Pane should render Default properly 1`] = `
|
||||
<GenericRightPaneComponent
|
||||
container={
|
||||
Object {
|
||||
"canSaveQueries": [Function],
|
||||
}
|
||||
}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="saveQueryPane"
|
||||
|
||||
@@ -2,10 +2,9 @@ import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
import { DatabaseAccount } from "../../../Contracts/DataModels";
|
||||
import { updateUserContext } from "../../../UserContext";
|
||||
import Explorer from "../../Explorer";
|
||||
import { SettingsPane } from "./SettingsPane";
|
||||
const props = {
|
||||
explorer: new Explorer(),
|
||||
expandConsole: (): void => undefined,
|
||||
closePanel: (): void => undefined,
|
||||
};
|
||||
describe("Settings Pane", () => {
|
||||
|
||||
@@ -7,16 +7,15 @@ import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility"
|
||||
import * as StringUtility from "../../../Shared/StringUtility";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
|
||||
import Explorer from "../../Explorer";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
||||
export interface SettingsPaneProps {
|
||||
explorer: Explorer;
|
||||
expandConsole: () => void;
|
||||
closePanel: () => void;
|
||||
}
|
||||
|
||||
export const SettingsPane: FunctionComponent<SettingsPaneProps> = ({
|
||||
explorer: container,
|
||||
expandConsole,
|
||||
closePanel,
|
||||
}: SettingsPaneProps) => {
|
||||
const [formErrors, setFormErrors] = useState<string>("");
|
||||
@@ -104,7 +103,7 @@ export const SettingsPane: FunctionComponent<SettingsPaneProps> = ({
|
||||
};
|
||||
|
||||
const genericPaneProps: RightPaneFormProps = {
|
||||
container,
|
||||
expandConsole,
|
||||
formError: formErrors,
|
||||
formErrorDetail: "",
|
||||
id: "settingspane",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -92,7 +92,6 @@ export const StringInputPane: FunctionComponent<StringInputPanelProps> = ({
|
||||
}
|
||||
};
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container: container,
|
||||
formError: formErrors,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "stringInputPane",
|
||||
@@ -101,6 +100,7 @@ export const StringInputPane: FunctionComponent<StringInputPanelProps> = ({
|
||||
submitButtonText: submitButtonLabel,
|
||||
onClose: closePanel,
|
||||
onSubmit: submit,
|
||||
expandConsole: () => container.expandConsole(),
|
||||
};
|
||||
return (
|
||||
<GenericRightPaneComponent {...genericPaneProps}>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -328,7 +328,7 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
||||
selectedKey={entity.type}
|
||||
entityPropertyPlaceHolder={detailedHelp}
|
||||
entityValuePlaceholder={entity.entityValuePlaceholder}
|
||||
entityValue={entity.value}
|
||||
entityValue={entity.value?.toString()}
|
||||
isEntityTypeDate={entity.isEntityTypeDate}
|
||||
entityTimeValue={entity.entityTimeValue}
|
||||
isEntityValueDisable={entity.isEntityValueDisable}
|
||||
|
||||
@@ -11,7 +11,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
|
||||
}
|
||||
>
|
||||
<GenericRightPaneComponent
|
||||
container={Object {}}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="querySelectPane"
|
||||
|
||||
@@ -32,7 +32,6 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
|
||||
const [isAvailableColumnChecked, setIsAvailableColumnChecked] = useState<boolean>(true);
|
||||
|
||||
const genericPaneProps: GenericRightPaneProps = {
|
||||
container: explorer,
|
||||
formError: "",
|
||||
formErrorDetail: "",
|
||||
id: "querySelectPane",
|
||||
@@ -41,6 +40,7 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
|
||||
submitButtonText: "OK",
|
||||
onClose: () => closePanel(),
|
||||
onSubmit: () => submit(),
|
||||
expandConsole: () => explorer.expandConsole(),
|
||||
};
|
||||
|
||||
const submit = (): void => {
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
||||
import { Upload } from "../../../Common/Upload/Upload";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||
import Explorer from "../../Explorer";
|
||||
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
||||
export interface UploadFilePanelProps {
|
||||
explorer: Explorer;
|
||||
expandConsole: () => void;
|
||||
closePanel: () => void;
|
||||
uploadFile: (name: string, content: string) => Promise<NotebookContentItem>;
|
||||
}
|
||||
|
||||
export const UploadFilePane: FunctionComponent<UploadFilePanelProps> = ({
|
||||
explorer: container,
|
||||
expandConsole,
|
||||
closePanel,
|
||||
uploadFile,
|
||||
}: UploadFilePanelProps) => {
|
||||
@@ -90,7 +89,7 @@ export const UploadFilePane: FunctionComponent<UploadFilePanelProps> = ({
|
||||
};
|
||||
|
||||
const genericPaneProps: RightPaneFormProps = {
|
||||
container: container,
|
||||
expandConsole,
|
||||
formError: formErrors,
|
||||
formErrorDetail: formErrorsDetails,
|
||||
id: "uploadFilePane",
|
||||
|
||||
@@ -68,7 +68,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({
|
||||
};
|
||||
|
||||
const genericPaneProps: RightPaneFormProps = {
|
||||
container: explorer,
|
||||
expandConsole: () => explorer.expandConsole(),
|
||||
formError,
|
||||
formErrorDetail,
|
||||
id: "uploaditemspane",
|
||||
|
||||
@@ -2,504 +2,7 @@
|
||||
|
||||
exports[`Upload Items Pane should render Default properly 1`] = `
|
||||
<RightPaneForm
|
||||
container={
|
||||
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],
|
||||
}
|
||||
}
|
||||
expandConsole={[Function]}
|
||||
formError=""
|
||||
formErrorDetail=""
|
||||
id="uploaditemspane"
|
||||
|
||||
@@ -404,6 +404,773 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
"defaultExperience": [Function],
|
||||
"deleteCollectionText": [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 {
|
||||
"container": [Circular],
|
||||
"firstFieldHasFocus": [Function],
|
||||
@@ -429,7 +1196,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
"isAutoscaleDefaultEnabled": [Function],
|
||||
"isEnableMongoCapabilityPresent": [Function],
|
||||
"isFixedCollectionWithSharedThroughputSupported": [Function],
|
||||
"isGitHubPaneEnabled": [Function],
|
||||
"isHostedDataExplorerEnabled": [Function],
|
||||
"isLastCollection": [Function],
|
||||
"isLastNonEmptyDatabase": [Function],
|
||||
@@ -447,9 +1213,14 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
"isSparkEnabledForAccount": [Function],
|
||||
"isSynapseLinkUpdating": [Function],
|
||||
"isTabsContentExpanded": [Function],
|
||||
"junoClient": JunoClient {
|
||||
"cachedPinnedRepos": [Function],
|
||||
"databaseAccount": undefined,
|
||||
},
|
||||
"memoryUsageInfo": [Function],
|
||||
"notebookBasePath": [Function],
|
||||
"notebookServerInfo": [Function],
|
||||
"onGitHubClientError": [Function],
|
||||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
@@ -525,7 +1296,7 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
|
||||
<Stack
|
||||
className="panelInfoErrorContainer"
|
||||
horizontal={true}
|
||||
verticalAlign="start"
|
||||
verticalAlign="center"
|
||||
>
|
||||
<div
|
||||
className="ms-Stack panelInfoErrorContainer css-140"
|
||||
|
||||
@@ -165,7 +165,7 @@ export function convertEntityToNewDocument(entity: Entities.ITableEntityForTable
|
||||
$id: entity.RowKey._,
|
||||
id: entity.RowKey._,
|
||||
};
|
||||
for (var property in entity) {
|
||||
for (const property in entity) {
|
||||
if (
|
||||
property !== Constants.EntityKeyNames.PartitionKey &&
|
||||
property !== Constants.EntityKeyNames.RowKey &&
|
||||
@@ -176,18 +176,30 @@ export function convertEntityToNewDocument(entity: Entities.ITableEntityForTable
|
||||
property !== keyProperties.attachments &&
|
||||
property !== keyProperties.Id2
|
||||
) {
|
||||
if (entity[property].$ === Constants.TableType.DateTime) {
|
||||
// Convert javascript date back to ticks with 20 zeros padding
|
||||
document[property] = {
|
||||
$t: (<any>DataTypes)[entity[property].$],
|
||||
$v: DateTimeUtilities.convertJSDateToTicksWithPadding(entity[property]._),
|
||||
};
|
||||
} else {
|
||||
document[property] = {
|
||||
$t: (<any>DataTypes)[entity[property].$],
|
||||
$v: entity[property]._,
|
||||
};
|
||||
const propertyValue = entity[property]._;
|
||||
let parsedValue;
|
||||
switch (entity[property].$) {
|
||||
case Constants.TableType.DateTime:
|
||||
parsedValue = DateTimeUtilities.convertJSDateToTicksWithPadding(propertyValue);
|
||||
break;
|
||||
case Constants.TableType.Boolean:
|
||||
parsedValue = propertyValue.toLowerCase() === "true";
|
||||
break;
|
||||
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;
|
||||
|
||||
@@ -5,8 +5,12 @@ import StyleIcon from "../../../images/Style.svg";
|
||||
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { GraphAccessor, GraphExplorerError } from "../Graph/GraphExplorerComponent/GraphExplorer";
|
||||
import { GraphExplorerAdapter } from "../Graph/GraphExplorerComponent/GraphExplorerAdapter";
|
||||
import {
|
||||
GraphAccessor,
|
||||
GraphExplorer,
|
||||
GraphExplorerError,
|
||||
GraphExplorerProps,
|
||||
} from "../Graph/GraphExplorerComponent/GraphExplorer";
|
||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||
import GraphStylingPane from "../Panes/GraphStylingPane";
|
||||
import { NewVertexPanel } from "../Panes/NewVertexPanel/NewVertexPanel";
|
||||
@@ -36,15 +40,13 @@ interface GraphTabOptions extends ViewModels.TabOptions {
|
||||
}
|
||||
|
||||
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
|
||||
public static readonly DEFAULT_NODE_CAPTION = "id";
|
||||
private static readonly LINK_COLOR = "#aaa";
|
||||
private static readonly NODE_SIZE = 10;
|
||||
private static readonly NODE_COLOR = "orange";
|
||||
private static readonly LINK_WIDTH = 1;
|
||||
private graphExplorerAdapter: GraphExplorerAdapter;
|
||||
private graphExplorerProps: GraphExplorerProps;
|
||||
private isNewVertexDisabled: ko.Observable<boolean>;
|
||||
private isPropertyEditing: ko.Observable<boolean>;
|
||||
private isGraphDisplayed: ko.Observable<boolean>;
|
||||
@@ -70,7 +72,7 @@ export default class GraphTab extends TabsBase {
|
||||
this.graphConfig = GraphTab.createGraphConfig();
|
||||
// TODO Merge this with this.graphConfig
|
||||
this.graphConfigUiData = GraphTab.createGraphConfigUiData(this.graphConfig);
|
||||
this.graphExplorerAdapter = new GraphExplorerAdapter({
|
||||
this.graphExplorerProps = {
|
||||
onGraphAccessorCreated: (instance: GraphAccessor): void => {
|
||||
this.graphAccessor = instance;
|
||||
},
|
||||
@@ -89,8 +91,9 @@ export default class GraphTab extends TabsBase {
|
||||
onResetDefaultGraphConfigValues: () => this.setDefaultGraphConfigValues(),
|
||||
graphConfig: this.graphConfig,
|
||||
graphConfigUiData: this.graphConfigUiData,
|
||||
onIsFilterQueryLoading: (isFilterQueryLoading: boolean): void => this.isFilterQueryLoading(isFilterQueryLoading),
|
||||
onIsValidQuery: (isValidQuery: boolean): void => this.isValidQuery(isValidQuery),
|
||||
onIsFilterQueryLoadingChange: (isFilterQueryLoading: boolean): void =>
|
||||
this.isFilterQueryLoading(isFilterQueryLoading),
|
||||
onIsValidQueryChange: (isValidQuery: boolean): void => this.isValidQuery(isValidQuery),
|
||||
collectionPartitionKeyProperty: options.collectionPartitionKeyProperty,
|
||||
graphBackendEndpoint: GraphTab.getGremlinEndpoint(options.account),
|
||||
databaseId: options.databaseId,
|
||||
@@ -103,7 +106,7 @@ export default class GraphTab extends TabsBase {
|
||||
}
|
||||
},
|
||||
resourceId: options.account.id,
|
||||
});
|
||||
};
|
||||
|
||||
this.isFilterQueryLoading = ko.observable(false);
|
||||
this.isValidQuery = ko.observable(true);
|
||||
@@ -115,6 +118,14 @@ export default class GraphTab extends TabsBase {
|
||||
: `${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 {
|
||||
super.onTabClick();
|
||||
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Graph);
|
||||
|
||||
@@ -205,9 +205,8 @@ export default class Database implements ViewModels.Database {
|
||||
this.deleteCollectionsFromList(deltaCollections.toDelete);
|
||||
}
|
||||
|
||||
public openAddCollection(database: Database, event: MouseEvent) {
|
||||
database.container.addCollectionPane.databaseId(database.id());
|
||||
database.container.addCollectionPane.open();
|
||||
public openAddCollection(database: Database) {
|
||||
database.container.openAddCollectionPanel(database.id());
|
||||
}
|
||||
|
||||
public findCollectionWithId(collectionId: string): ViewModels.Collection {
|
||||
|
||||
@@ -197,7 +197,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||
className: "databaseHeader",
|
||||
children: [],
|
||||
isSelected: () => this.isDataNodeSelected(database.id()),
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(this.container),
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(this.container, database.id()),
|
||||
onClick: async (isExpanded) => {
|
||||
// Rewritten version of expandCollapseDatabase():
|
||||
if (isExpanded) {
|
||||
@@ -607,7 +607,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||
gitHubNotebooksTree.contextMenu = [
|
||||
{
|
||||
label: "Manage GitHub settings",
|
||||
onClick: () => this.container.gitHubReposPane.open(),
|
||||
onClick: () => this.container.openGitHubReposPanel("Manage GitHub settings"),
|
||||
},
|
||||
{
|
||||
label: "Disconnect from GitHub",
|
||||
|
||||
@@ -52,7 +52,6 @@ import { useConfig } from "./hooks/useConfig";
|
||||
import { useKnockoutExplorer } from "./hooks/useKnockoutExplorer";
|
||||
import { useSidePanel } from "./hooks/useSidePanel";
|
||||
import { useTabs } from "./hooks/useTabs";
|
||||
import { KOCommentEnd, KOCommentIfStart } from "./koComment";
|
||||
import "./Libs/jquery";
|
||||
import "./Shared/appInsights";
|
||||
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: "graph-styling-pane", params: { data: graphStylingPane} }' />
|
||||
<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} />}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -115,6 +115,7 @@ export enum Action {
|
||||
NotebooksGalleryFavoritesCount,
|
||||
NotebooksGalleryPublishedCount,
|
||||
SelfServe,
|
||||
ExpandAddCollectionPaneAdvancedSection,
|
||||
}
|
||||
|
||||
export const ActionModifiers = {
|
||||
|
||||
@@ -19,7 +19,7 @@ interface UserContext {
|
||||
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
|
||||
// This is coming in a future Cosmos ARM API version as a prperty on databaseAccount
|
||||
apiType?: ApiType;
|
||||
apiType: ApiType;
|
||||
readonly isTryCosmosDBSubscription?: boolean;
|
||||
readonly portalEnv?: PortalEnv;
|
||||
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 { getCollectionName } from "../Utils/APITypeUtils";
|
||||
import * as AutoPilotUtils from "../Utils/AutoPilotUtils";
|
||||
|
||||
interface ComputeRUUsagePriceHourlyArgs {
|
||||
@@ -10,7 +11,7 @@ interface ComputeRUUsagePriceHourlyArgs {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -161,7 +162,7 @@ export function getAutoPilotV3SpendHtml(maxAutoPilotThroughputSet: number, isDat
|
||||
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(
|
||||
maxAutoPilotThroughputSet
|
||||
)} 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> ` +
|
||||
`(${regions} ${regions === 1 ? "region" : "regions"}, ${throughput}RU/s, ${currencySign}${pricePerRu}/RU)` +
|
||||
`<p style='padding: 10px 0px 0px 0px;'>` +
|
||||
`<em>${estimatedCostDisclaimer}</em></p>`
|
||||
`<em>*${estimatedCostDisclaimer}</em></p>`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -261,11 +262,10 @@ export function getUpsellMessage(
|
||||
serverId = "default",
|
||||
isFreeTier = false,
|
||||
isFirstResourceCreated = false,
|
||||
defaultExperience: string,
|
||||
isCollection: boolean
|
||||
): string {
|
||||
if (isFreeTier) {
|
||||
const collectionName = getCollectionName(defaultExperience);
|
||||
const collectionName = getCollectionName().toLocaleLowerCase();
|
||||
const resourceType = isCollection ? collectionName : "database";
|
||||
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.`
|
||||
@@ -277,22 +277,8 @@ export function getUpsellMessage(
|
||||
price = Constants.OfferPricing.MonthlyPricing.mooncake.Standard.StartingPrice;
|
||||
}
|
||||
|
||||
return `Start at ${getCurrencySign(serverId)}${price}/mo per database, multiple containers 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");
|
||||
return `Start at ${getCurrencySign(serverId)}${price}/mo per database, multiple ${getCollectionName(
|
||||
true
|
||||
).toLocaleLowerCase()} included`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
await explorer.click('[data-test="New Collection"]');
|
||||
await explorer.click('[data-test="addCollection-newDatabaseId"]');
|
||||
await explorer.fill('[data-test="addCollection-newDatabaseId"]', databaseId);
|
||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
||||
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 explorer.fill('[aria-label="New database id"]', databaseId);
|
||||
await explorer.fill('[aria-label="Collection id"]', containerId);
|
||||
await explorer.fill('[aria-label="Shard key"]', "/pk");
|
||||
await explorer.click("#sidePanelOkButton");
|
||||
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
||||
await safeClick(explorer, `.nodeItem >> text=${containerId}`);
|
||||
// Create indexing policy
|
||||
|
||||
@@ -15,15 +15,10 @@ test("SQL CRUD", async () => {
|
||||
});
|
||||
|
||||
await explorer.click('[data-test="New Container"]');
|
||||
await explorer.click('[data-test="addCollection-newDatabaseId"]');
|
||||
await explorer.fill('[data-test="addCollection-newDatabaseId"]', databaseId);
|
||||
await explorer.click('[data-test="addCollection-collectionId"]');
|
||||
await explorer.fill('[data-test="addCollection-collectionId"]', containerId);
|
||||
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 explorer.fill('[aria-label="New database id"]', databaseId);
|
||||
await explorer.fill('[aria-label="Container id"]', containerId);
|
||||
await explorer.fill('[aria-label="Partition key"]', "/pk");
|
||||
await explorer.click("#sidePanelOkButton");
|
||||
await safeClick(explorer, `.nodeItem >> text=${databaseId}`);
|
||||
await safeClick(explorer, `[data-test="${containerId}"] [aria-label="More"]`);
|
||||
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="addCollection-collectionId"]');
|
||||
await explorer.fill('[data-test="addCollection-collectionId"]', tableId);
|
||||
await explorer.click('[data-test="addCollection-createCollection"]');
|
||||
await explorer.fill('[aria-label="Table id"]', tableId);
|
||||
await explorer.click("#sidePanelOkButton");
|
||||
await safeClick(explorer, `[data-test="TablesDB"]`);
|
||||
await safeClick(explorer, `[data-test="${tableId}"] [aria-label="More"]`);
|
||||
await safeClick(explorer, 'button[role="menuitem"]:has-text("Delete Table")');
|
||||
|
||||
Reference in New Issue
Block a user