mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 15:06:55 +00:00
Fixed settingsV2 bugs and added experimentation (#264)
* inital commit for flight tests - FIxed bugs with settingstab v2 * minor edits * removed console log * fixed bug with autoscale throughput step increase * resolved PR comments * fixed compile error * Added comment
This commit is contained in:
parent
444f663733
commit
8028734cb0
@ -117,7 +117,6 @@ export class Features {
|
|||||||
public static readonly enableGalleryPublish = "enablegallerypublish";
|
public static readonly enableGalleryPublish = "enablegallerypublish";
|
||||||
public static readonly enableCodeOfConduct = "enablecodeofconduct";
|
public static readonly enableCodeOfConduct = "enablecodeofconduct";
|
||||||
public static readonly enableLinkInjection = "enablelinkinjection";
|
public static readonly enableLinkInjection = "enablelinkinjection";
|
||||||
public static readonly enableSettingsV2 = "enablesettingsv2";
|
|
||||||
public static readonly enableSpark = "enablespark";
|
public static readonly enableSpark = "enablespark";
|
||||||
public static readonly livyEndpoint = "livyendpoint";
|
public static readonly livyEndpoint = "livyendpoint";
|
||||||
public static readonly notebookServerUrl = "notebookserverurl";
|
public static readonly notebookServerUrl = "notebookserverurl";
|
||||||
@ -131,6 +130,11 @@ export class Features {
|
|||||||
public static readonly enableSDKoperations = "enablesdkoperations";
|
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 {
|
export class AfecFeatures {
|
||||||
public static readonly Spark = "spark-public-preview";
|
public static readonly Spark = "spark-public-preview";
|
||||||
public static readonly Notebooks = "sparknotebooks-public-preview";
|
public static readonly Notebooks = "sparknotebooks-public-preview";
|
||||||
|
@ -388,6 +388,7 @@ export interface DataExplorerInputsFrame {
|
|||||||
dataExplorerVersion?: string;
|
dataExplorerVersion?: string;
|
||||||
isAuthWithresourceToken?: boolean;
|
isAuthWithresourceToken?: boolean;
|
||||||
defaultCollectionThroughput?: CollectionCreationDefaults;
|
defaultCollectionThroughput?: CollectionCreationDefaults;
|
||||||
|
flights?: readonly string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionCreationDefaults {
|
export interface CollectionCreationDefaults {
|
||||||
|
@ -55,7 +55,6 @@ export const FeaturePanelComponent: React.FunctionComponent = () => {
|
|||||||
label: "Enable Injecting Notebook Viewer Link into the first cell",
|
label: "Enable Injecting Notebook Viewer Link into the first cell",
|
||||||
value: "true"
|
value: "true"
|
||||||
},
|
},
|
||||||
{ key: "feature.enablesettingsv2", label: "Enable SettingsV2 Tab", value: "true" },
|
|
||||||
{ key: "feature.canexceedmaximumvalue", label: "Can exceed max value", value: "true" },
|
{ key: "feature.canexceedmaximumvalue", label: "Can exceed max value", value: "true" },
|
||||||
{
|
{
|
||||||
key: "feature.enablefixedcollectionwithsharedthroughput",
|
key: "feature.enablefixedcollectionwithsharedthroughput",
|
||||||
|
@ -178,12 +178,6 @@ exports[`Feature panel renders all flags 1`] = `
|
|||||||
className="checkboxRow"
|
className="checkboxRow"
|
||||||
horizontalAlign="space-between"
|
horizontalAlign="space-between"
|
||||||
>
|
>
|
||||||
<StyledCheckboxBase
|
|
||||||
checked={false}
|
|
||||||
key="feature.enablesettingsv2"
|
|
||||||
label="Enable SettingsV2 Tab"
|
|
||||||
onChange={[Function]}
|
|
||||||
/>
|
|
||||||
<StyledCheckboxBase
|
<StyledCheckboxBase
|
||||||
checked={false}
|
checked={false}
|
||||||
key="feature.canexceedmaximumvalue"
|
key="feature.canexceedmaximumvalue"
|
||||||
|
@ -6,7 +6,7 @@ import SettingsTabV2 from "../../Tabs/SettingsTabV2";
|
|||||||
import { collection } from "./TestUtils";
|
import { collection } from "./TestUtils";
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import { TtlType, isDirty, TtlOnNoDefault, TtlOn, TtlOff } from "./SettingsUtils";
|
import { TtlType, isDirty } from "./SettingsUtils";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import { updateCollection } from "../../../Common/dataAccess/updateCollection";
|
import { updateCollection } from "../../../Common/dataAccess/updateCollection";
|
||||||
jest.mock("../../../Common/dataAccess/updateCollection", () => ({
|
jest.mock("../../../Common/dataAccess/updateCollection", () => ({
|
||||||
@ -220,13 +220,6 @@ describe("SettingsComponent", () => {
|
|||||||
expect(isDirty(state.throughput, state.throughputBaseline)).toEqual(false);
|
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", () => {
|
it("getAnalyticalStorageTtl", () => {
|
||||||
const newCollection = { ...collection };
|
const newCollection = { ...collection };
|
||||||
newCollection.analyticalStorageTtl = ko.observable(10);
|
newCollection.analyticalStorageTtl = ko.observable(10);
|
||||||
|
@ -27,9 +27,6 @@ import {
|
|||||||
SettingsV2TabTypes,
|
SettingsV2TabTypes,
|
||||||
getTabTitle,
|
getTabTitle,
|
||||||
isDirty,
|
isDirty,
|
||||||
TtlOff,
|
|
||||||
TtlOn,
|
|
||||||
TtlOnNoDefault,
|
|
||||||
parseConflictResolutionMode,
|
parseConflictResolutionMode,
|
||||||
parseConflictResolutionProcedure
|
parseConflictResolutionProcedure
|
||||||
} from "./SettingsUtils";
|
} from "./SettingsUtils";
|
||||||
@ -38,7 +35,7 @@ import {
|
|||||||
ConflictResolutionComponentProps
|
ConflictResolutionComponentProps
|
||||||
} from "./SettingsSubComponents/ConflictResolutionComponent";
|
} from "./SettingsSubComponents/ConflictResolutionComponent";
|
||||||
import { SubSettingsComponent, SubSettingsComponentProps } from "./SettingsSubComponents/SubSettingsComponent";
|
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 "./SettingsComponent.less";
|
||||||
import { IndexingPolicyComponent, IndexingPolicyComponentProps } from "./SettingsSubComponents/IndexingPolicyComponent";
|
import { IndexingPolicyComponent, IndexingPolicyComponentProps } from "./SettingsSubComponents/IndexingPolicyComponent";
|
||||||
|
|
||||||
@ -85,7 +82,6 @@ export interface SettingsComponentState {
|
|||||||
indexingPolicyContent: DataModels.IndexingPolicy;
|
indexingPolicyContent: DataModels.IndexingPolicy;
|
||||||
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
|
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
|
||||||
shouldDiscardIndexingPolicy: boolean;
|
shouldDiscardIndexingPolicy: boolean;
|
||||||
indexingPolicyElementFocussed: boolean;
|
|
||||||
isIndexingPolicyDirty: boolean;
|
isIndexingPolicyDirty: boolean;
|
||||||
|
|
||||||
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode;
|
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode;
|
||||||
@ -102,7 +98,6 @@ export interface SettingsComponentState {
|
|||||||
|
|
||||||
export class SettingsComponent extends React.Component<SettingsComponentProps, SettingsComponentState> {
|
export class SettingsComponent extends React.Component<SettingsComponentProps, SettingsComponentState> {
|
||||||
private static readonly sixMonthsInSeconds = 15768000;
|
private static readonly sixMonthsInSeconds = 15768000;
|
||||||
private static readonly zeroSeconds = 0;
|
|
||||||
|
|
||||||
public saveSettingsButton: ButtonV2;
|
public saveSettingsButton: ButtonV2;
|
||||||
public discardSettingsChangesButton: ButtonV2;
|
public discardSettingsChangesButton: ButtonV2;
|
||||||
@ -160,7 +155,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
|
|
||||||
indexingPolicyContent: undefined,
|
indexingPolicyContent: undefined,
|
||||||
indexingPolicyContentBaseline: undefined,
|
indexingPolicyContentBaseline: undefined,
|
||||||
indexingPolicyElementFocussed: false,
|
|
||||||
shouldDiscardIndexingPolicy: false,
|
shouldDiscardIndexingPolicy: false,
|
||||||
isIndexingPolicyDirty: false,
|
isIndexingPolicyDirty: false,
|
||||||
|
|
||||||
@ -518,9 +512,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
private onScaleDiscardableChange = (isScaleDiscardable: boolean): void =>
|
private onScaleDiscardableChange = (isScaleDiscardable: boolean): void =>
|
||||||
this.setState({ isScaleDiscardable: isScaleDiscardable });
|
this.setState({ isScaleDiscardable: isScaleDiscardable });
|
||||||
|
|
||||||
private onIndexingPolicyElementFocusChange = (indexingPolicyElementFocussed: boolean): void =>
|
|
||||||
this.setState({ indexingPolicyElementFocussed: indexingPolicyElementFocussed });
|
|
||||||
|
|
||||||
private onIndexingPolicyContentChange = (newIndexingPolicy: DataModels.IndexingPolicy): void =>
|
private onIndexingPolicyContentChange = (newIndexingPolicy: DataModels.IndexingPolicy): void =>
|
||||||
this.setState({ indexingPolicyContent: newIndexingPolicy });
|
this.setState({ indexingPolicyContent: newIndexingPolicy });
|
||||||
|
|
||||||
@ -544,79 +535,34 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private onConflictResolutionPolicyModeChange = (
|
private onConflictResolutionPolicyModeChange = (newMode: DataModels.ConflictResolutionMode): void =>
|
||||||
event?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
this.setState({ conflictResolutionPolicyMode: newMode });
|
||||||
option?: IChoiceGroupOption
|
|
||||||
): void =>
|
|
||||||
this.setState({
|
|
||||||
conflictResolutionPolicyMode:
|
|
||||||
DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode]
|
|
||||||
});
|
|
||||||
|
|
||||||
private onConflictResolutionPolicyPathChange = (
|
private onConflictResolutionPolicyPathChange = (newPath: string): void =>
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
this.setState({ conflictResolutionPolicyPath: newPath });
|
||||||
newValue?: string
|
|
||||||
): void => this.setState({ conflictResolutionPolicyPath: newValue });
|
|
||||||
|
|
||||||
private onConflictResolutionPolicyProcedureChange = (
|
private onConflictResolutionPolicyProcedureChange = (newProcedure: string): void =>
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
this.setState({ conflictResolutionPolicyProcedure: newProcedure });
|
||||||
newValue?: string
|
|
||||||
): void => this.setState({ conflictResolutionPolicyProcedure: newValue });
|
|
||||||
|
|
||||||
private onConflictResolutionDirtyChange = (isConflictResolutionDirty: boolean): void =>
|
private onConflictResolutionDirtyChange = (isConflictResolutionDirty: boolean): void =>
|
||||||
this.setState({ isConflictResolutionDirty: isConflictResolutionDirty });
|
this.setState({ isConflictResolutionDirty: isConflictResolutionDirty });
|
||||||
|
|
||||||
public getTtlValue = (value: string): TtlType => {
|
private onTtlChange = (newTtl: TtlType): void => this.setState({ timeToLive: newTtl });
|
||||||
switch (value) {
|
|
||||||
case TtlOn:
|
|
||||||
return TtlType.On;
|
|
||||||
case TtlOff:
|
|
||||||
return TtlType.Off;
|
|
||||||
case TtlOnNoDefault:
|
|
||||||
return TtlType.OnNoDefault;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
private onTtlChange = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption): void =>
|
private onTimeToLiveSecondsChange = (newTimeToLiveSeconds: number): void =>
|
||||||
this.setState({ timeToLive: this.getTtlValue(option.key) });
|
|
||||||
|
|
||||||
private onTimeToLiveSecondsChange = (
|
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
): void => {
|
|
||||||
let newTimeToLiveSeconds = parseInt(newValue);
|
|
||||||
newTimeToLiveSeconds = isNaN(newTimeToLiveSeconds) ? SettingsComponent.zeroSeconds : newTimeToLiveSeconds;
|
|
||||||
this.setState({ timeToLiveSeconds: newTimeToLiveSeconds });
|
this.setState({ timeToLiveSeconds: newTimeToLiveSeconds });
|
||||||
};
|
|
||||||
|
|
||||||
private onGeoSpatialConfigTypeChange = (
|
private onGeoSpatialConfigTypeChange = (newGeoSpatialConfigType: GeospatialConfigType): void =>
|
||||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
this.setState({ geospatialConfigType: newGeoSpatialConfigType });
|
||||||
option?: IChoiceGroupOption
|
|
||||||
): void =>
|
|
||||||
this.setState({ geospatialConfigType: GeospatialConfigType[option.key as keyof typeof GeospatialConfigType] });
|
|
||||||
|
|
||||||
private onAnalyticalStorageTtlSelectionChange = (
|
private onAnalyticalStorageTtlSelectionChange = (newAnalyticalStorageTtlSelection: TtlType): void =>
|
||||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
this.setState({ analyticalStorageTtlSelection: newAnalyticalStorageTtlSelection });
|
||||||
option?: IChoiceGroupOption
|
|
||||||
): void => this.setState({ analyticalStorageTtlSelection: this.getTtlValue(option.key) });
|
|
||||||
|
|
||||||
private onAnalyticalStorageTtlSecondsChange = (
|
private onAnalyticalStorageTtlSecondsChange = (newAnalyticalStorageTtlSeconds: number): void =>
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
): void => {
|
|
||||||
let newAnalyticalStorageTtlSeconds = parseInt(newValue);
|
|
||||||
newAnalyticalStorageTtlSeconds = isNaN(newAnalyticalStorageTtlSeconds)
|
|
||||||
? SettingsComponent.zeroSeconds
|
|
||||||
: newAnalyticalStorageTtlSeconds;
|
|
||||||
this.setState({ analyticalStorageTtlSeconds: newAnalyticalStorageTtlSeconds });
|
this.setState({ analyticalStorageTtlSeconds: newAnalyticalStorageTtlSeconds });
|
||||||
};
|
|
||||||
|
|
||||||
private onChangeFeedPolicyChange = (
|
private onChangeFeedPolicyChange = (newChangeFeedPolicy: ChangeFeedPolicyState): void =>
|
||||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
this.setState({ changeFeedPolicy: newChangeFeedPolicy });
|
||||||
option?: IChoiceGroupOption
|
|
||||||
): void =>
|
|
||||||
this.setState({ changeFeedPolicy: ChangeFeedPolicyState[option.key as keyof typeof ChangeFeedPolicyState] });
|
|
||||||
|
|
||||||
private onSubSettingsSaveableChange = (isSubSettingsSaveable: boolean): void =>
|
private onSubSettingsSaveableChange = (isSubSettingsSaveable: boolean): void =>
|
||||||
this.setState({ isSubSettingsSaveable: isSubSettingsSaveable });
|
this.setState({ isSubSettingsSaveable: isSubSettingsSaveable });
|
||||||
@ -844,7 +790,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
resetShouldDiscardIndexingPolicy: this.resetShouldDiscardIndexingPolicy,
|
resetShouldDiscardIndexingPolicy: this.resetShouldDiscardIndexingPolicy,
|
||||||
indexingPolicyContent: this.state.indexingPolicyContent,
|
indexingPolicyContent: this.state.indexingPolicyContent,
|
||||||
indexingPolicyContentBaseline: this.state.indexingPolicyContentBaseline,
|
indexingPolicyContentBaseline: this.state.indexingPolicyContentBaseline,
|
||||||
onIndexingPolicyElementFocusChange: this.onIndexingPolicyElementFocusChange,
|
|
||||||
onIndexingPolicyContentChange: this.onIndexingPolicyContentChange,
|
onIndexingPolicyContentChange: this.onIndexingPolicyContentChange,
|
||||||
logIndexingPolicySuccessMessage: this.logIndexingPolicySuccessMessage,
|
logIndexingPolicySuccessMessage: this.logIndexingPolicySuccessMessage,
|
||||||
onIndexingPolicyDirtyChange: this.onIndexingPolicyDirtyChange
|
onIndexingPolicyDirtyChange: this.onIndexingPolicyDirtyChange
|
||||||
|
@ -18,24 +18,15 @@ export interface ConflictResolutionComponentProps {
|
|||||||
container: Explorer;
|
container: Explorer;
|
||||||
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode;
|
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode;
|
||||||
conflictResolutionPolicyModeBaseline: DataModels.ConflictResolutionMode;
|
conflictResolutionPolicyModeBaseline: DataModels.ConflictResolutionMode;
|
||||||
onConflictResolutionPolicyModeChange: (
|
onConflictResolutionPolicyModeChange: (newMode: DataModels.ConflictResolutionMode) => void;
|
||||||
event?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
|
||||||
option?: IChoiceGroupOption
|
|
||||||
) => void;
|
|
||||||
conflictResolutionPolicyPath: string;
|
conflictResolutionPolicyPath: string;
|
||||||
conflictResolutionPolicyPathBaseline: string;
|
conflictResolutionPolicyPathBaseline: string;
|
||||||
|
|
||||||
onConflictResolutionPolicyPathChange: (
|
onConflictResolutionPolicyPathChange: (newPath: string) => void;
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
) => void;
|
|
||||||
conflictResolutionPolicyProcedure: string;
|
conflictResolutionPolicyProcedure: string;
|
||||||
conflictResolutionPolicyProcedureBaseline: string;
|
conflictResolutionPolicyProcedureBaseline: string;
|
||||||
|
|
||||||
onConflictResolutionPolicyProcedureChange: (
|
onConflictResolutionPolicyProcedureChange: (newProcedure: string) => void;
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
) => void;
|
|
||||||
onConflictResolutionDirtyChange: (isConflictResolutionDirty: boolean) => void;
|
onConflictResolutionDirtyChange: (isConflictResolutionDirty: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,12 +68,30 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onConflictResolutionPolicyModeChange = (
|
||||||
|
event?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||||
|
option?: IChoiceGroupOption
|
||||||
|
): void =>
|
||||||
|
this.props.onConflictResolutionPolicyModeChange(
|
||||||
|
DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode]
|
||||||
|
);
|
||||||
|
|
||||||
|
private onConflictResolutionPolicyPathChange = (
|
||||||
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
newValue?: string
|
||||||
|
): void => this.props.onConflictResolutionPolicyPathChange(newValue);
|
||||||
|
|
||||||
|
private onConflictResolutionPolicyProcedureChange = (
|
||||||
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
newValue?: string
|
||||||
|
): void => this.props.onConflictResolutionPolicyProcedureChange(newValue);
|
||||||
|
|
||||||
private getConflictResolutionModeComponent = (): JSX.Element => (
|
private getConflictResolutionModeComponent = (): JSX.Element => (
|
||||||
<ChoiceGroup
|
<ChoiceGroup
|
||||||
label="Mode"
|
label="Mode"
|
||||||
selectedKey={this.props.conflictResolutionPolicyMode}
|
selectedKey={this.props.conflictResolutionPolicyMode}
|
||||||
options={this.conflictResolutionChoiceGroupOptions}
|
options={this.conflictResolutionChoiceGroupOptions}
|
||||||
onChange={this.props.onConflictResolutionPolicyModeChange}
|
onChange={this.onConflictResolutionPolicyModeChange}
|
||||||
styles={getChoiceGroupStyles(
|
styles={getChoiceGroupStyles(
|
||||||
this.props.conflictResolutionPolicyMode,
|
this.props.conflictResolutionPolicyMode,
|
||||||
this.props.conflictResolutionPolicyModeBaseline
|
this.props.conflictResolutionPolicyModeBaseline
|
||||||
@ -104,7 +113,7 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
|||||||
this.props.conflictResolutionPolicyPathBaseline
|
this.props.conflictResolutionPolicyPathBaseline
|
||||||
)}
|
)}
|
||||||
value={this.props.conflictResolutionPolicyPath}
|
value={this.props.conflictResolutionPolicyPath}
|
||||||
onChange={this.props.onConflictResolutionPolicyPathChange}
|
onChange={this.onConflictResolutionPolicyPathChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -122,7 +131,7 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
|||||||
this.props.conflictResolutionPolicyProcedureBaseline
|
this.props.conflictResolutionPolicyProcedureBaseline
|
||||||
)}
|
)}
|
||||||
value={this.props.conflictResolutionPolicyProcedure}
|
value={this.props.conflictResolutionPolicyProcedure}
|
||||||
onChange={this.props.onConflictResolutionPolicyProcedureChange}
|
onChange={this.onConflictResolutionPolicyProcedureChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,9 +17,6 @@ describe("IndexingPolicyComponent", () => {
|
|||||||
},
|
},
|
||||||
indexingPolicyContent: initialIndexingPolicyContent,
|
indexingPolicyContent: initialIndexingPolicyContent,
|
||||||
indexingPolicyContentBaseline: initialIndexingPolicyContent,
|
indexingPolicyContentBaseline: initialIndexingPolicyContent,
|
||||||
onIndexingPolicyElementFocusChange: () => {
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
onIndexingPolicyContentChange: () => {
|
onIndexingPolicyContentChange: () => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
@ -10,7 +10,6 @@ export interface IndexingPolicyComponentProps {
|
|||||||
resetShouldDiscardIndexingPolicy: () => void;
|
resetShouldDiscardIndexingPolicy: () => void;
|
||||||
indexingPolicyContent: DataModels.IndexingPolicy;
|
indexingPolicyContent: DataModels.IndexingPolicy;
|
||||||
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
|
indexingPolicyContentBaseline: DataModels.IndexingPolicy;
|
||||||
onIndexingPolicyElementFocusChange: (indexingPolicyContentFocussed: boolean) => void;
|
|
||||||
onIndexingPolicyContentChange: (newIndexingPolicy: DataModels.IndexingPolicy) => void;
|
onIndexingPolicyContentChange: (newIndexingPolicy: DataModels.IndexingPolicy) => void;
|
||||||
logIndexingPolicySuccessMessage: () => void;
|
logIndexingPolicySuccessMessage: () => void;
|
||||||
onIndexingPolicyDirtyChange: (isIndexingPolicyDirty: boolean) => void;
|
onIndexingPolicyDirtyChange: (isIndexingPolicyDirty: boolean) => void;
|
||||||
@ -89,8 +88,6 @@ export class IndexingPolicyComponent extends React.Component<
|
|||||||
ariaLabel: "Indexing Policy"
|
ariaLabel: "Indexing Policy"
|
||||||
});
|
});
|
||||||
if (this.indexingPolicyEditor) {
|
if (this.indexingPolicyEditor) {
|
||||||
this.indexingPolicyEditor.onDidFocusEditorText(() => this.props.onIndexingPolicyElementFocusChange(true));
|
|
||||||
this.indexingPolicyEditor.onDidBlurEditorText(() => this.props.onIndexingPolicyElementFocusChange(false));
|
|
||||||
const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel();
|
const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel();
|
||||||
indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this));
|
indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this));
|
||||||
this.props.logIndexingPolicySuccessMessage();
|
this.props.logIndexingPolicySuccessMessage();
|
||||||
|
@ -2,7 +2,7 @@ import { shallow } from "enzyme";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { SubSettingsComponent, SubSettingsComponentProps } from "./SubSettingsComponent";
|
import { SubSettingsComponent, SubSettingsComponentProps } from "./SubSettingsComponent";
|
||||||
import { container, collection } from "../TestUtils";
|
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 ko from "knockout";
|
||||||
import Explorer from "../../../Explorer";
|
import Explorer from "../../../Explorer";
|
||||||
|
|
||||||
@ -133,4 +133,11 @@ describe("SubSettingsComponent", () => {
|
|||||||
expect(isComponentDirtyResult.isSaveable).toEqual(true);
|
expect(isComponentDirtyResult.isSaveable).toEqual(true);
|
||||||
expect(isComponentDirtyResult.isDiscardable).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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,11 @@ import {
|
|||||||
TtlType,
|
TtlType,
|
||||||
ChangeFeedPolicyState,
|
ChangeFeedPolicyState,
|
||||||
isDirty,
|
isDirty,
|
||||||
IsComponentDirtyResult
|
IsComponentDirtyResult,
|
||||||
|
TtlOn,
|
||||||
|
TtlOff,
|
||||||
|
TtlOnNoDefault,
|
||||||
|
getSanitizedInputValue
|
||||||
} from "../SettingsUtils";
|
} from "../SettingsUtils";
|
||||||
import Explorer from "../../../Explorer";
|
import Explorer from "../../../Explorer";
|
||||||
import { Int32 } from "../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
import { Int32 } from "../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
||||||
@ -37,40 +41,28 @@ export interface SubSettingsComponentProps {
|
|||||||
timeToLive: TtlType;
|
timeToLive: TtlType;
|
||||||
timeToLiveBaseline: TtlType;
|
timeToLiveBaseline: TtlType;
|
||||||
|
|
||||||
onTtlChange: (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption) => void;
|
onTtlChange: (newTtl: TtlType) => void;
|
||||||
timeToLiveSeconds: number;
|
timeToLiveSeconds: number;
|
||||||
timeToLiveSecondsBaseline: number;
|
timeToLiveSecondsBaseline: number;
|
||||||
onTimeToLiveSecondsChange: (
|
onTimeToLiveSecondsChange: (newTimeToLiveSeconds: number) => void;
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
geospatialConfigType: GeospatialConfigType;
|
geospatialConfigType: GeospatialConfigType;
|
||||||
geospatialConfigTypeBaseline: GeospatialConfigType;
|
geospatialConfigTypeBaseline: GeospatialConfigType;
|
||||||
onGeoSpatialConfigTypeChange: (
|
onGeoSpatialConfigTypeChange: (newGeoSpatialConfigType: GeospatialConfigType) => void;
|
||||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
|
||||||
option?: IChoiceGroupOption
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
isAnalyticalStorageEnabled: boolean;
|
isAnalyticalStorageEnabled: boolean;
|
||||||
analyticalStorageTtlSelection: TtlType;
|
analyticalStorageTtlSelection: TtlType;
|
||||||
analyticalStorageTtlSelectionBaseline: TtlType;
|
analyticalStorageTtlSelectionBaseline: TtlType;
|
||||||
onAnalyticalStorageTtlSelectionChange: (
|
onAnalyticalStorageTtlSelectionChange: (newAnalyticalStorageTtlSelection: TtlType) => void;
|
||||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
|
||||||
option?: IChoiceGroupOption
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
analyticalStorageTtlSeconds: number;
|
analyticalStorageTtlSeconds: number;
|
||||||
analyticalStorageTtlSecondsBaseline: number;
|
analyticalStorageTtlSecondsBaseline: number;
|
||||||
onAnalyticalStorageTtlSecondsChange: (
|
onAnalyticalStorageTtlSecondsChange: (newAnalyticalStorageTtlSeconds: number) => void;
|
||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
|
||||||
newValue?: string
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
changeFeedPolicyVisible: boolean;
|
changeFeedPolicyVisible: boolean;
|
||||||
changeFeedPolicy: ChangeFeedPolicyState;
|
changeFeedPolicy: ChangeFeedPolicyState;
|
||||||
changeFeedPolicyBaseline: ChangeFeedPolicyState;
|
changeFeedPolicyBaseline: ChangeFeedPolicyState;
|
||||||
onChangeFeedPolicyChange: (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption) => void;
|
onChangeFeedPolicyChange: (newChangeFeedPolicyState: ChangeFeedPolicyState) => void;
|
||||||
onSubSettingsSaveableChange: (isSubSettingsSaveable: boolean) => void;
|
onSubSettingsSaveableChange: (isSubSettingsSaveable: boolean) => void;
|
||||||
onSubSettingsDiscardableChange: (isSubSettingsDiscardable: boolean) => void;
|
onSubSettingsDiscardableChange: (isSubSettingsDiscardable: boolean) => void;
|
||||||
}
|
}
|
||||||
@ -139,6 +131,54 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
{ key: TtlType.On, text: "On" }
|
{ key: TtlType.On, text: "On" }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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 = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption): void =>
|
||||||
|
this.props.onTtlChange(this.getTtlValue(option.key));
|
||||||
|
|
||||||
|
private onTimeToLiveSecondsChange = (
|
||||||
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
newValue?: string
|
||||||
|
): void => {
|
||||||
|
const newTimeToLiveSeconds = getSanitizedInputValue(newValue, Int32.Max);
|
||||||
|
this.props.onTimeToLiveSecondsChange(newTimeToLiveSeconds);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onGeoSpatialConfigTypeChange = (
|
||||||
|
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||||
|
option?: IChoiceGroupOption
|
||||||
|
): void =>
|
||||||
|
this.props.onGeoSpatialConfigTypeChange(GeospatialConfigType[option.key as keyof typeof GeospatialConfigType]);
|
||||||
|
|
||||||
|
private onAnalyticalStorageTtlSelectionChange = (
|
||||||
|
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||||
|
option?: IChoiceGroupOption
|
||||||
|
): void => this.props.onAnalyticalStorageTtlSelectionChange(this.getTtlValue(option.key));
|
||||||
|
|
||||||
|
private onAnalyticalStorageTtlSecondsChange = (
|
||||||
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
newValue?: string
|
||||||
|
): void => {
|
||||||
|
const newAnalyticalStorageTtlSeconds = getSanitizedInputValue(newValue, Int32.Max);
|
||||||
|
this.props.onAnalyticalStorageTtlSecondsChange(newAnalyticalStorageTtlSeconds);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onChangeFeedPolicyChange = (
|
||||||
|
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||||
|
option?: IChoiceGroupOption
|
||||||
|
): void =>
|
||||||
|
this.props.onChangeFeedPolicyChange(ChangeFeedPolicyState[option.key as keyof typeof ChangeFeedPolicyState]);
|
||||||
|
|
||||||
private getTtlComponent = (): JSX.Element => (
|
private getTtlComponent = (): JSX.Element => (
|
||||||
<Stack {...titleAndInputStackProps}>
|
<Stack {...titleAndInputStackProps}>
|
||||||
<ChoiceGroup
|
<ChoiceGroup
|
||||||
@ -146,7 +186,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
label="Time to Live"
|
label="Time to Live"
|
||||||
selectedKey={this.props.timeToLive}
|
selectedKey={this.props.timeToLive}
|
||||||
options={this.ttlChoiceGroupOptions}
|
options={this.ttlChoiceGroupOptions}
|
||||||
onChange={this.props.onTtlChange}
|
onChange={this.onTtlChange}
|
||||||
styles={getChoiceGroupStyles(this.props.timeToLive, this.props.timeToLiveBaseline)}
|
styles={getChoiceGroupStyles(this.props.timeToLive, this.props.timeToLiveBaseline)}
|
||||||
/>
|
/>
|
||||||
{isDirty(this.props.timeToLive, this.props.timeToLiveBaseline) && this.props.timeToLive === TtlType.On && (
|
{isDirty(this.props.timeToLive, this.props.timeToLiveBaseline) && this.props.timeToLive === TtlType.On && (
|
||||||
@ -163,7 +203,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
min={1}
|
min={1}
|
||||||
max={Int32.Max}
|
max={Int32.Max}
|
||||||
value={this.props.timeToLiveSeconds?.toString()}
|
value={this.props.timeToLiveSeconds?.toString()}
|
||||||
onChange={this.props.onTimeToLiveSecondsChange}
|
onChange={this.onTimeToLiveSecondsChange}
|
||||||
suffix="second(s)"
|
suffix="second(s)"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -183,7 +223,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
label="Analytical Storage Time to Live"
|
label="Analytical Storage Time to Live"
|
||||||
selectedKey={this.props.analyticalStorageTtlSelection}
|
selectedKey={this.props.analyticalStorageTtlSelection}
|
||||||
options={this.analyticalTtlChoiceGroupOptions}
|
options={this.analyticalTtlChoiceGroupOptions}
|
||||||
onChange={this.props.onAnalyticalStorageTtlSelectionChange}
|
onChange={this.onAnalyticalStorageTtlSelectionChange}
|
||||||
styles={getChoiceGroupStyles(
|
styles={getChoiceGroupStyles(
|
||||||
this.props.analyticalStorageTtlSelection,
|
this.props.analyticalStorageTtlSelection,
|
||||||
this.props.analyticalStorageTtlSelectionBaseline
|
this.props.analyticalStorageTtlSelectionBaseline
|
||||||
@ -202,7 +242,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
max={Int32.Max}
|
max={Int32.Max}
|
||||||
value={this.props.analyticalStorageTtlSeconds?.toString()}
|
value={this.props.analyticalStorageTtlSeconds?.toString()}
|
||||||
suffix="second(s)"
|
suffix="second(s)"
|
||||||
onChange={this.props.onAnalyticalStorageTtlSecondsChange}
|
onChange={this.onAnalyticalStorageTtlSecondsChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
@ -219,7 +259,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
label="Geospatial Configuration"
|
label="Geospatial Configuration"
|
||||||
selectedKey={this.props.geospatialConfigType}
|
selectedKey={this.props.geospatialConfigType}
|
||||||
options={this.geoSpatialConfigTypeChoiceGroupOptions}
|
options={this.geoSpatialConfigTypeChoiceGroupOptions}
|
||||||
onChange={this.props.onGeoSpatialConfigTypeChange}
|
onChange={this.onGeoSpatialConfigTypeChange}
|
||||||
styles={getChoiceGroupStyles(this.props.geospatialConfigType, this.props.geospatialConfigTypeBaseline)}
|
styles={getChoiceGroupStyles(this.props.geospatialConfigType, this.props.geospatialConfigTypeBaseline)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -241,7 +281,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
|||||||
id="changeFeedPolicy"
|
id="changeFeedPolicy"
|
||||||
selectedKey={this.props.changeFeedPolicy}
|
selectedKey={this.props.changeFeedPolicy}
|
||||||
options={this.changeFeedChoiceGroupOptions}
|
options={this.changeFeedChoiceGroupOptions}
|
||||||
onChange={this.props.onChangeFeedPolicyChange}
|
onChange={this.onChangeFeedPolicyChange}
|
||||||
styles={getChoiceGroupStyles(this.props.changeFeedPolicy, this.props.changeFeedPolicyBaseline)}
|
styles={getChoiceGroupStyles(this.props.changeFeedPolicy, this.props.changeFeedPolicyBaseline)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
/>
|
/>
|
||||||
|
@ -26,9 +26,10 @@ import {
|
|||||||
MessageBarType
|
MessageBarType
|
||||||
} from "office-ui-fabric-react";
|
} from "office-ui-fabric-react";
|
||||||
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
||||||
import { IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
|
import { getSanitizedInputValue, IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
|
||||||
import * as SharedConstants from "../../../../../Shared/Constants";
|
import * as SharedConstants from "../../../../../Shared/Constants";
|
||||||
import * as DataModels from "../../../../../Contracts/DataModels";
|
import * as DataModels from "../../../../../Contracts/DataModels";
|
||||||
|
import { Int32 } from "../../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
||||||
|
|
||||||
export interface ThroughputInputAutoPilotV3Props {
|
export interface ThroughputInputAutoPilotV3Props {
|
||||||
databaseAccount: DataModels.DatabaseAccount;
|
databaseAccount: DataModels.DatabaseAccount;
|
||||||
@ -71,9 +72,9 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
> {
|
> {
|
||||||
private shouldCheckComponentIsDirty = true;
|
private shouldCheckComponentIsDirty = true;
|
||||||
private static readonly defaultStep = 100;
|
private static readonly defaultStep = 100;
|
||||||
private static readonly zeroThroughput = 0;
|
|
||||||
private step: number;
|
private step: number;
|
||||||
private choiceGroupFixedStyle = getChoiceGroupStyles(undefined, undefined);
|
private throughputInputMaxValue: number;
|
||||||
|
private autoPilotInputMaxValue: number;
|
||||||
private options: IChoiceGroupOption[] = [
|
private options: IChoiceGroupOption[] = [
|
||||||
{ key: "true", text: "Autoscale" },
|
{ key: "true", text: "Autoscale" },
|
||||||
{ key: "false", text: "Manual" }
|
{ key: "false", text: "Manual" }
|
||||||
@ -140,6 +141,8 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.step = this.props.step ?? ThroughputInputAutoPilotV3Component.defaultStep;
|
this.step = this.props.step ?? ThroughputInputAutoPilotV3Component.defaultStep;
|
||||||
|
this.throughputInputMaxValue = this.props.canExceedMaximumValue ? Int32.Max : this.props.maximum;
|
||||||
|
this.autoPilotInputMaxValue = Int32.Max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasProvisioningTypeChanged = (): boolean =>
|
public hasProvisioningTypeChanged = (): boolean =>
|
||||||
@ -200,8 +203,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
newValue?: string
|
newValue?: string
|
||||||
): void => {
|
): void => {
|
||||||
let newThroughput = parseInt(newValue);
|
const newThroughput = getSanitizedInputValue(newValue, this.autoPilotInputMaxValue);
|
||||||
newThroughput = isNaN(newThroughput) ? ThroughputInputAutoPilotV3Component.zeroThroughput : newThroughput;
|
|
||||||
this.props.onMaxAutoPilotThroughputChange(newThroughput);
|
this.props.onMaxAutoPilotThroughputChange(newThroughput);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,9 +211,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
newValue?: string
|
newValue?: string
|
||||||
): void => {
|
): void => {
|
||||||
let newThroughput = parseInt(newValue);
|
const newThroughput = getSanitizedInputValue(newValue, this.throughputInputMaxValue);
|
||||||
newThroughput = isNaN(newThroughput) ? ThroughputInputAutoPilotV3Component.zeroThroughput : newThroughput;
|
|
||||||
|
|
||||||
if (this.overrideWithAutoPilotSettings()) {
|
if (this.overrideWithAutoPilotSettings()) {
|
||||||
this.props.onMaxAutoPilotThroughputChange(newThroughput);
|
this.props.onMaxAutoPilotThroughputChange(newThroughput);
|
||||||
} else {
|
} else {
|
||||||
@ -245,7 +245,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
onChange={this.onChoiceGroupChange}
|
onChange={this.onChoiceGroupChange}
|
||||||
required={this.props.showAsMandatory}
|
required={this.props.showAsMandatory}
|
||||||
ariaLabelledBy={labelId}
|
ariaLabelledBy={labelId}
|
||||||
styles={this.choiceGroupFixedStyle}
|
styles={getChoiceGroupStyles(this.props.wasAutopilotOriginallySet, this.props.isAutoPilotSelected)}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
@ -270,8 +270,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
key="auto pilot throughput input"
|
key="auto pilot throughput input"
|
||||||
styles={getTextFieldStyles(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline)}
|
styles={getTextFieldStyles(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline)}
|
||||||
disabled={this.overrideWithProvisionedThroughputSettings()}
|
disabled={this.overrideWithProvisionedThroughputSettings()}
|
||||||
step={this.step}
|
step={AutoPilotUtils.autoPilotIncrementStep}
|
||||||
min={AutoPilotUtils.minAutoPilotThroughput}
|
|
||||||
value={this.overrideWithProvisionedThroughputSettings() ? "" : this.props.maxAutoPilotThroughput?.toString()}
|
value={this.overrideWithProvisionedThroughputSettings() ? "" : this.props.maxAutoPilotThroughput?.toString()}
|
||||||
onChange={this.onAutoPilotThroughputChange}
|
onChange={this.onAutoPilotThroughputChange}
|
||||||
/>
|
/>
|
||||||
@ -298,8 +297,6 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
styles={getTextFieldStyles(this.props.throughput, this.props.throughputBaseline)}
|
styles={getTextFieldStyles(this.props.throughput, this.props.throughputBaseline)}
|
||||||
disabled={this.overrideWithAutoPilotSettings()}
|
disabled={this.overrideWithAutoPilotSettings()}
|
||||||
step={this.step}
|
step={this.step}
|
||||||
min={this.props.minimum}
|
|
||||||
max={this.props.canExceedMaximumValue ? undefined : this.props.maximum}
|
|
||||||
value={
|
value={
|
||||||
this.overrideWithAutoPilotSettings()
|
this.overrideWithAutoPilotSettings()
|
||||||
? this.props.maxAutoPilotThroughputBaseline?.toString()
|
? this.props.maxAutoPilotThroughputBaseline?.toString()
|
||||||
|
@ -81,10 +81,10 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
|
|||||||
Object {
|
Object {
|
||||||
"selectors": Object {
|
"selectors": Object {
|
||||||
".ms-ChoiceField-field.is-checked::after": Object {
|
".ms-ChoiceField-field.is-checked::after": Object {
|
||||||
"borderColor": "",
|
"borderColor": undefined,
|
||||||
},
|
},
|
||||||
".ms-ChoiceField-field.is-checked::before": Object {
|
".ms-ChoiceField-field.is-checked::before": Object {
|
||||||
"borderColor": "",
|
"borderColor": undefined,
|
||||||
},
|
},
|
||||||
".ms-ChoiceField-wrapper label": Object {
|
".ms-ChoiceField-wrapper label": Object {
|
||||||
"fontFamily": undefined,
|
"fontFamily": undefined,
|
||||||
@ -113,10 +113,9 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
|
|||||||
id="autopilotInput"
|
id="autopilotInput"
|
||||||
key="auto pilot throughput input"
|
key="auto pilot throughput input"
|
||||||
label="Max RU/s"
|
label="Max RU/s"
|
||||||
min={4000}
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
required={true}
|
required={true}
|
||||||
step={100}
|
step={1000}
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
"fieldGroup": Object {
|
"fieldGroup": Object {
|
||||||
@ -219,7 +218,6 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
|
|||||||
disabled={false}
|
disabled={false}
|
||||||
id="throughputInput"
|
id="throughputInput"
|
||||||
key="provisioned throughput input"
|
key="provisioned throughput input"
|
||||||
min={10000}
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
required={true}
|
required={true}
|
||||||
step={100}
|
step={100}
|
||||||
@ -375,7 +373,6 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
|
|||||||
disabled={false}
|
disabled={false}
|
||||||
id="throughputInput"
|
id="throughputInput"
|
||||||
key="provisioned throughput input"
|
key="provisioned throughput input"
|
||||||
min={10000}
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
required={true}
|
required={true}
|
||||||
step={100}
|
step={100}
|
||||||
|
@ -2,6 +2,7 @@ import { collection, container } from "./TestUtils";
|
|||||||
import {
|
import {
|
||||||
getMaxRUs,
|
getMaxRUs,
|
||||||
getMinRUs,
|
getMinRUs,
|
||||||
|
getSanitizedInputValue,
|
||||||
hasDatabaseSharedThroughput,
|
hasDatabaseSharedThroughput,
|
||||||
isDirty,
|
isDirty,
|
||||||
isDirtyTypes,
|
isDirtyTypes,
|
||||||
@ -86,4 +87,11 @@ describe("SettingsUtils", () => {
|
|||||||
expect(isDirty(baseline, current)).toEqual(true);
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import * as PricingUtils from "../../../Utils/PricingUtils";
|
|||||||
|
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
|
|
||||||
|
const zeroValue = 0;
|
||||||
export type isDirtyTypes = boolean | string | number | DataModels.IndexingPolicy;
|
export type isDirtyTypes = boolean | string | number | DataModels.IndexingPolicy;
|
||||||
export const TtlOff = "off";
|
export const TtlOff = "off";
|
||||||
export const TtlOn = "on";
|
export const TtlOn = "on";
|
||||||
@ -129,6 +130,16 @@ export const parseConflictResolutionProcedure = (procedureFromBackEnd: string):
|
|||||||
return procedureFromBackEnd;
|
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 => {
|
export const isDirty = (current: isDirtyTypes, baseline: isDirtyTypes): boolean => {
|
||||||
const currentType = typeof current;
|
const currentType = typeof current;
|
||||||
const baselineType = typeof baseline;
|
const baselineType = typeof baseline;
|
||||||
|
@ -5325,7 +5325,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
logIndexingPolicySuccessMessage={[Function]}
|
logIndexingPolicySuccessMessage={[Function]}
|
||||||
onIndexingPolicyContentChange={[Function]}
|
onIndexingPolicyContentChange={[Function]}
|
||||||
onIndexingPolicyDirtyChange={[Function]}
|
onIndexingPolicyDirtyChange={[Function]}
|
||||||
onIndexingPolicyElementFocusChange={[Function]}
|
|
||||||
resetShouldDiscardIndexingPolicy={[Function]}
|
resetShouldDiscardIndexingPolicy={[Function]}
|
||||||
shouldDiscardIndexingPolicy={false}
|
shouldDiscardIndexingPolicy={false}
|
||||||
/>
|
/>
|
||||||
|
@ -212,7 +212,7 @@ export default class Explorer {
|
|||||||
public isGalleryPublishEnabled: ko.Computed<boolean>;
|
public isGalleryPublishEnabled: ko.Computed<boolean>;
|
||||||
public isCodeOfConductEnabled: ko.Computed<boolean>;
|
public isCodeOfConductEnabled: ko.Computed<boolean>;
|
||||||
public isLinkInjectionEnabled: ko.Computed<boolean>;
|
public isLinkInjectionEnabled: ko.Computed<boolean>;
|
||||||
public isSettingsV2Enabled: ko.Computed<boolean>;
|
public isSettingsV2Enabled: ko.Observable<boolean>;
|
||||||
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
||||||
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
||||||
public isCopyNotebookPaneEnabled: ko.Observable<boolean>;
|
public isCopyNotebookPaneEnabled: ko.Observable<boolean>;
|
||||||
@ -421,7 +421,8 @@ export default class Explorer {
|
|||||||
this.isLinkInjectionEnabled = ko.computed<boolean>(() =>
|
this.isLinkInjectionEnabled = ko.computed<boolean>(() =>
|
||||||
this.isFeatureEnabled(Constants.Features.enableLinkInjection)
|
this.isFeatureEnabled(Constants.Features.enableLinkInjection)
|
||||||
);
|
);
|
||||||
this.isSettingsV2Enabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
|
//this.isSettingsV2Enabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
|
||||||
|
this.isSettingsV2Enabled = ko.observable(false);
|
||||||
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
||||||
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||||
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
|
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||||
@ -1919,6 +1920,7 @@ export default class Explorer {
|
|||||||
this.flight(inputs.addCollectionDefaultFlight);
|
this.flight(inputs.addCollectionDefaultFlight);
|
||||||
this.isTryCosmosDBSubscription(inputs.isTryCosmosDBSubscription);
|
this.isTryCosmosDBSubscription(inputs.isTryCosmosDBSubscription);
|
||||||
this.isAuthWithResourceToken(inputs.isAuthWithresourceToken);
|
this.isAuthWithResourceToken(inputs.isAuthWithresourceToken);
|
||||||
|
this.setFeatureFlagsFromFlights(inputs.flights);
|
||||||
|
|
||||||
if (!!inputs.dataExplorerVersion) {
|
if (!!inputs.dataExplorerVersion) {
|
||||||
this.parentFrameDataExplorerVersion(inputs.dataExplorerVersion);
|
this.parentFrameDataExplorerVersion(inputs.dataExplorerVersion);
|
||||||
@ -1953,6 +1955,16 @@ export default class Explorer {
|
|||||||
return Q();
|
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 {
|
public findSelectedCollection(): ViewModels.Collection {
|
||||||
if (this.selectedNode().nodeKind === "Collection") {
|
if (this.selectedNode().nodeKind === "Collection") {
|
||||||
return this.findSelectedCollectionForSelectedNode();
|
return this.findSelectedCollectionForSelectedNode();
|
||||||
|
Loading…
Reference in New Issue
Block a user