diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
index e3c114d04..1ffd0d459 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
@@ -1,6 +1,7 @@
import {
Checkbox,
ChoiceGroup,
+ DefaultButton,
FontIcon,
IChoiceGroupOption,
IMessageBarStyles,
@@ -18,6 +19,7 @@ import {
TextField,
Toggle,
} from "@fluentui/react";
+import { useDialog } from "Explorer/Controls/Dialog";
import { Keys, t } from "Localization";
import React from "react";
import * as DataModels from "../../../../../Contracts/DataModels";
@@ -90,10 +92,15 @@ export interface ThroughputInputAutoPilotV3Props {
onHotPartitionKeyRateLimitingPolicyChange: (newPolicy: DataModels.HotPartitionKeyRateLimitingPolicy) => void;
}
+interface IsThroughputComponentDirtyResult extends IsComponentDirtyResult {
+ priceHasChanged: boolean;
+}
+
interface ThroughputInputAutoPilotV3State {
spendAckChecked: boolean;
exceedFreeTierThroughput: boolean;
}
+
export class ThroughputInputAutoPilotV3Component extends React.Component<
ThroughputInputAutoPilotV3Props,
ThroughputInputAutoPilotV3State
@@ -135,14 +142,16 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
this.shouldCheckComponentIsDirty = false;
};
- public IsComponentDirty = (): IsComponentDirtyResult => {
+ public IsComponentDirty = (): IsThroughputComponentDirtyResult => {
let isSaveable = false;
let isDiscardable = false;
+ let priceHasChanged = false;
if (this.props.isEnabled) {
if (this.hasProvisioningTypeChanged()) {
isSaveable = true;
isDiscardable = true;
+ priceHasChanged = true;
} else if (
isHotPartitionKeyThrottlingEnabled() &&
isDirty(this.props.hotPartitionKeyRateLimitingPolicy, this.props.hotPartitionKeyRateLimitingPolicyBaseline)
@@ -152,6 +161,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
} else if (this.props.isAutoPilotSelected) {
if (isDirty(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline)) {
isDiscardable = true;
+ priceHasChanged = true;
if (
this.props.softAllowedMaximumThroughput
? this.props.maxAutoPilotThroughput <= this.props.softAllowedMaximumThroughput &&
@@ -165,6 +175,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
if (isDirty(this.props.throughput, this.props.throughputBaseline)) {
isDiscardable = true;
isSaveable = true;
+ priceHasChanged = true;
if (
!this.props.throughput ||
this.props.throughput < this.props.minimum ||
@@ -177,7 +188,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
}
}
}
- return { isSaveable, isDiscardable };
+ return { isSaveable, isDiscardable, priceHasChanged };
};
public constructor(props: ThroughputInputAutoPilotV3Props) {
@@ -210,7 +221,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
return <>>;
}
- const isDirty: boolean = this.IsComponentDirty().isDiscardable;
+ const isDirty: boolean = this.IsComponentDirty().priceHasChanged;
const regions = account?.properties?.readLocations?.length || 1;
const multimaster = account?.properties?.enableMultipleWriteLocations || false;
@@ -858,7 +869,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
private renderWarningMessage = (): JSX.Element => {
let warningMessage: JSX.Element;
- if (this.IsComponentDirty().isDiscardable) {
+ if (this.IsComponentDirty().priceHasChanged) {
warningMessage = saveThroughputWarningMessage;
}
@@ -889,34 +900,60 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
onText={t(Keys.common.on)}
offText={t(Keys.common.off)}
checked={!!this.props.hotPartitionKeyRateLimitingPolicy}
+ disabled={!!this.props.hotPartitionKeyRateLimitingPolicy}
onChange={(_ev, checked) => {
if (checked) {
- this.props.onHotPartitionKeyRateLimitingPolicyChange({
- maximumPerPartitionKeyThroughputUtilizationPercent:
- this.props.hotPartitionKeyRateLimitingPolicyBaseline
- ?.maximumPerPartitionKeyThroughputUtilizationPercent ?? 75,
- });
- } else {
- this.props.onHotPartitionKeyRateLimitingPolicyChange(null);
+ useDialog.getState().showOkCancelModalDialog(
+ t(Keys.controls.settings.scale.rateLimitConfirmOverride),
+ "",
+ t(Keys.common.yes),
+ () =>
+ this.props.onHotPartitionKeyRateLimitingPolicyChange({
+ maximumPerPartitionKeyThroughputUtilizationPercent:
+ this.props.hotPartitionKeyRateLimitingPolicyBaseline
+ ?.maximumPerPartitionKeyThroughputUtilizationPercent ?? 75, //CTODO: move default to common const when we get final default value from backend team
+ }),
+ t(Keys.common.no),
+ undefined,
+ <>
+ {t(Keys.controls.settings.scale.rateLimitOverrideWarning1)}
+
+
+ {t(Keys.controls.settings.scale.rateLimitOverrideWarning2)}
+ >,
+ );
}
}}
/>
- `${value} percent`}
- valueFormat={(value: number) => `${value}%`}
- showValue
- value={this.props.hotPartitionKeyRateLimitingPolicy?.maximumPerPartitionKeyThroughputUtilizationPercent ?? 75}
- onChange={(value: number) =>
- this.props.onHotPartitionKeyRateLimitingPolicyChange({
- maximumPerPartitionKeyThroughputUtilizationPercent: value,
- })
- }
- />
+
+ `${value} percent`}
+ valueFormat={(value: number) => `${value}%`}
+ showValue
+ value={
+ this.props.hotPartitionKeyRateLimitingPolicy?.maximumPerPartitionKeyThroughputUtilizationPercent ?? 75
+ }
+ onChange={(value: number) =>
+ this.props.onHotPartitionKeyRateLimitingPolicyChange({
+ maximumPerPartitionKeyThroughputUtilizationPercent: value,
+ })
+ }
+ styles={{ root: { width: "75%" } }}
+ />
+
+ this.props.onHotPartitionKeyRateLimitingPolicyChange({
+ maximumPerPartitionKeyThroughputUtilizationPercent: 75,
+ })
+ }
+ />
+
);
};
diff --git a/src/Localization/en/Resources.json b/src/Localization/en/Resources.json
index 60b50f63d..a4660775f 100644
--- a/src/Localization/en/Resources.json
+++ b/src/Localization/en/Resources.json
@@ -895,8 +895,11 @@
"keyspaceSharedThroughput": "This table shared throughput is configured at the keyspace",
"throughputRangeLabel": "Throughput ({{min}} - {{max}} RU/s)",
"unlimited": "unlimited",
- "rateLimitingPolicyTitle": "Rate limiting policy",
- "rateLimitPolicyMaxThroughputUtilizationLabel": "Max per partition key Throughput utilization"
+ "rateLimitingPolicyTitle": "Override default rate limiting policy",
+ "rateLimitPolicyMaxThroughputUtilizationLabel": "Max partition key throughput utilization",
+ "rateLimitOverrideWarning1": "Overriding the default rate limiting is irreversible. Though you will be able to manually reset the value to its default, the policy will remain overriden at the value you set.",
+ "rateLimitOverrideWarning2": "Are you sure you wish to continue?",
+ "rateLimitConfirmOverride": "Confirm override"
},
"partitionKeyEditor": {
"changePartitionKey": "Change {{partitionKeyName}}",
diff --git a/src/Utils/arm/generatedClients/cosmos/sqlResources.ts b/src/Utils/arm/generatedClients/cosmos/sqlResources.ts
index 33b7dc620..4c1b97392 100644
--- a/src/Utils/arm/generatedClients/cosmos/sqlResources.ts
+++ b/src/Utils/arm/generatedClients/cosmos/sqlResources.ts
@@ -9,7 +9,7 @@
import { configContext } from "../../../../ConfigContext";
import { armRequest } from "../../request";
import * as Types from "./types";
-const apiVersion = "2025-11-01-preview";
+const apiVersion = "2026-04-01-preview";
/* Lists the SQL databases under an existing Azure Cosmos DB database account. */
export async function listSqlDatabases(