diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts
index a3d410cc9..2ac739e8a 100644
--- a/src/Common/Constants.ts
+++ b/src/Common/Constants.ts
@@ -117,7 +117,6 @@ export class Features {
public static readonly enableGalleryPublish = "enablegallerypublish";
public static readonly enableCodeOfConduct = "enablecodeofconduct";
public static readonly enableLinkInjection = "enablelinkinjection";
- public static readonly enableSettingsV2 = "enablesettingsv2";
public static readonly enableSpark = "enablespark";
public static readonly livyEndpoint = "livyendpoint";
public static readonly notebookServerUrl = "notebookserverurl";
@@ -131,6 +130,11 @@ export class Features {
public static readonly enableSDKoperations = "enablesdkoperations";
}
+// flight names returned from the portal are always lowercase
+export class Flights {
+ public static readonly SettingsV2 = "settingsv2";
+}
+
export class AfecFeatures {
public static readonly Spark = "spark-public-preview";
public static readonly Notebooks = "sparknotebooks-public-preview";
diff --git a/src/Contracts/ViewModels.ts b/src/Contracts/ViewModels.ts
index 7a1630609..ab3b95628 100644
--- a/src/Contracts/ViewModels.ts
+++ b/src/Contracts/ViewModels.ts
@@ -388,6 +388,7 @@ export interface DataExplorerInputsFrame {
dataExplorerVersion?: string;
isAuthWithresourceToken?: boolean;
defaultCollectionThroughput?: CollectionCreationDefaults;
+ flights?: readonly string[];
}
export interface CollectionCreationDefaults {
diff --git a/src/Explorer/Controls/FeaturePanel/FeaturePanelComponent.tsx b/src/Explorer/Controls/FeaturePanel/FeaturePanelComponent.tsx
index 5234e281d..b0f1733f7 100644
--- a/src/Explorer/Controls/FeaturePanel/FeaturePanelComponent.tsx
+++ b/src/Explorer/Controls/FeaturePanel/FeaturePanelComponent.tsx
@@ -55,7 +55,6 @@ export const FeaturePanelComponent: React.FunctionComponent = () => {
label: "Enable Injecting Notebook Viewer Link into the first cell",
value: "true"
},
- { key: "feature.enablesettingsv2", label: "Enable SettingsV2 Tab", value: "true" },
{ key: "feature.canexceedmaximumvalue", label: "Can exceed max value", value: "true" },
{
key: "feature.enablefixedcollectionwithsharedthroughput",
diff --git a/src/Explorer/Controls/FeaturePanel/__snapshots__/FeaturePanelComponent.test.tsx.snap b/src/Explorer/Controls/FeaturePanel/__snapshots__/FeaturePanelComponent.test.tsx.snap
index f0628b6f0..7f4a39014 100644
--- a/src/Explorer/Controls/FeaturePanel/__snapshots__/FeaturePanelComponent.test.tsx.snap
+++ b/src/Explorer/Controls/FeaturePanel/__snapshots__/FeaturePanelComponent.test.tsx.snap
@@ -178,12 +178,6 @@ exports[`Feature panel renders all flags 1`] = `
className="checkboxRow"
horizontalAlign="space-between"
>
-
({
@@ -220,13 +220,6 @@ describe("SettingsComponent", () => {
expect(isDirty(state.throughput, state.throughputBaseline)).toEqual(false);
});
- it("getTtlValue", async () => {
- const settingsComponentInstance = new SettingsComponent(baseProps);
- expect(settingsComponentInstance.getTtlValue(TtlType.OnNoDefault)).toEqual(TtlOnNoDefault);
- expect(settingsComponentInstance.getTtlValue(TtlType.On)).toEqual(TtlOn);
- expect(settingsComponentInstance.getTtlValue(TtlType.Off)).toEqual(TtlOff);
- });
-
it("getAnalyticalStorageTtl", () => {
const newCollection = { ...collection };
newCollection.analyticalStorageTtl = ko.observable(10);
diff --git a/src/Explorer/Controls/Settings/SettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsComponent.tsx
index de78632ee..7d2e4a336 100644
--- a/src/Explorer/Controls/Settings/SettingsComponent.tsx
+++ b/src/Explorer/Controls/Settings/SettingsComponent.tsx
@@ -27,9 +27,6 @@ import {
SettingsV2TabTypes,
getTabTitle,
isDirty,
- TtlOff,
- TtlOn,
- TtlOnNoDefault,
parseConflictResolutionMode,
parseConflictResolutionProcedure
} from "./SettingsUtils";
@@ -38,7 +35,7 @@ import {
ConflictResolutionComponentProps
} from "./SettingsSubComponents/ConflictResolutionComponent";
import { SubSettingsComponent, SubSettingsComponentProps } from "./SettingsSubComponents/SubSettingsComponent";
-import { Pivot, PivotItem, IPivotProps, IPivotItemProps, IChoiceGroupOption } from "office-ui-fabric-react";
+import { Pivot, PivotItem, IPivotProps, IPivotItemProps } from "office-ui-fabric-react";
import "./SettingsComponent.less";
import { IndexingPolicyComponent, IndexingPolicyComponentProps } from "./SettingsSubComponents/IndexingPolicyComponent";
@@ -85,7 +82,6 @@ export interface SettingsComponentState {
indexingPolicyContent: DataModels.IndexingPolicy;
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
shouldDiscardIndexingPolicy: boolean;
- indexingPolicyElementFocussed: boolean;
isIndexingPolicyDirty: boolean;
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode;
@@ -102,7 +98,6 @@ export interface SettingsComponentState {
export class SettingsComponent extends React.Component {
private static readonly sixMonthsInSeconds = 15768000;
- private static readonly zeroSeconds = 0;
public saveSettingsButton: ButtonV2;
public discardSettingsChangesButton: ButtonV2;
@@ -160,7 +155,6 @@ export class SettingsComponent extends React.Component
this.setState({ isScaleDiscardable: isScaleDiscardable });
- private onIndexingPolicyElementFocusChange = (indexingPolicyElementFocussed: boolean): void =>
- this.setState({ indexingPolicyElementFocussed: indexingPolicyElementFocussed });
-
private onIndexingPolicyContentChange = (newIndexingPolicy: DataModels.IndexingPolicy): void =>
this.setState({ indexingPolicyContent: newIndexingPolicy });
@@ -544,79 +535,34 @@ export class SettingsComponent extends React.Component,
- option?: IChoiceGroupOption
- ): void =>
- this.setState({
- conflictResolutionPolicyMode:
- DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode]
- });
+ private onConflictResolutionPolicyModeChange = (newMode: DataModels.ConflictResolutionMode): void =>
+ this.setState({ conflictResolutionPolicyMode: newMode });
- private onConflictResolutionPolicyPathChange = (
- event: React.FormEvent,
- newValue?: string
- ): void => this.setState({ conflictResolutionPolicyPath: newValue });
+ private onConflictResolutionPolicyPathChange = (newPath: string): void =>
+ this.setState({ conflictResolutionPolicyPath: newPath });
- private onConflictResolutionPolicyProcedureChange = (
- event: React.FormEvent,
- newValue?: string
- ): void => this.setState({ conflictResolutionPolicyProcedure: newValue });
+ private onConflictResolutionPolicyProcedureChange = (newProcedure: string): void =>
+ this.setState({ conflictResolutionPolicyProcedure: newProcedure });
private onConflictResolutionDirtyChange = (isConflictResolutionDirty: boolean): void =>
this.setState({ isConflictResolutionDirty: isConflictResolutionDirty });
- public getTtlValue = (value: string): TtlType => {
- switch (value) {
- case TtlOn:
- return TtlType.On;
- case TtlOff:
- return TtlType.Off;
- case TtlOnNoDefault:
- return TtlType.OnNoDefault;
- }
- return undefined;
- };
+ private onTtlChange = (newTtl: TtlType): void => this.setState({ timeToLive: newTtl });
- private onTtlChange = (ev?: React.FormEvent, option?: IChoiceGroupOption): void =>
- this.setState({ timeToLive: this.getTtlValue(option.key) });
-
- private onTimeToLiveSecondsChange = (
- event: React.FormEvent,
- newValue?: string
- ): void => {
- let newTimeToLiveSeconds = parseInt(newValue);
- newTimeToLiveSeconds = isNaN(newTimeToLiveSeconds) ? SettingsComponent.zeroSeconds : newTimeToLiveSeconds;
+ private onTimeToLiveSecondsChange = (newTimeToLiveSeconds: number): void =>
this.setState({ timeToLiveSeconds: newTimeToLiveSeconds });
- };
- private onGeoSpatialConfigTypeChange = (
- ev?: React.FormEvent,
- option?: IChoiceGroupOption
- ): void =>
- this.setState({ geospatialConfigType: GeospatialConfigType[option.key as keyof typeof GeospatialConfigType] });
+ private onGeoSpatialConfigTypeChange = (newGeoSpatialConfigType: GeospatialConfigType): void =>
+ this.setState({ geospatialConfigType: newGeoSpatialConfigType });
- private onAnalyticalStorageTtlSelectionChange = (
- ev?: React.FormEvent,
- option?: IChoiceGroupOption
- ): void => this.setState({ analyticalStorageTtlSelection: this.getTtlValue(option.key) });
+ private onAnalyticalStorageTtlSelectionChange = (newAnalyticalStorageTtlSelection: TtlType): void =>
+ this.setState({ analyticalStorageTtlSelection: newAnalyticalStorageTtlSelection });
- private onAnalyticalStorageTtlSecondsChange = (
- event: React.FormEvent,
- newValue?: string
- ): void => {
- let newAnalyticalStorageTtlSeconds = parseInt(newValue);
- newAnalyticalStorageTtlSeconds = isNaN(newAnalyticalStorageTtlSeconds)
- ? SettingsComponent.zeroSeconds
- : newAnalyticalStorageTtlSeconds;
+ private onAnalyticalStorageTtlSecondsChange = (newAnalyticalStorageTtlSeconds: number): void =>
this.setState({ analyticalStorageTtlSeconds: newAnalyticalStorageTtlSeconds });
- };
- private onChangeFeedPolicyChange = (
- ev?: React.FormEvent,
- option?: IChoiceGroupOption
- ): void =>
- this.setState({ changeFeedPolicy: ChangeFeedPolicyState[option.key as keyof typeof ChangeFeedPolicyState] });
+ private onChangeFeedPolicyChange = (newChangeFeedPolicy: ChangeFeedPolicyState): void =>
+ this.setState({ changeFeedPolicy: newChangeFeedPolicy });
private onSubSettingsSaveableChange = (isSubSettingsSaveable: boolean): void =>
this.setState({ isSubSettingsSaveable: isSubSettingsSaveable });
@@ -844,7 +790,6 @@ export class SettingsComponent extends React.Component,
- option?: IChoiceGroupOption
- ) => void;
+ onConflictResolutionPolicyModeChange: (newMode: DataModels.ConflictResolutionMode) => void;
conflictResolutionPolicyPath: string;
conflictResolutionPolicyPathBaseline: string;
- onConflictResolutionPolicyPathChange: (
- event: React.FormEvent,
- newValue?: string
- ) => void;
+ onConflictResolutionPolicyPathChange: (newPath: string) => void;
conflictResolutionPolicyProcedure: string;
conflictResolutionPolicyProcedureBaseline: string;
- onConflictResolutionPolicyProcedureChange: (
- event: React.FormEvent,
- newValue?: string
- ) => void;
+ onConflictResolutionPolicyProcedureChange: (newProcedure: string) => void;
onConflictResolutionDirtyChange: (isConflictResolutionDirty: boolean) => void;
}
@@ -77,12 +68,30 @@ export class ConflictResolutionComponent extends React.Component,
+ option?: IChoiceGroupOption
+ ): void =>
+ this.props.onConflictResolutionPolicyModeChange(
+ DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode]
+ );
+
+ private onConflictResolutionPolicyPathChange = (
+ event: React.FormEvent,
+ newValue?: string
+ ): void => this.props.onConflictResolutionPolicyPathChange(newValue);
+
+ private onConflictResolutionPolicyProcedureChange = (
+ event: React.FormEvent,
+ newValue?: string
+ ): void => this.props.onConflictResolutionPolicyProcedureChange(newValue);
+
private getConflictResolutionModeComponent = (): JSX.Element => (
);
@@ -122,7 +131,7 @@ export class ConflictResolutionComponent extends React.Component
);
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.test.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.test.tsx
index 0aff95860..38d192f6c 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.test.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.test.tsx
@@ -17,9 +17,6 @@ describe("IndexingPolicyComponent", () => {
},
indexingPolicyContent: initialIndexingPolicyContent,
indexingPolicyContentBaseline: initialIndexingPolicyContent,
- onIndexingPolicyElementFocusChange: () => {
- return;
- },
onIndexingPolicyContentChange: () => {
return;
},
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx
index 335f552eb..f1dede13a 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx
@@ -10,7 +10,6 @@ export interface IndexingPolicyComponentProps {
resetShouldDiscardIndexingPolicy: () => void;
indexingPolicyContent: DataModels.IndexingPolicy;
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
- onIndexingPolicyElementFocusChange: (indexingPolicyContentFocussed: boolean) => void;
onIndexingPolicyContentChange: (newIndexingPolicy: DataModels.IndexingPolicy) => void;
logIndexingPolicySuccessMessage: () => void;
onIndexingPolicyDirtyChange: (isIndexingPolicyDirty: boolean) => void;
@@ -89,8 +88,6 @@ export class IndexingPolicyComponent extends React.Component<
ariaLabel: "Indexing Policy"
});
if (this.indexingPolicyEditor) {
- this.indexingPolicyEditor.onDidFocusEditorText(() => this.props.onIndexingPolicyElementFocusChange(true));
- this.indexingPolicyEditor.onDidBlurEditorText(() => this.props.onIndexingPolicyElementFocusChange(false));
const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel();
indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this));
this.props.logIndexingPolicySuccessMessage();
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx
index 2f9c16297..4793edbdb 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx
@@ -2,7 +2,7 @@ import { shallow } from "enzyme";
import React from "react";
import { SubSettingsComponent, SubSettingsComponentProps } from "./SubSettingsComponent";
import { container, collection } from "../TestUtils";
-import { TtlType, GeospatialConfigType, ChangeFeedPolicyState } from "../SettingsUtils";
+import { TtlType, GeospatialConfigType, ChangeFeedPolicyState, TtlOnNoDefault, TtlOn, TtlOff } from "../SettingsUtils";
import ko from "knockout";
import Explorer from "../../../Explorer";
@@ -133,4 +133,11 @@ describe("SubSettingsComponent", () => {
expect(isComponentDirtyResult.isSaveable).toEqual(true);
expect(isComponentDirtyResult.isDiscardable).toEqual(true);
});
+
+ it("getTtlValue", async () => {
+ const subSettingsComponentInstance = new SubSettingsComponent(baseProps);
+ expect(subSettingsComponentInstance.getTtlValue(TtlType.OnNoDefault)).toEqual(TtlOnNoDefault);
+ expect(subSettingsComponentInstance.getTtlValue(TtlType.On)).toEqual(TtlOn);
+ expect(subSettingsComponentInstance.getTtlValue(TtlType.Off)).toEqual(TtlOff);
+ });
});
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx
index 5e9eaefb3..4322bd6e8 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx
@@ -5,7 +5,11 @@ import {
TtlType,
ChangeFeedPolicyState,
isDirty,
- IsComponentDirtyResult
+ IsComponentDirtyResult,
+ TtlOn,
+ TtlOff,
+ TtlOnNoDefault,
+ getSanitizedInputValue
} from "../SettingsUtils";
import Explorer from "../../../Explorer";
import { Int32 } from "../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
@@ -37,40 +41,28 @@ export interface SubSettingsComponentProps {
timeToLive: TtlType;
timeToLiveBaseline: TtlType;
- onTtlChange: (ev?: React.FormEvent, option?: IChoiceGroupOption) => void;
+ onTtlChange: (newTtl: TtlType) => void;
timeToLiveSeconds: number;
timeToLiveSecondsBaseline: number;
- onTimeToLiveSecondsChange: (
- event: React.FormEvent,
- newValue?: string
- ) => void;
+ onTimeToLiveSecondsChange: (newTimeToLiveSeconds: number) => void;
geospatialConfigType: GeospatialConfigType;
geospatialConfigTypeBaseline: GeospatialConfigType;
- onGeoSpatialConfigTypeChange: (
- ev?: React.FormEvent,
- option?: IChoiceGroupOption
- ) => void;
+ onGeoSpatialConfigTypeChange: (newGeoSpatialConfigType: GeospatialConfigType) => void;
isAnalyticalStorageEnabled: boolean;
analyticalStorageTtlSelection: TtlType;
analyticalStorageTtlSelectionBaseline: TtlType;
- onAnalyticalStorageTtlSelectionChange: (
- ev?: React.FormEvent,
- option?: IChoiceGroupOption
- ) => void;
+ onAnalyticalStorageTtlSelectionChange: (newAnalyticalStorageTtlSelection: TtlType) => void;
analyticalStorageTtlSeconds: number;
analyticalStorageTtlSecondsBaseline: number;
- onAnalyticalStorageTtlSecondsChange: (
- event: React.FormEvent,
- newValue?: string
- ) => void;
+ onAnalyticalStorageTtlSecondsChange: (newAnalyticalStorageTtlSeconds: number) => void;
changeFeedPolicyVisible: boolean;
changeFeedPolicy: ChangeFeedPolicyState;
changeFeedPolicyBaseline: ChangeFeedPolicyState;
- onChangeFeedPolicyChange: (ev?: React.FormEvent, option?: IChoiceGroupOption) => void;
+ onChangeFeedPolicyChange: (newChangeFeedPolicyState: ChangeFeedPolicyState) => void;
onSubSettingsSaveableChange: (isSubSettingsSaveable: boolean) => void;
onSubSettingsDiscardableChange: (isSubSettingsDiscardable: boolean) => void;
}
@@ -139,6 +131,54 @@ export class SubSettingsComponent extends React.Component {
+ switch (value) {
+ case TtlOn:
+ return TtlType.On;
+ case TtlOff:
+ return TtlType.Off;
+ case TtlOnNoDefault:
+ return TtlType.OnNoDefault;
+ }
+ return undefined;
+ };
+
+ private onTtlChange = (ev?: React.FormEvent, option?: IChoiceGroupOption): void =>
+ this.props.onTtlChange(this.getTtlValue(option.key));
+
+ private onTimeToLiveSecondsChange = (
+ event: React.FormEvent,
+ newValue?: string
+ ): void => {
+ const newTimeToLiveSeconds = getSanitizedInputValue(newValue, Int32.Max);
+ this.props.onTimeToLiveSecondsChange(newTimeToLiveSeconds);
+ };
+
+ private onGeoSpatialConfigTypeChange = (
+ ev?: React.FormEvent,
+ option?: IChoiceGroupOption
+ ): void =>
+ this.props.onGeoSpatialConfigTypeChange(GeospatialConfigType[option.key as keyof typeof GeospatialConfigType]);
+
+ private onAnalyticalStorageTtlSelectionChange = (
+ ev?: React.FormEvent,
+ option?: IChoiceGroupOption
+ ): void => this.props.onAnalyticalStorageTtlSelectionChange(this.getTtlValue(option.key));
+
+ private onAnalyticalStorageTtlSecondsChange = (
+ event: React.FormEvent,
+ newValue?: string
+ ): void => {
+ const newAnalyticalStorageTtlSeconds = getSanitizedInputValue(newValue, Int32.Max);
+ this.props.onAnalyticalStorageTtlSecondsChange(newAnalyticalStorageTtlSeconds);
+ };
+
+ private onChangeFeedPolicyChange = (
+ ev?: React.FormEvent,
+ option?: IChoiceGroupOption
+ ): void =>
+ this.props.onChangeFeedPolicyChange(ChangeFeedPolicyState[option.key as keyof typeof ChangeFeedPolicyState]);
+
private getTtlComponent = (): JSX.Element => (
{isDirty(this.props.timeToLive, this.props.timeToLiveBaseline) && this.props.timeToLive === TtlType.On && (
@@ -163,7 +203,7 @@ export class SubSettingsComponent extends React.Component
)}
@@ -183,7 +223,7 @@ export class SubSettingsComponent extends React.Component
)}
@@ -219,7 +259,7 @@ export class SubSettingsComponent extends React.Component
);
@@ -241,7 +281,7 @@ export class SubSettingsComponent extends React.Component
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
index 372865593..279c8da5e 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputInputAutoPilotV3Component.tsx
@@ -26,9 +26,10 @@ import {
MessageBarType
} from "office-ui-fabric-react";
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
-import { IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
+import { getSanitizedInputValue, IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
import * as SharedConstants from "../../../../../Shared/Constants";
import * as DataModels from "../../../../../Contracts/DataModels";
+import { Int32 } from "../../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
export interface ThroughputInputAutoPilotV3Props {
databaseAccount: DataModels.DatabaseAccount;
@@ -71,9 +72,9 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
> {
private shouldCheckComponentIsDirty = true;
private static readonly defaultStep = 100;
- private static readonly zeroThroughput = 0;
private step: number;
- private choiceGroupFixedStyle = getChoiceGroupStyles(undefined, undefined);
+ private throughputInputMaxValue: number;
+ private autoPilotInputMaxValue: number;
private options: IChoiceGroupOption[] = [
{ key: "true", text: "Autoscale" },
{ key: "false", text: "Manual" }
@@ -140,6 +141,8 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
};
this.step = this.props.step ?? ThroughputInputAutoPilotV3Component.defaultStep;
+ this.throughputInputMaxValue = this.props.canExceedMaximumValue ? Int32.Max : this.props.maximum;
+ this.autoPilotInputMaxValue = Int32.Max;
}
public hasProvisioningTypeChanged = (): boolean =>
@@ -200,8 +203,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
event: React.FormEvent,
newValue?: string
): void => {
- let newThroughput = parseInt(newValue);
- newThroughput = isNaN(newThroughput) ? ThroughputInputAutoPilotV3Component.zeroThroughput : newThroughput;
+ const newThroughput = getSanitizedInputValue(newValue, this.autoPilotInputMaxValue);
this.props.onMaxAutoPilotThroughputChange(newThroughput);
};
@@ -209,9 +211,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
event: React.FormEvent,
newValue?: string
): void => {
- let newThroughput = parseInt(newValue);
- newThroughput = isNaN(newThroughput) ? ThroughputInputAutoPilotV3Component.zeroThroughput : newThroughput;
-
+ const newThroughput = getSanitizedInputValue(newValue, this.throughputInputMaxValue);
if (this.overrideWithAutoPilotSettings()) {
this.props.onMaxAutoPilotThroughputChange(newThroughput);
} else {
@@ -245,7 +245,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
onChange={this.onChoiceGroupChange}
required={this.props.showAsMandatory}
ariaLabelledBy={labelId}
- styles={this.choiceGroupFixedStyle}
+ styles={getChoiceGroupStyles(this.props.wasAutopilotOriginallySet, this.props.isAutoPilotSelected)}
/>
);
@@ -270,8 +270,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
key="auto pilot throughput input"
styles={getTextFieldStyles(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline)}
disabled={this.overrideWithProvisionedThroughputSettings()}
- step={this.step}
- min={AutoPilotUtils.minAutoPilotThroughput}
+ step={AutoPilotUtils.autoPilotIncrementStep}
value={this.overrideWithProvisionedThroughputSettings() ? "" : this.props.maxAutoPilotThroughput?.toString()}
onChange={this.onAutoPilotThroughputChange}
/>
@@ -298,8 +297,6 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
styles={getTextFieldStyles(this.props.throughput, this.props.throughputBaseline)}
disabled={this.overrideWithAutoPilotSettings()}
step={this.step}
- min={this.props.minimum}
- max={this.props.canExceedMaximumValue ? undefined : this.props.maximum}
value={
this.overrideWithAutoPilotSettings()
? this.props.maxAutoPilotThroughputBaseline?.toString()
diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/__snapshots__/ThroughputInputAutoPilotV3Component.test.tsx.snap b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/__snapshots__/ThroughputInputAutoPilotV3Component.test.tsx.snap
index e035baa96..9fe18a4cc 100644
--- a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/__snapshots__/ThroughputInputAutoPilotV3Component.test.tsx.snap
+++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/__snapshots__/ThroughputInputAutoPilotV3Component.test.tsx.snap
@@ -81,10 +81,10 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
Object {
"selectors": Object {
".ms-ChoiceField-field.is-checked::after": Object {
- "borderColor": "",
+ "borderColor": undefined,
},
".ms-ChoiceField-field.is-checked::before": Object {
- "borderColor": "",
+ "borderColor": undefined,
},
".ms-ChoiceField-wrapper label": Object {
"fontFamily": undefined,
@@ -113,10 +113,9 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
id="autopilotInput"
key="auto pilot throughput input"
label="Max RU/s"
- min={4000}
onChange={[Function]}
required={true}
- step={100}
+ step={1000}
styles={
Object {
"fieldGroup": Object {
@@ -219,7 +218,6 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
disabled={false}
id="throughputInput"
key="provisioned throughput input"
- min={10000}
onChange={[Function]}
required={true}
step={100}
@@ -375,7 +373,6 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
disabled={false}
id="throughputInput"
key="provisioned throughput input"
- min={10000}
onChange={[Function]}
required={true}
step={100}
diff --git a/src/Explorer/Controls/Settings/SettingsUtils.test.tsx b/src/Explorer/Controls/Settings/SettingsUtils.test.tsx
index b69e72ac7..b072f63d9 100644
--- a/src/Explorer/Controls/Settings/SettingsUtils.test.tsx
+++ b/src/Explorer/Controls/Settings/SettingsUtils.test.tsx
@@ -2,6 +2,7 @@ import { collection, container } from "./TestUtils";
import {
getMaxRUs,
getMinRUs,
+ getSanitizedInputValue,
hasDatabaseSharedThroughput,
isDirty,
isDirtyTypes,
@@ -86,4 +87,11 @@ describe("SettingsUtils", () => {
expect(isDirty(baseline, current)).toEqual(true);
});
});
+
+ it("getSanitizedInputValue", () => {
+ const max = 100;
+ expect(getSanitizedInputValue("", max)).toEqual(0);
+ expect(getSanitizedInputValue("999", max)).toEqual(99);
+ expect(getSanitizedInputValue("10", max)).toEqual(10);
+ });
});
diff --git a/src/Explorer/Controls/Settings/SettingsUtils.tsx b/src/Explorer/Controls/Settings/SettingsUtils.tsx
index 026868c2b..790c08f2f 100644
--- a/src/Explorer/Controls/Settings/SettingsUtils.tsx
+++ b/src/Explorer/Controls/Settings/SettingsUtils.tsx
@@ -6,6 +6,7 @@ import * as PricingUtils from "../../../Utils/PricingUtils";
import Explorer from "../../Explorer";
+const zeroValue = 0;
export type isDirtyTypes = boolean | string | number | DataModels.IndexingPolicy;
export const TtlOff = "off";
export const TtlOn = "on";
@@ -129,6 +130,16 @@ export const parseConflictResolutionProcedure = (procedureFromBackEnd: string):
return procedureFromBackEnd;
};
+export const getSanitizedInputValue = (newValueString: string, max: number): number => {
+ let newValue = parseInt(newValueString);
+ if (isNaN(newValue)) {
+ newValue = zeroValue;
+ } else if (newValue > max) {
+ newValue = Math.floor(newValue / 10);
+ }
+ return newValue;
+};
+
export const isDirty = (current: isDirtyTypes, baseline: isDirtyTypes): boolean => {
const currentType = typeof current;
const baselineType = typeof baseline;
diff --git a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap
index b03865c5f..37746400b 100644
--- a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap
+++ b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap
@@ -5325,7 +5325,6 @@ exports[`SettingsComponent renders 1`] = `
logIndexingPolicySuccessMessage={[Function]}
onIndexingPolicyContentChange={[Function]}
onIndexingPolicyDirtyChange={[Function]}
- onIndexingPolicyElementFocusChange={[Function]}
resetShouldDiscardIndexingPolicy={[Function]}
shouldDiscardIndexingPolicy={false}
/>
diff --git a/src/Explorer/Explorer.ts b/src/Explorer/Explorer.ts
index 3a38cb183..e98526700 100644
--- a/src/Explorer/Explorer.ts
+++ b/src/Explorer/Explorer.ts
@@ -212,7 +212,7 @@ export default class Explorer {
public isGalleryPublishEnabled: ko.Computed;
public isCodeOfConductEnabled: ko.Computed;
public isLinkInjectionEnabled: ko.Computed;
- public isSettingsV2Enabled: ko.Computed;
+ public isSettingsV2Enabled: ko.Observable;
public isGitHubPaneEnabled: ko.Observable;
public isPublishNotebookPaneEnabled: ko.Observable;
public isCopyNotebookPaneEnabled: ko.Observable;
@@ -421,7 +421,8 @@ export default class Explorer {
this.isLinkInjectionEnabled = ko.computed(() =>
this.isFeatureEnabled(Constants.Features.enableLinkInjection)
);
- this.isSettingsV2Enabled = ko.computed(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
+ //this.isSettingsV2Enabled = ko.computed(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
+ this.isSettingsV2Enabled = ko.observable(false);
this.isGitHubPaneEnabled = ko.observable(false);
this.isPublishNotebookPaneEnabled = ko.observable(false);
this.isCopyNotebookPaneEnabled = ko.observable(false);
@@ -1919,6 +1920,7 @@ export default class Explorer {
this.flight(inputs.addCollectionDefaultFlight);
this.isTryCosmosDBSubscription(inputs.isTryCosmosDBSubscription);
this.isAuthWithResourceToken(inputs.isAuthWithresourceToken);
+ this.setFeatureFlagsFromFlights(inputs.flights);
if (!!inputs.dataExplorerVersion) {
this.parentFrameDataExplorerVersion(inputs.dataExplorerVersion);
@@ -1953,6 +1955,16 @@ export default class Explorer {
return Q();
}
+ public setFeatureFlagsFromFlights(flights: readonly string[]): void {
+ if (!flights) {
+ return;
+ }
+
+ if (flights.indexOf(Constants.Flights.SettingsV2) !== -1) {
+ this.isSettingsV2Enabled(true);
+ }
+ }
+
public findSelectedCollection(): ViewModels.Collection {
if (this.selectedNode().nodeKind === "Collection") {
return this.findSelectedCollectionForSelectedNode();