mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-04-22 14:33:34 +01:00
Copilot assisted changes to remove shared throughput options in add database/container.
This commit is contained in:
1
package-lock.json
generated
1
package-lock.json
generated
@@ -15862,6 +15862,7 @@
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export function getNewDatabaseSharedThroughputDefault(): boolean {
|
||||
return false;
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
} from "@fluentui/react";
|
||||
import * as Constants from "Common/Constants";
|
||||
import { createCollection } from "Common/dataAccess/createCollection";
|
||||
import { getNewDatabaseSharedThroughputDefault } from "Common/DatabaseUtility";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { configContext, Platform } from "ConfigContext";
|
||||
import * as DataModels from "Contracts/DataModels";
|
||||
@@ -77,7 +76,6 @@ export const DefaultVectorEmbeddingPolicy: DataModels.VectorEmbeddingPolicy = {
|
||||
export interface AddCollectionPanelState {
|
||||
createNewDatabase: boolean;
|
||||
newDatabaseId: string;
|
||||
isSharedThroughputChecked: boolean;
|
||||
selectedDatabaseId: string;
|
||||
collectionId: string;
|
||||
enableIndexing: boolean;
|
||||
@@ -103,8 +101,6 @@ export interface AddCollectionPanelState {
|
||||
}
|
||||
|
||||
export class AddCollectionPanel extends React.Component<AddCollectionPanelProps, AddCollectionPanelState> {
|
||||
private newDatabaseThroughput: number;
|
||||
private isNewDatabaseAutoscale: boolean;
|
||||
private collectionThroughput: number;
|
||||
private isCollectionAutoscale: boolean;
|
||||
private isCostAcknowledged: boolean;
|
||||
@@ -117,7 +113,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
createNewDatabase:
|
||||
userContext.apiType !== "Tables" && configContext.platform !== Platform.Fabric && !this.props.databaseId,
|
||||
newDatabaseId: props.isQuickstart ? this.getSampleDBName() : "",
|
||||
isSharedThroughputChecked: getNewDatabaseSharedThroughputDefault(),
|
||||
selectedDatabaseId:
|
||||
userContext.apiType === "Tables" ? CollectionCreation.TablesAPIDefaultDatabase : this.props.databaseId,
|
||||
collectionId: props.isQuickstart ? `Sample${getCollectionName()}` : "",
|
||||
@@ -351,61 +346,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
this.setState({ newDatabaseId: event.target.value })
|
||||
}
|
||||
/>
|
||||
|
||||
{!isServerlessAccount() && (
|
||||
<Stack horizontal>
|
||||
<Checkbox
|
||||
label={t(Keys.panes.addCollection.shareThroughput, {
|
||||
collectionName: getCollectionName(true).toLocaleLowerCase(),
|
||||
})}
|
||||
checked={this.state.isSharedThroughputChecked}
|
||||
styles={{
|
||||
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center" },
|
||||
root: {
|
||||
selectors: {
|
||||
":hover .ms-Checkbox-text": { color: "var(--colorNeutralForeground1)" },
|
||||
},
|
||||
},
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) =>
|
||||
this.setState({ isSharedThroughputChecked: isChecked })
|
||||
}
|
||||
/>
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content={t(Keys.panes.addCollection.shareThroughputTooltip, {
|
||||
collectionName: getCollectionName(true).toLocaleLowerCase(),
|
||||
})}
|
||||
>
|
||||
<Icon
|
||||
iconName="Info"
|
||||
className="panelInfoIcon"
|
||||
tabIndex={0}
|
||||
ariaLabel={t(Keys.panes.addCollection.shareThroughputTooltip, {
|
||||
collectionName: getCollectionName(true).toLocaleLowerCase(),
|
||||
})}
|
||||
/>
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{!isServerlessAccount() && this.state.isSharedThroughputChecked && (
|
||||
<ThroughputInput
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount() && !isFirstResourceCreated}
|
||||
isDatabase={true}
|
||||
isSharded={this.state.isSharded}
|
||||
isFreeTier={isFreeTierAccount()}
|
||||
isQuickstart={this.props.isQuickstart}
|
||||
setThroughputValue={(throughput: number) => (this.newDatabaseThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (this.isNewDatabaseAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isThroughputCapExceeded: boolean) =>
|
||||
this.setState({ isThroughputCapExceeded })
|
||||
}
|
||||
onCostAcknowledgeChange={(isAcknowledge: boolean) => (this.isCostAcknowledged = isAcknowledge)}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{!this.state.createNewDatabase && (
|
||||
@@ -515,9 +455,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{userContext.apiType === "Mongo" &&
|
||||
(!this.state.isSharedThroughputChecked ||
|
||||
this.props.explorer.isFixedCollectionWithSharedThroughputSupported()) && (
|
||||
{userContext.apiType === "Mongo" && this.props.explorer.isFixedCollectionWithSharedThroughputSupported() && (
|
||||
<Stack>
|
||||
<Stack horizontal style={{ marginTop: -5, marginBottom: -4 }}>
|
||||
<span className="mandatoryStar">* </span>
|
||||
@@ -1191,7 +1129,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
if (this.state.createNewDatabase) {
|
||||
return !this.state.isSharedThroughputChecked;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.state.enableDedicatedThroughput) {
|
||||
@@ -1206,9 +1144,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.state.createNewDatabase
|
||||
? this.state.isSharedThroughputChecked
|
||||
: this.isSelectedDatabaseSharedThroughput();
|
||||
return this.state.createNewDatabase ? false : this.isSelectedDatabaseSharedThroughput();
|
||||
}
|
||||
|
||||
private shouldShowVectorSearchParameters() {
|
||||
@@ -1253,9 +1189,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
return false;
|
||||
}
|
||||
|
||||
const throughput = this.state.createNewDatabase ? this.newDatabaseThroughput : this.collectionThroughput;
|
||||
const throughput = this.collectionThroughput;
|
||||
if (throughput > CollectionCreation.DefaultCollectionRUs100K && !this.isCostAcknowledged) {
|
||||
const errorMessage = this.isNewDatabaseAutoscale
|
||||
const errorMessage = this.isCollectionAutoscale
|
||||
? t(Keys.panes.addCollection.acknowledgeSpendErrorMonthly)
|
||||
: t(Keys.panes.addCollection.acknowledgeSpendErrorDaily);
|
||||
this.setState({ errorMessage });
|
||||
@@ -1379,9 +1315,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
database: {
|
||||
id: databaseId,
|
||||
new: this.state.createNewDatabase,
|
||||
shared: this.state.createNewDatabase
|
||||
? this.state.isSharedThroughputChecked
|
||||
: this.isSelectedDatabaseSharedThroughput(),
|
||||
shared: this.state.createNewDatabase ? false : this.isSelectedDatabaseSharedThroughput(),
|
||||
},
|
||||
collection: {
|
||||
id: this.state.collectionId,
|
||||
@@ -1399,7 +1333,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateCollection, telemetryData);
|
||||
|
||||
const databaseLevelThroughput: boolean = this.state.createNewDatabase
|
||||
? this.state.isSharedThroughputChecked
|
||||
? false
|
||||
: this.isSelectedDatabaseSharedThroughput() && !this.state.enableDedicatedThroughput;
|
||||
|
||||
let offerThroughput: number;
|
||||
@@ -1410,13 +1344,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
autoPilotMaxThroughput = DEFAULT_FABRIC_NATIVE_CONTAINER_THROUGHPUT;
|
||||
offerThroughput = undefined;
|
||||
} else if (databaseLevelThroughput) {
|
||||
if (this.state.createNewDatabase) {
|
||||
if (this.isNewDatabaseAutoscale) {
|
||||
autoPilotMaxThroughput = this.newDatabaseThroughput;
|
||||
} else {
|
||||
offerThroughput = this.newDatabaseThroughput;
|
||||
}
|
||||
}
|
||||
// Existing shared database: no collection-level throughput needed
|
||||
} else {
|
||||
if (this.isCollectionAutoscale) {
|
||||
autoPilotMaxThroughput = this.collectionThroughput;
|
||||
|
||||
@@ -105,49 +105,6 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<Stack
|
||||
horizontal={true}
|
||||
>
|
||||
<StyledCheckboxBase
|
||||
checked={false}
|
||||
label="Share throughput across containers"
|
||||
onChange={[Function]}
|
||||
styles={
|
||||
{
|
||||
"checkbox": {
|
||||
"height": 12,
|
||||
"width": 12,
|
||||
},
|
||||
"label": {
|
||||
"alignItems": "center",
|
||||
"padding": 0,
|
||||
},
|
||||
"root": {
|
||||
"selectors": {
|
||||
":hover .ms-Checkbox-text": {
|
||||
"color": "var(--colorNeutralForeground1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
"text": {
|
||||
"color": "var(--colorNeutralForeground1)",
|
||||
"fontSize": 12,
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<StyledTooltipHostBase
|
||||
content="Throughput configured at the database level will be shared across all containers within the database."
|
||||
directionalHint={4}
|
||||
>
|
||||
<Icon
|
||||
ariaLabel="Throughput configured at the database level will be shared across all containers within the database."
|
||||
className="panelInfoIcon"
|
||||
iconName="Info"
|
||||
tabIndex={0}
|
||||
/>
|
||||
</StyledTooltipHostBase>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Separator
|
||||
className="panelSeparator"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Checkbox, Stack, Text, TextField } from "@fluentui/react";
|
||||
import { getNewDatabaseSharedThroughputDefault } from "Common/DatabaseUtility";
|
||||
import { Stack, Text, TextField } from "@fluentui/react";
|
||||
import { Keys, t } from "Localization";
|
||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||
@@ -9,15 +8,11 @@ import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
|
||||
import { createDatabase } from "../../../Common/dataAccess/createDatabase";
|
||||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import { SubscriptionType } from "../../../Contracts/SubscriptionType";
|
||||
import * as SharedConstants from "../../../Shared/Constants";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||
import { isServerlessAccount } from "../../../Utils/CapabilityUtils";
|
||||
import { getUpsellMessage } from "../../../Utils/PricingUtils";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useDatabases } from "../../useDatabases";
|
||||
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||
@@ -34,9 +29,6 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
buttonElement,
|
||||
}: AddDatabasePaneProps) => {
|
||||
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
|
||||
let throughput: number;
|
||||
let isAutoscaleSelected: boolean;
|
||||
let isCostAcknowledged: boolean;
|
||||
const { subscriptionType } = userContext;
|
||||
const isCassandraAccount: boolean = userContext.apiType === "Cassandra";
|
||||
const databaseLabel: string = isCassandraAccount ? "keyspace" : "database";
|
||||
@@ -49,23 +41,15 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
const [databaseId, setDatabaseId] = useState<string>("");
|
||||
const databaseIdTooltipText = t(Keys.panes.addDatabase.databaseTooltip, { databaseLabel, collectionsLabel });
|
||||
|
||||
const databaseLevelThroughputTooltipText = t(Keys.panes.addDatabase.shareThroughputTooltip, {
|
||||
databaseLabel,
|
||||
collectionsLabel,
|
||||
});
|
||||
const [databaseCreateNewShared, setDatabaseCreateNewShared] = useState<boolean>(
|
||||
getNewDatabaseSharedThroughputDefault(),
|
||||
);
|
||||
const [formErrors, setFormErrors] = useState<string>("");
|
||||
const [isExecuting, setIsExecuting] = useState<boolean>(false);
|
||||
const [isThroughputCapExceeded, setIsThroughputCapExceeded] = useState<boolean>(false);
|
||||
|
||||
const isFreeTierAccount: boolean = userContext.databaseAccount?.properties?.enableFreeTier;
|
||||
|
||||
const addDatabasePaneMessage = {
|
||||
database: {
|
||||
id: databaseId,
|
||||
shared: databaseCreateNewShared,
|
||||
shared: false,
|
||||
},
|
||||
subscriptionType: SubscriptionType[subscriptionType],
|
||||
subscriptionQuotaId: userContext.quotaId,
|
||||
@@ -76,9 +60,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
const addDatabasePaneOpenMessage = {
|
||||
subscriptionType: SubscriptionType[subscriptionType],
|
||||
subscriptionQuotaId: userContext.quotaId,
|
||||
defaultsCheck: {
|
||||
throughput,
|
||||
},
|
||||
defaultsCheck: {},
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
};
|
||||
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
|
||||
@@ -88,13 +70,8 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
}, []);
|
||||
|
||||
const onSubmit = () => {
|
||||
if (!_isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const addDatabasePaneStartMessage = {
|
||||
...addDatabasePaneMessage,
|
||||
throughput,
|
||||
};
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateDatabase, addDatabasePaneStartMessage);
|
||||
setFormErrors("");
|
||||
@@ -102,69 +79,41 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
|
||||
const createDatabaseParams: DataModels.CreateDatabaseParams = {
|
||||
databaseId: addDatabasePaneStartMessage.database.id,
|
||||
databaseLevelThroughput: addDatabasePaneStartMessage.database.shared,
|
||||
databaseLevelThroughput: false,
|
||||
};
|
||||
if (isAutoscaleSelected) {
|
||||
createDatabaseParams.autoPilotMaxThroughput = addDatabasePaneStartMessage.throughput;
|
||||
} else {
|
||||
createDatabaseParams.offerThroughput = addDatabasePaneStartMessage.throughput;
|
||||
}
|
||||
|
||||
createDatabase(createDatabaseParams).then(
|
||||
() => {
|
||||
_onCreateDatabaseSuccess(throughput, startKey);
|
||||
_onCreateDatabaseSuccess(startKey);
|
||||
},
|
||||
(error: string) => {
|
||||
_onCreateDatabaseFailure(error, throughput, startKey);
|
||||
_onCreateDatabaseFailure(error, startKey);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const _onCreateDatabaseSuccess = (offerThroughput: number, startKey: number): void => {
|
||||
const _onCreateDatabaseSuccess = (startKey: number): void => {
|
||||
setIsExecuting(false);
|
||||
closeSidePanel();
|
||||
container.refreshAllDatabases();
|
||||
const addDatabasePaneSuccessMessage = {
|
||||
...addDatabasePaneMessage,
|
||||
offerThroughput,
|
||||
};
|
||||
TelemetryProcessor.traceSuccess(Action.CreateDatabase, addDatabasePaneSuccessMessage, startKey);
|
||||
};
|
||||
|
||||
const _onCreateDatabaseFailure = (error: string, offerThroughput: number, startKey: number): void => {
|
||||
const _onCreateDatabaseFailure = (error: string, startKey: number): void => {
|
||||
setIsExecuting(false);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
setFormErrors(errorMessage);
|
||||
const addDatabasePaneFailedMessage = {
|
||||
...addDatabasePaneMessage,
|
||||
offerThroughput,
|
||||
error: errorMessage,
|
||||
errorStack: getErrorStack(error),
|
||||
};
|
||||
TelemetryProcessor.traceFailure(Action.CreateDatabase, addDatabasePaneFailedMessage, startKey);
|
||||
};
|
||||
|
||||
const _isValid = (): boolean => {
|
||||
// TODO add feature flag that disables validation for customers with custom accounts
|
||||
if (isAutoscaleSelected) {
|
||||
if (!AutoPilotUtils.isValidAutoPilotThroughput(throughput)) {
|
||||
setFormErrors(t(Keys.panes.addDatabase.greaterThanError, { minValue: AutoPilotUtils.autoPilotThroughput1K }));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && !isCostAcknowledged) {
|
||||
setFormErrors(
|
||||
isAutoscaleSelected
|
||||
? t(Keys.panes.addDatabase.acknowledgeSpendErrorMonthly)
|
||||
: t(Keys.panes.addDatabase.acknowledgeSpendErrorDaily),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleonChangeDBId = React.useCallback(
|
||||
(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {
|
||||
setDatabaseId(newValue || "");
|
||||
@@ -176,7 +125,6 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
formError: formErrors,
|
||||
isExecuting,
|
||||
submitButtonText: t(Keys.common.ok),
|
||||
isSubmitButtonDisabled: isThroughputCapExceeded,
|
||||
onSubmit,
|
||||
};
|
||||
|
||||
@@ -224,42 +172,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
data-lpignore={true}
|
||||
data-1p-ignore={true}
|
||||
/>
|
||||
|
||||
{!isServerlessAccount() && (
|
||||
<Stack horizontal>
|
||||
<Checkbox
|
||||
title={t(Keys.panes.addDatabase.provisionSharedThroughputTitle)}
|
||||
styles={{
|
||||
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center" },
|
||||
root: {
|
||||
selectors: {
|
||||
":hover .ms-Checkbox-text": { color: "var(--colorNeutralForeground1)" },
|
||||
},
|
||||
},
|
||||
}}
|
||||
label={t(Keys.panes.addDatabase.provisionThroughputLabel)}
|
||||
checked={databaseCreateNewShared}
|
||||
onChange={() => setDatabaseCreateNewShared(!databaseCreateNewShared)}
|
||||
/>
|
||||
<InfoTooltip>{databaseLevelThroughputTooltipText}</InfoTooltip>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
{!isServerlessAccount() && databaseCreateNewShared && (
|
||||
<ThroughputInput
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !useDatabases.getState().isFirstResourceCreated()}
|
||||
isDatabase={true}
|
||||
isSharded={databaseCreateNewShared}
|
||||
isFreeTier={isFreeTierAccount}
|
||||
setThroughputValue={(newThroughput: number) => (throughput = newThroughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (isAutoscaleSelected = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isCapExceeded: boolean) => setIsThroughputCapExceeded(isCapExceeded)}
|
||||
onCostAcknowledgeChange={(isAcknowledged: boolean) => (isCostAcknowledged = isAcknowledged)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</RightPaneForm>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||
<RightPaneForm
|
||||
formError=""
|
||||
isExecuting={false}
|
||||
isSubmitButtonDisabled={false}
|
||||
onSubmit={[Function]}
|
||||
submitButtonText="OK"
|
||||
>
|
||||
@@ -61,42 +60,6 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<Stack
|
||||
horizontal={true}
|
||||
>
|
||||
<StyledCheckboxBase
|
||||
checked={false}
|
||||
label="Provision throughput"
|
||||
onChange={[Function]}
|
||||
styles={
|
||||
{
|
||||
"checkbox": {
|
||||
"height": 12,
|
||||
"width": 12,
|
||||
},
|
||||
"label": {
|
||||
"alignItems": "center",
|
||||
"padding": 0,
|
||||
},
|
||||
"root": {
|
||||
"selectors": {
|
||||
":hover .ms-Checkbox-text": {
|
||||
"color": "var(--colorNeutralForeground1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
"text": {
|
||||
"color": "var(--colorNeutralForeground1)",
|
||||
"fontSize": 12,
|
||||
},
|
||||
}
|
||||
}
|
||||
title="Provision shared throughput"
|
||||
/>
|
||||
<InfoTooltip>
|
||||
Provisioned throughput at the database level will be shared across all collections within the database.
|
||||
</InfoTooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
</RightPaneForm>
|
||||
|
||||
@@ -15,7 +15,7 @@ describe("Cassandra add collection pane test", () => {
|
||||
|
||||
it("should render default properly", () => {
|
||||
expect(screen.getByRole("radio", { name: "Create new keyspace", checked: true })).toBeDefined();
|
||||
expect(screen.getByRole("checkbox", { name: "Provision shared throughput", checked: false })).toBeDefined();
|
||||
expect(screen.queryByRole("checkbox", { name: "Provision shared throughput" })).toBeNull();
|
||||
});
|
||||
|
||||
it("click on use existing", () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Checkbox, Dropdown, IDropdownOption, Link, Stack, Text, TextField } from "@fluentui/react";
|
||||
import { Dropdown, IDropdownOption, Link, Stack, Text, TextField } from "@fluentui/react";
|
||||
import * as Constants from "Common/Constants";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
||||
@@ -27,8 +27,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
explorer: container,
|
||||
cassandraApiClient,
|
||||
}: CassandraAddCollectionPaneProps) => {
|
||||
let newKeySpaceThroughput: number;
|
||||
let isNewKeySpaceAutoscale: boolean;
|
||||
let tableThroughput: number;
|
||||
let isTableAutoscale: boolean;
|
||||
let isCostAcknowledged: boolean;
|
||||
@@ -52,7 +50,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
collection: {
|
||||
id: tableId,
|
||||
storage: Constants.BackendDefaults.multiPartitionStorageInGb,
|
||||
offerThroughput: newKeySpaceThroughput || tableThroughput,
|
||||
offerThroughput: tableThroughput,
|
||||
partitionKey: "",
|
||||
databaseId: keyspaceCreateNew ? newKeyspaceId : existingKeyspaceId,
|
||||
},
|
||||
@@ -60,18 +58,17 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
subscriptionQuotaId: userContext.quotaId,
|
||||
defaultsCheck: {
|
||||
storage: "u",
|
||||
throughput: newKeySpaceThroughput || tableThroughput,
|
||||
throughput: tableThroughput,
|
||||
},
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
const throughput = keyspaceCreateNew ? newKeySpaceThroughput : tableThroughput;
|
||||
const throughput = tableThroughput;
|
||||
const keyspaceId = keyspaceCreateNew ? newKeyspaceId : existingKeyspaceId;
|
||||
|
||||
if (throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && !isCostAcknowledged) {
|
||||
const errorMessage =
|
||||
isNewKeySpaceAutoscale || isTableAutoscale
|
||||
const errorMessage = isTableAutoscale
|
||||
? t(Keys.panes.addCollection.acknowledgeSpendErrorMonthly)
|
||||
: t(Keys.panes.addCollection.acknowledgeSpendErrorDaily);
|
||||
setFormError(errorMessage);
|
||||
@@ -79,14 +76,10 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
}
|
||||
|
||||
setIsExecuting(true);
|
||||
const autoPilotCommand = `cosmosdb_autoscale_max_throughput`;
|
||||
const createKeyspaceQueryPrefix = `CREATE KEYSPACE ${keyspaceId.trim()} WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 3 }`;
|
||||
const createKeyspaceQuery: string = isKeyspaceShared
|
||||
? isNewKeySpaceAutoscale
|
||||
? `${createKeyspaceQueryPrefix} AND ${autoPilotCommand}=${newKeySpaceThroughput};`
|
||||
: `${createKeyspaceQueryPrefix} AND cosmosdb_provisioned_throughput=${newKeySpaceThroughput};`
|
||||
: `${createKeyspaceQueryPrefix};`;
|
||||
const createKeyspaceQuery = `${createKeyspaceQueryPrefix};`;
|
||||
let tableQuery: string;
|
||||
const autoPilotCommand = `cosmosdb_autoscale_max_throughput`;
|
||||
const createTableQueryPrefix = `CREATE TABLE ${keyspaceId}.${tableId.trim()} ${userTableQuery}`;
|
||||
|
||||
if (tableThroughput) {
|
||||
@@ -177,7 +170,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
tabIndex={0}
|
||||
onChange={() => {
|
||||
setKeyspaceCreateNew(true);
|
||||
setIsKeyspaceShared(false);
|
||||
setExistingKeyspaceId("");
|
||||
}}
|
||||
/>
|
||||
@@ -192,7 +184,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
tabIndex={0}
|
||||
onChange={() => {
|
||||
setKeyspaceCreateNew(false);
|
||||
setIsKeyspaceShared(false);
|
||||
}}
|
||||
/>
|
||||
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.useExisting)}</span>
|
||||
@@ -214,25 +205,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
ariaLabel="Keyspace id"
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
{!isServerlessAccount() && (
|
||||
<Stack horizontal>
|
||||
<Checkbox
|
||||
label="Provision shared throughput"
|
||||
checked={isKeyspaceShared}
|
||||
styles={{
|
||||
text: { fontSize: 12 },
|
||||
checkbox: { width: 12, height: 12 },
|
||||
label: { padding: 0, alignItems: "center" },
|
||||
}}
|
||||
onChange={(ev: React.FormEvent<HTMLElement>, isChecked: boolean) => setIsKeyspaceShared(isChecked)}
|
||||
/>
|
||||
<InfoTooltip>
|
||||
Provisioned throughput at the keyspace level will be shared across unlimited number of tables within
|
||||
the keyspace
|
||||
</InfoTooltip>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
@@ -256,21 +228,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
responsiveMode={999}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isServerlessAccount() && keyspaceCreateNew && isKeyspaceShared && (
|
||||
<ThroughputInput
|
||||
showFreeTierExceedThroughputTooltip={
|
||||
isFreeTierAccount && !useDatabases.getState().isFirstResourceCreated()
|
||||
}
|
||||
isDatabase
|
||||
isSharded
|
||||
isFreeTier={isFreeTierAccount}
|
||||
setThroughputValue={(throughput: number) => (newKeySpaceThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (isNewKeySpaceAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isCapExceeded: boolean) => setIsThroughputCapExceeded(isCapExceeded)}
|
||||
onCostAcknowledgeChange={(isAcknowledged: boolean) => (isCostAcknowledged = isAcknowledged)}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
@@ -328,7 +285,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
<InfoTooltip>{t(Keys.panes.cassandraAddCollection.provisionDedicatedThroughputTooltip)}</InfoTooltip>
|
||||
</Stack>
|
||||
)}
|
||||
{!isServerlessAccount() && (!isKeyspaceShared || dedicateTableThroughput) && (
|
||||
{!isServerlessAccount() && (keyspaceCreateNew || !isKeyspaceShared || dedicateTableThroughput) && (
|
||||
<ThroughputInput
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !useDatabases.getState().isFirstResourceCreated()}
|
||||
isDatabase={false}
|
||||
|
||||
@@ -438,21 +438,15 @@
|
||||
"keyspaceIdLabel": "Keyspace id",
|
||||
"databaseIdPlaceholder": "Type a new {{databaseLabel}} id",
|
||||
"databaseTooltip": "A {{databaseLabel}} is a logical container of one or more {{collectionsLabel}}",
|
||||
"shareThroughput": "Share throughput across {{collectionsLabel}}",
|
||||
"shareThroughputTooltip": "Provisioned throughput at the {{databaseLabel}} level will be shared across all {{collectionsLabel}} within the {{databaseLabel}}.",
|
||||
"greaterThanError": "Please enter a value greater than {{minValue}} for autopilot throughput",
|
||||
"acknowledgeSpendError": "Please acknowledge the estimated {{period}} spend.",
|
||||
"acknowledgeSpendErrorMonthly": "Please acknowledge the estimated monthly spend.",
|
||||
"acknowledgeSpendErrorDaily": "Please acknowledge the estimated daily spend.",
|
||||
"provisionSharedThroughputTitle": "Provision shared throughput",
|
||||
"provisionThroughputLabel": "Provision throughput"
|
||||
"acknowledgeSpendErrorDaily": "Please acknowledge the estimated daily spend."
|
||||
},
|
||||
"addCollection": {
|
||||
"createNew": "Create new",
|
||||
"useExisting": "Use existing",
|
||||
"databaseTooltip": "A database is analogous to a namespace. It is the unit of management for a set of {{collectionName}}.",
|
||||
"shareThroughput": "Share throughput across {{collectionName}}",
|
||||
"shareThroughputTooltip": "Throughput configured at the database level will be shared across all {{collectionName}} within the database.",
|
||||
"collectionIdLabel": "{{collectionName}} id",
|
||||
"collectionIdTooltip": "Unique identifier for the {{collectionName}} and used for id-based routing through REST and all SDKs.",
|
||||
"collectionIdPlaceholder": "e.g., {{collectionName}}1",
|
||||
|
||||
Reference in New Issue
Block a user