mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-22 20:17:13 +00:00
Remove RU Max Limits
This commit is contained in:
parent
a133134b8b
commit
415ebc505b
@ -1,45 +0,0 @@
|
|||||||
import * as DataModels from "../../Contracts/DataModels";
|
|
||||||
import * as HeadersUtility from "../HeadersUtility";
|
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import { ContainerDefinition, Resource } from "@azure/cosmos";
|
|
||||||
import { HttpHeaders } from "../Constants";
|
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
|
||||||
import { client } from "../CosmosClient";
|
|
||||||
import { handleError } from "../ErrorHandlingUtils";
|
|
||||||
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
|
||||||
|
|
||||||
interface ResourceWithStatistics {
|
|
||||||
statistics: DataModels.Statistic[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const readCollectionQuotaInfo = async (
|
|
||||||
collection: ViewModels.Collection
|
|
||||||
): Promise<DataModels.CollectionQuotaInfo> => {
|
|
||||||
const clearMessage = logConsoleProgress(`Querying containers for database ${collection.id}`);
|
|
||||||
const options: RequestOptions = {};
|
|
||||||
options.populateQuotaInfo = true;
|
|
||||||
options.initialHeaders = options.initialHeaders || {};
|
|
||||||
options.initialHeaders[HttpHeaders.populatePartitionStatistics] = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await client()
|
|
||||||
.database(collection.databaseId)
|
|
||||||
.container(collection.id())
|
|
||||||
.read(options);
|
|
||||||
const quota: DataModels.CollectionQuotaInfo = HeadersUtility.getQuota(response.headers);
|
|
||||||
const resource = response.resource as ContainerDefinition & Resource & ResourceWithStatistics;
|
|
||||||
quota["usageSizeInKB"] = resource.statistics.reduce(
|
|
||||||
(previousValue: number, currentValue: DataModels.Statistic) => previousValue + currentValue.sizeInKB,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
quota["numPartitions"] = resource.statistics.length;
|
|
||||||
quota["uniqueKeyPolicy"] = collection.uniqueKeyPolicy; // TODO: Remove after refactoring (#119617)
|
|
||||||
|
|
||||||
return quota;
|
|
||||||
} catch (error) {
|
|
||||||
handleError(error, "ReadCollectionQuotaInfo", `Error while querying quota info for container ${collection.id}`);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
clearMessage();
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,25 +0,0 @@
|
|||||||
import { updateOfferThroughputBeyondLimit } from "./updateOfferThroughputBeyondLimit";
|
|
||||||
|
|
||||||
describe("updateOfferThroughputBeyondLimit", () => {
|
|
||||||
it("should call fetch", async () => {
|
|
||||||
window.fetch = jest.fn(() => {
|
|
||||||
return {
|
|
||||||
ok: true
|
|
||||||
};
|
|
||||||
});
|
|
||||||
window.dataExplorer = {
|
|
||||||
logConsoleData: jest.fn(),
|
|
||||||
deleteInProgressConsoleDataWithId: jest.fn()
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
} as any;
|
|
||||||
await updateOfferThroughputBeyondLimit({
|
|
||||||
subscriptionId: "foo",
|
|
||||||
resourceGroup: "foo",
|
|
||||||
databaseAccountName: "foo",
|
|
||||||
databaseName: "foo",
|
|
||||||
throughput: 1000000000,
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: false
|
|
||||||
});
|
|
||||||
expect(window.fetch).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,57 +0,0 @@
|
|||||||
import { Platform, configContext } from "../../ConfigContext";
|
|
||||||
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
|
|
||||||
import { AutoPilotOfferSettings } from "../../Contracts/DataModels";
|
|
||||||
import { logConsoleProgress, logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
|
|
||||||
import { HttpHeaders } from "../Constants";
|
|
||||||
import { handleError } from "../ErrorHandlingUtils";
|
|
||||||
|
|
||||||
interface UpdateOfferThroughputRequest {
|
|
||||||
subscriptionId: string;
|
|
||||||
resourceGroup: string;
|
|
||||||
databaseAccountName: string;
|
|
||||||
databaseName: string;
|
|
||||||
collectionName?: string;
|
|
||||||
throughput: number;
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: boolean;
|
|
||||||
offerAutopilotSettings?: AutoPilotOfferSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateOfferThroughputBeyondLimit(request: UpdateOfferThroughputRequest): Promise<void> {
|
|
||||||
if (configContext.platform !== Platform.Portal) {
|
|
||||||
throw new Error("Updating throughput beyond specified limit is not supported on this platform");
|
|
||||||
}
|
|
||||||
|
|
||||||
const resourceDescriptionInfo = request.collectionName
|
|
||||||
? `database ${request.databaseName} and container ${request.collectionName}`
|
|
||||||
: `database ${request.databaseName}`;
|
|
||||||
|
|
||||||
const clearMessage = logConsoleProgress(
|
|
||||||
`Requesting increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const url = `${configContext.BACKEND_ENDPOINT}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
|
|
||||||
const authorizationHeader = getAuthorizationHeader();
|
|
||||||
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(request),
|
|
||||||
headers: { [authorizationHeader.header]: authorizationHeader.token, [HttpHeaders.contentType]: "application/json" }
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
logConsoleInfo(
|
|
||||||
`Successfully requested an increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}`
|
|
||||||
);
|
|
||||||
clearMessage();
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const error = await response.json();
|
|
||||||
handleError(
|
|
||||||
error,
|
|
||||||
"updateOfferThroughputBeyondLimit",
|
|
||||||
`Failed to request an increase in throughput for ${request.throughput}`
|
|
||||||
);
|
|
||||||
clearMessage();
|
|
||||||
throw error;
|
|
||||||
}
|
|
@ -191,18 +191,6 @@ export interface OfferWithHeaders extends Offer {
|
|||||||
headers: any;
|
headers: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionQuotaInfo {
|
|
||||||
storedProcedures: number;
|
|
||||||
triggers: number;
|
|
||||||
functions: number;
|
|
||||||
documentsSize: number;
|
|
||||||
collectionSize: number;
|
|
||||||
documentsCount: number;
|
|
||||||
usageSizeInKB: number;
|
|
||||||
numPartitions: number;
|
|
||||||
uniqueKeyPolicy?: UniqueKeyPolicy; // TODO: This should ideally not be a part of the collection quota. Remove after refactoring. (#119617)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OfferThroughputInfo {
|
export interface OfferThroughputInfo {
|
||||||
minimumRUForCollection: number;
|
minimumRUForCollection: number;
|
||||||
numPhysicalPartitions: number;
|
numPhysicalPartitions: number;
|
||||||
|
@ -117,7 +117,6 @@ export interface Collection extends CollectionBase {
|
|||||||
analyticalStorageTtl: ko.Observable<number>;
|
analyticalStorageTtl: ko.Observable<number>;
|
||||||
indexingPolicy: ko.Observable<DataModels.IndexingPolicy>;
|
indexingPolicy: ko.Observable<DataModels.IndexingPolicy>;
|
||||||
uniqueKeyPolicy: DataModels.UniqueKeyPolicy;
|
uniqueKeyPolicy: DataModels.UniqueKeyPolicy;
|
||||||
quotaInfo: ko.Observable<DataModels.CollectionQuotaInfo>;
|
|
||||||
offer: ko.Observable<DataModels.Offer>;
|
offer: ko.Observable<DataModels.Offer>;
|
||||||
conflictResolutionPolicy: ko.Observable<DataModels.ConflictResolutionPolicy>;
|
conflictResolutionPolicy: ko.Observable<DataModels.ConflictResolutionPolicy>;
|
||||||
changeFeedPolicy: ko.Observable<DataModels.ChangeFeedPolicy>;
|
changeFeedPolicy: ko.Observable<DataModels.ChangeFeedPolicy>;
|
||||||
|
@ -1,54 +1,49 @@
|
|||||||
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
|
import { IPivotItemProps, IPivotProps, Pivot, PivotItem } from "office-ui-fabric-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
|
||||||
import * as Constants from "../../../Common/Constants";
|
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
|
||||||
import * as SharedConstants from "../../../Shared/Constants";
|
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
|
||||||
import DiscardIcon from "../../../../images/discard.svg";
|
import DiscardIcon from "../../../../images/discard.svg";
|
||||||
import SaveIcon from "../../../../images/save-cosmos.svg";
|
import SaveIcon from "../../../../images/save-cosmos.svg";
|
||||||
import { traceStart, traceFailure, traceSuccess, trace } from "../../../Shared/Telemetry/TelemetryProcessor";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
import { getIndexTransformationProgress } from "../../../Common/dataAccess/getIndexTransformationProgress";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { readMongoDBCollectionThroughRP } from "../../../Common/dataAccess/readMongoDBCollection";
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
|
|
||||||
import { updateCollection, updateMongoDBCollectionThroughRP } from "../../../Common/dataAccess/updateCollection";
|
import { updateCollection, updateMongoDBCollectionThroughRP } from "../../../Common/dataAccess/updateCollection";
|
||||||
|
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
|
||||||
|
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||||
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
|
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||||
|
import { trace, traceFailure, traceStart, traceSuccess } from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import { MongoDBCollectionResource, MongoIndex } from "../../../Utils/arm/generatedClients/2020-04-01/types";
|
||||||
|
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { userContext } from "../../../UserContext";
|
import Explorer from "../../Explorer";
|
||||||
import { updateOfferThroughputBeyondLimit } from "../../../Common/dataAccess/updateOfferThroughputBeyondLimit";
|
|
||||||
import SettingsTab from "../../Tabs/SettingsTabV2";
|
import SettingsTab from "../../Tabs/SettingsTabV2";
|
||||||
import { throughputUnit } from "./SettingsRenderUtils";
|
import "./SettingsComponent.less";
|
||||||
import { ScaleComponent, ScaleComponentProps } from "./SettingsSubComponents/ScaleComponent";
|
|
||||||
import {
|
|
||||||
MongoIndexingPolicyComponent,
|
|
||||||
MongoIndexingPolicyComponentProps
|
|
||||||
} from "./SettingsSubComponents/MongoIndexingPolicy/MongoIndexingPolicyComponent";
|
|
||||||
import {
|
|
||||||
getMaxRUs,
|
|
||||||
hasDatabaseSharedThroughput,
|
|
||||||
GeospatialConfigType,
|
|
||||||
TtlType,
|
|
||||||
ChangeFeedPolicyState,
|
|
||||||
SettingsV2TabTypes,
|
|
||||||
getTabTitle,
|
|
||||||
isDirty,
|
|
||||||
AddMongoIndexProps,
|
|
||||||
MongoIndexTypes,
|
|
||||||
parseConflictResolutionMode,
|
|
||||||
parseConflictResolutionProcedure,
|
|
||||||
getMongoNotification
|
|
||||||
} from "./SettingsUtils";
|
|
||||||
import {
|
import {
|
||||||
ConflictResolutionComponent,
|
ConflictResolutionComponent,
|
||||||
ConflictResolutionComponentProps
|
ConflictResolutionComponentProps
|
||||||
} from "./SettingsSubComponents/ConflictResolutionComponent";
|
} from "./SettingsSubComponents/ConflictResolutionComponent";
|
||||||
import { SubSettingsComponent, SubSettingsComponentProps } from "./SettingsSubComponents/SubSettingsComponent";
|
|
||||||
import { Pivot, PivotItem, IPivotProps, IPivotItemProps } from "office-ui-fabric-react";
|
|
||||||
import "./SettingsComponent.less";
|
|
||||||
import { IndexingPolicyComponent, IndexingPolicyComponentProps } from "./SettingsSubComponents/IndexingPolicyComponent";
|
import { IndexingPolicyComponent, IndexingPolicyComponentProps } from "./SettingsSubComponents/IndexingPolicyComponent";
|
||||||
import { MongoDBCollectionResource, MongoIndex } from "../../../Utils/arm/generatedClients/2020-04-01/types";
|
import {
|
||||||
import { readMongoDBCollectionThroughRP } from "../../../Common/dataAccess/readMongoDBCollection";
|
MongoIndexingPolicyComponent,
|
||||||
import { getIndexTransformationProgress } from "../../../Common/dataAccess/getIndexTransformationProgress";
|
MongoIndexingPolicyComponentProps
|
||||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
} from "./SettingsSubComponents/MongoIndexingPolicy/MongoIndexingPolicyComponent";
|
||||||
|
import { ScaleComponent, ScaleComponentProps } from "./SettingsSubComponents/ScaleComponent";
|
||||||
|
import { SubSettingsComponent, SubSettingsComponentProps } from "./SettingsSubComponents/SubSettingsComponent";
|
||||||
|
import {
|
||||||
|
AddMongoIndexProps,
|
||||||
|
ChangeFeedPolicyState,
|
||||||
|
GeospatialConfigType,
|
||||||
|
getMongoNotification,
|
||||||
|
getTabTitle,
|
||||||
|
hasDatabaseSharedThroughput,
|
||||||
|
isDirty,
|
||||||
|
MongoIndexTypes,
|
||||||
|
parseConflictResolutionMode,
|
||||||
|
parseConflictResolutionProcedure,
|
||||||
|
SettingsV2TabTypes,
|
||||||
|
TtlType
|
||||||
|
} from "./SettingsUtils";
|
||||||
|
|
||||||
interface SettingsV2TabInfo {
|
interface SettingsV2TabInfo {
|
||||||
tab: SettingsV2TabTypes;
|
tab: SettingsV2TabTypes;
|
||||||
@ -450,7 +445,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
if (this.state.isScaleSaveable) {
|
if (this.state.isScaleSaveable) {
|
||||||
const newThroughput = this.state.throughput;
|
const newThroughput = this.state.throughput;
|
||||||
const newOffer: DataModels.Offer = { ...this.collection.offer() };
|
const newOffer: DataModels.Offer = { ...this.collection.offer() };
|
||||||
const originalThroughputValue: number = this.state.throughput;
|
|
||||||
|
|
||||||
if (newOffer.content) {
|
if (newOffer.content) {
|
||||||
newOffer.content.offerThroughput = newThroughput;
|
newOffer.content.offerThroughput = newThroughput;
|
||||||
@ -488,34 +482,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
getMaxRUs(this.collection, this.container) <=
|
|
||||||
SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
newThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
this.container
|
|
||||||
) {
|
|
||||||
const requestPayload = {
|
|
||||||
subscriptionId: userContext.subscriptionId,
|
|
||||||
databaseAccountName: userContext.databaseAccount.name,
|
|
||||||
resourceGroup: userContext.resourceGroup,
|
|
||||||
databaseName: this.collection.databaseId,
|
|
||||||
collectionName: this.collection.id(),
|
|
||||||
throughput: newThroughput,
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: false
|
|
||||||
};
|
|
||||||
|
|
||||||
await updateOfferThroughputBeyondLimit(requestPayload);
|
|
||||||
this.collection.offer().content.offerThroughput = originalThroughputValue;
|
|
||||||
this.setState({
|
|
||||||
isScaleSaveable: false,
|
|
||||||
isScaleDiscardable: false,
|
|
||||||
throughput: originalThroughputValue,
|
|
||||||
throughputBaseline: originalThroughputValue,
|
|
||||||
initialNotification: {
|
|
||||||
description: `Throughput update for ${newThroughput} ${throughputUnit}`
|
|
||||||
} as DataModels.Notification
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const updateOfferParams: DataModels.UpdateOfferParams = {
|
const updateOfferParams: DataModels.UpdateOfferParams = {
|
||||||
databaseId: this.collection.databaseId,
|
databaseId: this.collection.databaseId,
|
||||||
collectionId: this.collection.id(),
|
collectionId: this.collection.id(),
|
||||||
@ -545,7 +511,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
this.container.isRefreshingExplorer(false);
|
this.container.isRefreshingExplorer(false);
|
||||||
this.setBaseline();
|
this.setBaseline();
|
||||||
this.setState({ wasAutopilotOriginallySet: this.state.isAutoPilotSelected });
|
this.setState({ wasAutopilotOriginallySet: this.state.isAutoPilotSelected });
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
|
import ko from "knockout";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ScaleComponent, ScaleComponentProps } from "./ScaleComponent";
|
|
||||||
import { container, collection } from "../TestUtils";
|
|
||||||
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
|
|
||||||
import Explorer from "../../../Explorer";
|
|
||||||
import * as Constants from "../../../../Common/Constants";
|
import * as Constants from "../../../../Common/Constants";
|
||||||
import * as DataModels from "../../../../Contracts/DataModels";
|
import * as DataModels from "../../../../Contracts/DataModels";
|
||||||
|
import Explorer from "../../../Explorer";
|
||||||
import { throughputUnit } from "../SettingsRenderUtils";
|
import { throughputUnit } from "../SettingsRenderUtils";
|
||||||
import * as SharedConstants from "../../../../Shared/Constants";
|
import { collection, container } from "../TestUtils";
|
||||||
import ko from "knockout";
|
import { ScaleComponent, ScaleComponentProps } from "./ScaleComponent";
|
||||||
|
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
|
||||||
|
|
||||||
describe("ScaleComponent", () => {
|
describe("ScaleComponent", () => {
|
||||||
const nonNationalCloudContainer = new Explorer();
|
const nonNationalCloudContainer = new Explorer();
|
||||||
@ -48,9 +47,7 @@ describe("ScaleComponent", () => {
|
|||||||
let wrapper = shallow(<ScaleComponent {...baseProps} />);
|
let wrapper = shallow(<ScaleComponent {...baseProps} />);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
expect(wrapper.exists(ThroughputInputAutoPilotV3Component)).toEqual(true);
|
expect(wrapper.exists(ThroughputInputAutoPilotV3Component)).toEqual(true);
|
||||||
expect(wrapper.exists("#throughputApplyLongDelayMessage")).toEqual(true);
|
|
||||||
expect(wrapper.exists("#throughputApplyShortDelayMessage")).toEqual(false);
|
expect(wrapper.exists("#throughputApplyShortDelayMessage")).toEqual(false);
|
||||||
expect(wrapper.find("#throughputApplyLongDelayMessage").html()).toContain(targetThroughput);
|
|
||||||
|
|
||||||
const newCollection = { ...collection };
|
const newCollection = { ...collection };
|
||||||
const maxThroughput = 5000;
|
const maxThroughput = 5000;
|
||||||
@ -109,11 +106,6 @@ describe("ScaleComponent", () => {
|
|||||||
expect(scaleComponent.isAutoScaleEnabled()).toEqual(true);
|
expect(scaleComponent.isAutoScaleEnabled()).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("getMaxRUThroughputInputLimit", () => {
|
|
||||||
const scaleComponent = new ScaleComponent(baseProps);
|
|
||||||
expect(scaleComponent.getMaxRUThroughputInputLimit()).toEqual(40000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("getThroughputTitle", () => {
|
it("getThroughputTitle", () => {
|
||||||
let scaleComponent = new ScaleComponent(baseProps);
|
let scaleComponent = new ScaleComponent(baseProps);
|
||||||
expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (6,000 - unlimited RU/s)");
|
expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (6,000 - unlimited RU/s)");
|
||||||
@ -126,26 +118,4 @@ describe("ScaleComponent", () => {
|
|||||||
scaleComponent = new ScaleComponent(newProps);
|
scaleComponent = new ScaleComponent(newProps);
|
||||||
expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (autoscale)");
|
expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (autoscale)");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("canThroughputExceedMaximumValue", () => {
|
|
||||||
let scaleComponent = new ScaleComponent(baseProps);
|
|
||||||
expect(scaleComponent.canThroughputExceedMaximumValue()).toEqual(true);
|
|
||||||
|
|
||||||
const newProps = { ...baseProps, container: nonNationalCloudContainer };
|
|
||||||
scaleComponent = new ScaleComponent(newProps);
|
|
||||||
expect(scaleComponent.canThroughputExceedMaximumValue()).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("getThroughputWarningMessage", () => {
|
|
||||||
const throughputBeyondLimit = SharedConstants.CollectionCreation.DefaultCollectionRUs1Million + 1000;
|
|
||||||
const throughputBeyondMaxRus = SharedConstants.CollectionCreation.DefaultCollectionRUs1Million - 1000;
|
|
||||||
|
|
||||||
const newProps = { ...baseProps, container: nonNationalCloudContainer, throughput: throughputBeyondLimit };
|
|
||||||
let scaleComponent = new ScaleComponent(newProps);
|
|
||||||
expect(scaleComponent.getThroughputWarningMessage().props.id).toEqual("updateThroughputBeyondLimitWarningMessage");
|
|
||||||
|
|
||||||
newProps.throughput = throughputBeyondMaxRus;
|
|
||||||
scaleComponent = new ScaleComponent(newProps);
|
|
||||||
expect(scaleComponent.getThroughputWarningMessage().props.id).toEqual("updateThroughputDelayedApplyWarningMessage");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
|
import { Label, MessageBar, MessageBarType, Stack, Text, TextField } from "office-ui-fabric-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as Constants from "../../../../Common/Constants";
|
import * as Constants from "../../../../Common/Constants";
|
||||||
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
|
import { configContext, Platform } from "../../../../ConfigContext";
|
||||||
import * as ViewModels from "../../../../Contracts/ViewModels";
|
|
||||||
import * as DataModels from "../../../../Contracts/DataModels";
|
import * as DataModels from "../../../../Contracts/DataModels";
|
||||||
import * as SharedConstants from "../../../../Shared/Constants";
|
import * as ViewModels from "../../../../Contracts/ViewModels";
|
||||||
|
import * as AutoPilotUtils from "../../../../Utils/AutoPilotUtils";
|
||||||
import Explorer from "../../../Explorer";
|
import Explorer from "../../../Explorer";
|
||||||
import {
|
import {
|
||||||
getTextFieldStyles,
|
getTextFieldStyles,
|
||||||
subComponentStackProps,
|
|
||||||
titleAndInputStackProps,
|
|
||||||
throughputUnit,
|
|
||||||
getThroughputApplyLongDelayMessage,
|
|
||||||
getThroughputApplyShortDelayMessage,
|
getThroughputApplyShortDelayMessage,
|
||||||
updateThroughputBeyondLimitWarningMessage,
|
subComponentStackProps,
|
||||||
updateThroughputDelayedApplyWarningMessage
|
throughputUnit,
|
||||||
|
titleAndInputStackProps
|
||||||
} from "../SettingsRenderUtils";
|
} from "../SettingsRenderUtils";
|
||||||
import { getMaxRUs, getMinRUs, hasDatabaseSharedThroughput } from "../SettingsUtils";
|
import { getMinRUs, hasDatabaseSharedThroughput } from "../SettingsUtils";
|
||||||
import * as AutoPilotUtils from "../../../../Utils/AutoPilotUtils";
|
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
|
||||||
import { Text, TextField, Stack, Label, MessageBar, MessageBarType } from "office-ui-fabric-react";
|
|
||||||
import { configContext, Platform } from "../../../../ConfigContext";
|
|
||||||
|
|
||||||
export interface ScaleComponentProps {
|
export interface ScaleComponentProps {
|
||||||
collection: ViewModels.Collection;
|
collection: ViewModels.Collection;
|
||||||
@ -75,40 +71,17 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public getMaxRUThroughputInputLimit = (): number => {
|
|
||||||
if (configContext.platform === Platform.Hosted && this.props.collection.partitionKey) {
|
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getMaxRUs(this.props.collection, this.props.container);
|
|
||||||
};
|
|
||||||
|
|
||||||
public getThroughputTitle = (): string => {
|
public getThroughputTitle = (): string => {
|
||||||
if (this.props.isAutoPilotSelected) {
|
if (this.props.isAutoPilotSelected) {
|
||||||
return AutoPilotUtils.getAutoPilotHeaderText();
|
return AutoPilotUtils.getAutoPilotHeaderText();
|
||||||
}
|
}
|
||||||
|
|
||||||
const minThroughput: string = getMinRUs(this.props.collection, this.props.container).toLocaleString();
|
const minThroughput: string = getMinRUs(this.props.collection, this.props.container).toLocaleString();
|
||||||
const maxThroughput: string =
|
const maxThroughput: string = !this.props.isFixedContainer ? "unlimited" : "10000";
|
||||||
this.canThroughputExceedMaximumValue() && !this.props.isFixedContainer
|
|
||||||
? "unlimited"
|
|
||||||
: getMaxRUs(this.props.collection, this.props.container).toLocaleString();
|
|
||||||
return `Throughput (${minThroughput} - ${maxThroughput} RU/s)`;
|
return `Throughput (${minThroughput} - ${maxThroughput} RU/s)`;
|
||||||
};
|
};
|
||||||
|
|
||||||
public canThroughputExceedMaximumValue = (): boolean => {
|
|
||||||
return (
|
|
||||||
!this.props.isFixedContainer &&
|
|
||||||
configContext.platform === Platform.Portal &&
|
|
||||||
!this.props.container.isRunningOnNationalCloud()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
public getInitialNotificationElement = (): JSX.Element => {
|
public getInitialNotificationElement = (): JSX.Element => {
|
||||||
if (this.props.initialNotification) {
|
|
||||||
return this.getLongDelayMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
const offer = this.props.collection?.offer && this.props.collection.offer();
|
const offer = this.props.collection?.offer && this.props.collection.offer();
|
||||||
if (
|
if (
|
||||||
offer &&
|
offer &&
|
||||||
@ -135,47 +108,6 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
public getThroughputWarningMessage = (): JSX.Element => {
|
|
||||||
const throughputExceedsBackendLimits: boolean =
|
|
||||||
this.canThroughputExceedMaximumValue() &&
|
|
||||||
getMaxRUs(this.props.collection, this.props.container) <=
|
|
||||||
SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
this.props.throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
|
|
||||||
if (throughputExceedsBackendLimits && !!this.props.collection.partitionKey && !this.props.isFixedContainer) {
|
|
||||||
return updateThroughputBeyondLimitWarningMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
const throughputExceedsMaxValue: boolean =
|
|
||||||
!this.isEmulator && this.props.throughput > getMaxRUs(this.props.collection, this.props.container);
|
|
||||||
|
|
||||||
if (throughputExceedsMaxValue && !!this.props.collection.partitionKey && !this.props.isFixedContainer) {
|
|
||||||
return updateThroughputDelayedApplyWarningMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
public getLongDelayMessage = (): JSX.Element => {
|
|
||||||
const matches: string[] = this.props.initialNotification?.description.match(
|
|
||||||
`Throughput update for (.*) ${throughputUnit}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const throughput = this.props.throughputBaseline;
|
|
||||||
const targetThroughput: number = matches.length > 1 && Number(matches[1]);
|
|
||||||
if (targetThroughput) {
|
|
||||||
return getThroughputApplyLongDelayMessage(
|
|
||||||
this.props.wasAutopilotOriginallySet,
|
|
||||||
throughput,
|
|
||||||
throughputUnit,
|
|
||||||
this.props.collection.databaseId,
|
|
||||||
this.props.collection.id(),
|
|
||||||
targetThroughput
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
|
|
||||||
private getThroughputInputComponent = (): JSX.Element => (
|
private getThroughputInputComponent = (): JSX.Element => (
|
||||||
<ThroughputInputAutoPilotV3Component
|
<ThroughputInputAutoPilotV3Component
|
||||||
databaseAccount={this.props.container.databaseAccount()}
|
databaseAccount={this.props.container.databaseAccount()}
|
||||||
@ -184,9 +116,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
throughputBaseline={this.props.throughputBaseline}
|
throughputBaseline={this.props.throughputBaseline}
|
||||||
onThroughputChange={this.props.onThroughputChange}
|
onThroughputChange={this.props.onThroughputChange}
|
||||||
minimum={getMinRUs(this.props.collection, this.props.container)}
|
minimum={getMinRUs(this.props.collection, this.props.container)}
|
||||||
maximum={this.getMaxRUThroughputInputLimit()}
|
|
||||||
isEnabled={!hasDatabaseSharedThroughput(this.props.collection)}
|
isEnabled={!hasDatabaseSharedThroughput(this.props.collection)}
|
||||||
canExceedMaximumValue={this.canThroughputExceedMaximumValue()}
|
|
||||||
label={this.getThroughputTitle()}
|
label={this.getThroughputTitle()}
|
||||||
isEmulator={this.isEmulator}
|
isEmulator={this.isEmulator}
|
||||||
isFixed={this.props.isFixedContainer}
|
isFixed={this.props.isFixedContainer}
|
||||||
@ -199,7 +129,6 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
spendAckChecked={false}
|
spendAckChecked={false}
|
||||||
onScaleSaveableChange={this.props.onScaleSaveableChange}
|
onScaleSaveableChange={this.props.onScaleSaveableChange}
|
||||||
onScaleDiscardableChange={this.props.onScaleDiscardableChange}
|
onScaleDiscardableChange={this.props.onScaleDiscardableChange}
|
||||||
getThroughputWarningMessage={this.getThroughputWarningMessage}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ describe("ThroughputInputAutoPilotV3Component", () => {
|
|||||||
throughputBaseline: 100,
|
throughputBaseline: 100,
|
||||||
onThroughputChange: undefined,
|
onThroughputChange: undefined,
|
||||||
minimum: 10000,
|
minimum: 10000,
|
||||||
maximum: 400,
|
|
||||||
step: 100,
|
step: 100,
|
||||||
isEnabled: true,
|
isEnabled: true,
|
||||||
isEmulator: false,
|
isEmulator: false,
|
||||||
@ -38,8 +37,7 @@ describe("ThroughputInputAutoPilotV3Component", () => {
|
|||||||
},
|
},
|
||||||
onScaleDiscardableChange: () => {
|
onScaleDiscardableChange: () => {
|
||||||
return;
|
return;
|
||||||
},
|
}
|
||||||
getThroughputWarningMessage: () => undefined
|
|
||||||
};
|
};
|
||||||
|
|
||||||
it("throughput input visible", () => {
|
it("throughput input visible", () => {
|
||||||
|
@ -1,35 +1,33 @@
|
|||||||
import React from "react";
|
|
||||||
import * as AutoPilotUtils from "../../../../../Utils/AutoPilotUtils";
|
|
||||||
import {
|
import {
|
||||||
getTextFieldStyles,
|
Checkbox,
|
||||||
getToolTipContainer,
|
|
||||||
noLeftPaddingCheckBoxStyle,
|
|
||||||
titleAndInputStackProps,
|
|
||||||
checkBoxAndInputStackProps,
|
|
||||||
getChoiceGroupStyles,
|
|
||||||
messageBarStyles,
|
|
||||||
getEstimatedSpendElement,
|
|
||||||
getEstimatedAutoscaleSpendElement,
|
|
||||||
getAutoPilotV3SpendElement,
|
|
||||||
manualToAutoscaleDisclaimerElement
|
|
||||||
} from "../../SettingsRenderUtils";
|
|
||||||
import {
|
|
||||||
Text,
|
|
||||||
TextField,
|
|
||||||
ChoiceGroup,
|
ChoiceGroup,
|
||||||
IChoiceGroupOption,
|
IChoiceGroupOption,
|
||||||
Checkbox,
|
|
||||||
Stack,
|
|
||||||
Label,
|
Label,
|
||||||
Link,
|
Link,
|
||||||
MessageBar,
|
MessageBar,
|
||||||
MessageBarType
|
MessageBarType,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
TextField
|
||||||
} from "office-ui-fabric-react";
|
} from "office-ui-fabric-react";
|
||||||
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
import React from "react";
|
||||||
import { getSanitizedInputValue, IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
|
|
||||||
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";
|
import * as AutoPilotUtils from "../../../../../Utils/AutoPilotUtils";
|
||||||
|
import {
|
||||||
|
checkBoxAndInputStackProps,
|
||||||
|
getAutoPilotV3SpendElement,
|
||||||
|
getChoiceGroupStyles,
|
||||||
|
getEstimatedAutoscaleSpendElement,
|
||||||
|
getEstimatedSpendElement,
|
||||||
|
getTextFieldStyles,
|
||||||
|
getToolTipContainer,
|
||||||
|
manualToAutoscaleDisclaimerElement,
|
||||||
|
messageBarStyles,
|
||||||
|
noLeftPaddingCheckBoxStyle,
|
||||||
|
titleAndInputStackProps
|
||||||
|
} from "../../SettingsRenderUtils";
|
||||||
|
import { getSanitizedInputValue, IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
|
||||||
|
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
||||||
|
|
||||||
export interface ThroughputInputAutoPilotV3Props {
|
export interface ThroughputInputAutoPilotV3Props {
|
||||||
databaseAccount: DataModels.DatabaseAccount;
|
databaseAccount: DataModels.DatabaseAccount;
|
||||||
@ -38,7 +36,6 @@ export interface ThroughputInputAutoPilotV3Props {
|
|||||||
throughputBaseline: number;
|
throughputBaseline: number;
|
||||||
onThroughputChange: (newThroughput: number) => void;
|
onThroughputChange: (newThroughput: number) => void;
|
||||||
minimum: number;
|
minimum: number;
|
||||||
maximum: number;
|
|
||||||
step?: number;
|
step?: number;
|
||||||
isEnabled?: boolean;
|
isEnabled?: boolean;
|
||||||
spendAckChecked?: boolean;
|
spendAckChecked?: boolean;
|
||||||
@ -59,7 +56,6 @@ export interface ThroughputInputAutoPilotV3Props {
|
|||||||
onMaxAutoPilotThroughputChange: (newThroughput: number) => void;
|
onMaxAutoPilotThroughputChange: (newThroughput: number) => void;
|
||||||
onScaleSaveableChange: (isScaleSaveable: boolean) => void;
|
onScaleSaveableChange: (isScaleSaveable: boolean) => void;
|
||||||
onScaleDiscardableChange: (isScaleDiscardable: boolean) => void;
|
onScaleDiscardableChange: (isScaleDiscardable: boolean) => void;
|
||||||
getThroughputWarningMessage: () => JSX.Element;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ThroughputInputAutoPilotV3State {
|
interface ThroughputInputAutoPilotV3State {
|
||||||
@ -119,13 +115,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
if (isDirty(this.props.throughput, this.props.throughputBaseline)) {
|
if (isDirty(this.props.throughput, this.props.throughputBaseline)) {
|
||||||
isDiscardable = true;
|
isDiscardable = true;
|
||||||
isSaveable = true;
|
isSaveable = true;
|
||||||
if (
|
if (!this.props.throughput || this.props.throughput < this.props.minimum) {
|
||||||
!this.props.throughput ||
|
|
||||||
this.props.throughput < this.props.minimum ||
|
|
||||||
(this.props.throughput > this.props.maximum && (this.props.isEmulator || this.props.isFixed)) ||
|
|
||||||
(this.props.throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
!this.props.canExceedMaximumValue)
|
|
||||||
) {
|
|
||||||
isSaveable = false;
|
isSaveable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,8 +131,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.throughputInputMaxValue = Number.MAX_SAFE_INTEGER;
|
||||||
this.autoPilotInputMaxValue = this.props.isFixed ? this.props.maximum : Int32.Max;
|
this.autoPilotInputMaxValue = Number.MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasProvisioningTypeChanged = (): boolean =>
|
public hasProvisioningTypeChanged = (): boolean =>
|
||||||
@ -306,12 +296,6 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
onChange={this.onThroughputChange}
|
onChange={this.onThroughputChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{this.props.getThroughputWarningMessage() && (
|
|
||||||
<MessageBar messageBarType={MessageBarType.warning} styles={messageBarStyles}>
|
|
||||||
{this.props.getThroughputWarningMessage()}
|
|
||||||
</MessageBar>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!this.props.isEmulator && this.getRequestUnitsUsageCost()}
|
{!this.props.isEmulator && this.getRequestUnitsUsageCost()}
|
||||||
|
|
||||||
{this.props.spendAckVisible && (
|
{this.props.spendAckVisible && (
|
||||||
|
@ -8,29 +8,6 @@ exports[`ScaleComponent renders with correct intiial notification 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<StyledMessageBarBase
|
|
||||||
messageBarType={5}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
id="throughputApplyLongDelayMessage"
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"fontSize": 12,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
A request to increase the throughput is currently in progress. This operation will take 1-3 business days to complete. View the latest status in Notifications.
|
|
||||||
<br />
|
|
||||||
Database:
|
|
||||||
test
|
|
||||||
, Container:
|
|
||||||
test
|
|
||||||
|
|
||||||
, Current autoscale throughput: 100 - 1000 RU/s, Target autoscale throughput: 600 - 6000 RU/s
|
|
||||||
</Text>
|
|
||||||
</StyledMessageBarBase>
|
|
||||||
<Stack
|
<Stack
|
||||||
tokens={
|
tokens={
|
||||||
Object {
|
Object {
|
||||||
@ -39,8 +16,6 @@ exports[`ScaleComponent renders with correct intiial notification 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ThroughputInputAutoPilotV3Component
|
<ThroughputInputAutoPilotV3Component
|
||||||
canExceedMaximumValue={true}
|
|
||||||
getThroughputWarningMessage={[Function]}
|
|
||||||
isAutoPilotSelected={false}
|
isAutoPilotSelected={false}
|
||||||
isEmulator={false}
|
isEmulator={false}
|
||||||
isEnabled={true}
|
isEnabled={true}
|
||||||
@ -48,7 +23,6 @@ exports[`ScaleComponent renders with correct intiial notification 1`] = `
|
|||||||
label="Throughput (6,000 - unlimited RU/s)"
|
label="Throughput (6,000 - unlimited RU/s)"
|
||||||
maxAutoPilotThroughput={4000}
|
maxAutoPilotThroughput={4000}
|
||||||
maxAutoPilotThroughputBaseline={4000}
|
maxAutoPilotThroughputBaseline={4000}
|
||||||
maximum={40000}
|
|
||||||
minimum={6000}
|
minimum={6000}
|
||||||
onAutoPilotSelected={[Function]}
|
onAutoPilotSelected={[Function]}
|
||||||
onMaxAutoPilotThroughputChange={[Function]}
|
onMaxAutoPilotThroughputChange={[Function]}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { collection, container } from "./TestUtils";
|
import { collection, container } from "./TestUtils";
|
||||||
import {
|
import {
|
||||||
getMaxRUs,
|
|
||||||
getMinRUs,
|
getMinRUs,
|
||||||
getMongoIndexType,
|
getMongoIndexType,
|
||||||
getMongoNotification,
|
getMongoNotification,
|
||||||
@ -23,11 +22,6 @@ import * as ViewModels from "../../../Contracts/ViewModels";
|
|||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
|
|
||||||
describe("SettingsUtils", () => {
|
describe("SettingsUtils", () => {
|
||||||
it("getMaxRUs", () => {
|
|
||||||
expect(collection.offer().content.collectionThroughputInfo.numPhysicalPartitions).toEqual(4);
|
|
||||||
expect(getMaxRUs(collection, container)).toEqual(40000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("getMinRUs", () => {
|
it("getMinRUs", () => {
|
||||||
expect(collection.offer().content.collectionThroughputInfo.numPhysicalPartitions).toEqual(4);
|
expect(collection.offer().content.collectionThroughputInfo.numPhysicalPartitions).toEqual(4);
|
||||||
expect(getMinRUs(collection, container)).toEqual(6000);
|
expect(getMinRUs(collection, container)).toEqual(6000);
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import * as SharedConstants from "../../../Shared/Constants";
|
import * as SharedConstants from "../../../Shared/Constants";
|
||||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
|
||||||
|
|
||||||
import Explorer from "../../Explorer";
|
|
||||||
import { MongoIndex } from "../../../Utils/arm/generatedClients/2020-04-01/types";
|
import { MongoIndex } from "../../../Utils/arm/generatedClients/2020-04-01/types";
|
||||||
|
import Explorer from "../../Explorer";
|
||||||
|
|
||||||
const zeroValue = 0;
|
const zeroValue = 0;
|
||||||
export type isDirtyTypes = boolean | string | number | DataModels.IndexingPolicy;
|
export type isDirtyTypes = boolean | string | number | DataModels.IndexingPolicy;
|
||||||
@ -71,22 +69,6 @@ export const hasDatabaseSharedThroughput = (collection: ViewModels.Collection):
|
|||||||
return database?.isDatabaseShared() && !collection.offer();
|
return database?.isDatabaseShared() && !collection.offer();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMaxRUs = (collection: ViewModels.Collection, container: Explorer): number => {
|
|
||||||
const isTryCosmosDBSubscription = container?.isTryCosmosDBSubscription() || false;
|
|
||||||
if (isTryCosmosDBSubscription) {
|
|
||||||
return Constants.TryCosmosExperience.maxRU;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numPartitionsFromOffer: number =
|
|
||||||
collection?.offer && collection.offer()?.content?.collectionThroughputInfo?.numPhysicalPartitions;
|
|
||||||
|
|
||||||
const numPartitionsFromQuotaInfo: number = collection?.quotaInfo()?.numPartitions;
|
|
||||||
|
|
||||||
const numPartitions = numPartitionsFromOffer ?? numPartitionsFromQuotaInfo ?? 1;
|
|
||||||
|
|
||||||
return SharedConstants.CollectionCreation.MaxRUPerPartition * numPartitions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getMinRUs = (collection: ViewModels.Collection, container: Explorer): number => {
|
export const getMinRUs = (collection: ViewModels.Collection, container: Explorer): number => {
|
||||||
const isTryCosmosDBSubscription = container?.isTryCosmosDBSubscription();
|
const isTryCosmosDBSubscription = container?.isTryCosmosDBSubscription();
|
||||||
if (isTryCosmosDBSubscription) {
|
if (isTryCosmosDBSubscription) {
|
||||||
@ -105,21 +87,7 @@ export const getMinRUs = (collection: ViewModels.Collection, container: Explorer
|
|||||||
return collectionThroughputInfo.minimumRUForCollection;
|
return collectionThroughputInfo.minimumRUForCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numPartitions = collectionThroughputInfo?.numPhysicalPartitions ?? collection.quotaInfo()?.numPartitions;
|
|
||||||
|
|
||||||
if (!numPartitions || numPartitions === 1) {
|
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
}
|
|
||||||
|
|
||||||
const baseRU = SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
|
||||||
|
|
||||||
const quotaInKb = collection.quotaInfo().collectionSize;
|
|
||||||
const quotaInGb = PricingUtils.usageInGB(quotaInKb);
|
|
||||||
|
|
||||||
const perPartitionGBQuota: number = Math.max(10, quotaInGb / numPartitions);
|
|
||||||
const baseRUbyPartitions: number = ((numPartitions * perPartitionGBQuota) / 10) * 100;
|
|
||||||
|
|
||||||
return Math.max(baseRU, baseRUbyPartitions);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseConflictResolutionMode = (modeFromBackend: string): DataModels.ConflictResolutionMode => {
|
export const parseConflictResolutionMode = (modeFromBackend: string): DataModels.ConflictResolutionMode => {
|
||||||
|
@ -18,7 +18,6 @@ export const collection = ({
|
|||||||
excludedPaths: []
|
excludedPaths: []
|
||||||
}),
|
}),
|
||||||
uniqueKeyPolicy: {} as DataModels.UniqueKeyPolicy,
|
uniqueKeyPolicy: {} as DataModels.UniqueKeyPolicy,
|
||||||
quotaInfo: ko.observable<DataModels.CollectionQuotaInfo>({} as DataModels.CollectionQuotaInfo),
|
|
||||||
offer: ko.observable<DataModels.Offer>({
|
offer: ko.observable<DataModels.Offer>({
|
||||||
content: {
|
content: {
|
||||||
offerThroughput: 10000,
|
offerThroughput: 10000,
|
||||||
|
@ -43,7 +43,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -86,7 +85,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -349,7 +347,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -575,7 +572,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -657,7 +653,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -760,7 +755,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -1301,7 +1295,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"version": 2,
|
"version": 2,
|
||||||
},
|
},
|
||||||
"partitionKeyProperty": "partitionKey",
|
"partitionKeyProperty": "partitionKey",
|
||||||
"quotaInfo": [Function],
|
|
||||||
"readSettings": [Function],
|
"readSettings": [Function],
|
||||||
"uniqueKeyPolicy": Object {},
|
"uniqueKeyPolicy": Object {},
|
||||||
}
|
}
|
||||||
@ -1323,7 +1316,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -1366,7 +1358,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -1629,7 +1620,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -1855,7 +1845,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -1937,7 +1926,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -2040,7 +2028,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -2616,7 +2603,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -2659,7 +2645,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -2922,7 +2907,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -3148,7 +3132,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -3230,7 +3213,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -3333,7 +3315,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -3874,7 +3855,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"version": 2,
|
"version": 2,
|
||||||
},
|
},
|
||||||
"partitionKeyProperty": "partitionKey",
|
"partitionKeyProperty": "partitionKey",
|
||||||
"quotaInfo": [Function],
|
|
||||||
"readSettings": [Function],
|
"readSettings": [Function],
|
||||||
"uniqueKeyPolicy": Object {},
|
"uniqueKeyPolicy": Object {},
|
||||||
}
|
}
|
||||||
@ -3896,7 +3876,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -3939,7 +3918,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -4202,7 +4180,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
@ -4428,7 +4405,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"collectionId": [Function],
|
"collectionId": [Function],
|
||||||
"collectionIdTitle": [Function],
|
"collectionIdTitle": [Function],
|
||||||
"collectionWithThroughputInShared": [Function],
|
"collectionWithThroughputInShared": [Function],
|
||||||
@ -4510,7 +4486,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"databaseCreateNewShared": [Function],
|
"databaseCreateNewShared": [Function],
|
||||||
@ -4613,7 +4588,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
"autoPilotUsageCost": [Function],
|
"autoPilotUsageCost": [Function],
|
||||||
"canConfigureThroughput": [Function],
|
"canConfigureThroughput": [Function],
|
||||||
"canExceedMaximumValue": [Function],
|
"canExceedMaximumValue": [Function],
|
||||||
"canRequestSupport": [Function],
|
|
||||||
"container": [Circular],
|
"container": [Circular],
|
||||||
"costsVisible": [Function],
|
"costsVisible": [Function],
|
||||||
"createTableQuery": [Function],
|
"createTableQuery": [Function],
|
||||||
|
@ -61,7 +61,6 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
public maxCollectionsReachedMessage: ko.Observable<string>;
|
public maxCollectionsReachedMessage: ko.Observable<string>;
|
||||||
public requestUnitsUsageCost: ko.Computed<string>;
|
public requestUnitsUsageCost: ko.Computed<string>;
|
||||||
public dedicatedRequestUnitsUsageCost: ko.Computed<string>;
|
public dedicatedRequestUnitsUsageCost: ko.Computed<string>;
|
||||||
public canRequestSupport: ko.PureComputed<boolean>;
|
|
||||||
public largePartitionKey: ko.Observable<boolean> = ko.observable<boolean>(false);
|
public largePartitionKey: ko.Observable<boolean> = ko.observable<boolean>(false);
|
||||||
public useIndexingForSharedThroughput: ko.Observable<boolean> = ko.observable<boolean>(true);
|
public useIndexingForSharedThroughput: ko.Observable<boolean> = ko.observable<boolean>(true);
|
||||||
public costsVisible: ko.PureComputed<boolean>;
|
public costsVisible: ko.PureComputed<boolean>;
|
||||||
@ -314,19 +313,6 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (
|
|
||||||
configContext.platform !== Platform.Emulator &&
|
|
||||||
!this.container.isTryCosmosDBSubscription() &&
|
|
||||||
configContext.platform !== Platform.Portal
|
|
||||||
) {
|
|
||||||
const offerThroughput: number = this._getThroughput();
|
|
||||||
return offerThroughput <= 100000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.costsVisible = ko.pureComputed(() => {
|
this.costsVisible = ko.pureComputed(() => {
|
||||||
return configContext.platform !== Platform.Emulator;
|
return configContext.platform !== Platform.Emulator;
|
||||||
});
|
});
|
||||||
|
@ -117,10 +117,6 @@
|
|||||||
showAutoPilot: !isFreeTierAccount()
|
showAutoPilot: !isFreeTierAccount()
|
||||||
}">
|
}">
|
||||||
</throughput-input-autopilot-v3>
|
</throughput-input-autopilot-v3>
|
||||||
<p data-bind="visible: canRequestSupport">
|
|
||||||
<!-- TODO: Replace link with call to the Azure Support blade --><a
|
|
||||||
href="https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20More%20Throughput%20Request">Contact
|
|
||||||
support</a> for more than <span data-bind="text: maxThroughputRUText"></span> RU/s.</p>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
<!-- Database provisioned throughput - End -->
|
<!-- Database provisioned throughput - End -->
|
||||||
|
@ -31,7 +31,6 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
public throughputSpendAck: ko.Observable<boolean>;
|
public throughputSpendAck: ko.Observable<boolean>;
|
||||||
public throughputSpendAckVisible: ko.Computed<boolean>;
|
public throughputSpendAckVisible: ko.Computed<boolean>;
|
||||||
public requestUnitsUsageCost: ko.Computed<string>;
|
public requestUnitsUsageCost: ko.Computed<string>;
|
||||||
public canRequestSupport: ko.PureComputed<boolean>;
|
|
||||||
public costsVisible: ko.PureComputed<boolean>;
|
public costsVisible: ko.PureComputed<boolean>;
|
||||||
public upsellMessage: ko.PureComputed<string>;
|
public upsellMessage: ko.PureComputed<string>;
|
||||||
public upsellMessageAriaLabel: ko.PureComputed<string>;
|
public upsellMessageAriaLabel: ko.PureComputed<string>;
|
||||||
@ -168,19 +167,6 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
return estimatedSpend;
|
return estimatedSpend;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (
|
|
||||||
configContext.platform !== Platform.Emulator &&
|
|
||||||
!this.container.isTryCosmosDBSubscription() &&
|
|
||||||
configContext.platform !== Platform.Portal
|
|
||||||
) {
|
|
||||||
const offerThroughput: number = this.throughput();
|
|
||||||
return offerThroughput <= 100000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.isFreeTierAccount = ko.computed<boolean>(() => {
|
this.isFreeTierAccount = ko.computed<boolean>(() => {
|
||||||
const databaseAccount = this.container && this.container.databaseAccount && this.container.databaseAccount();
|
const databaseAccount = this.container && this.container.databaseAccount && this.container.databaseAccount();
|
||||||
const isFreeTierAccount =
|
const isFreeTierAccount =
|
||||||
|
@ -33,7 +33,6 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
|
|||||||
public keyspaceThroughput: ko.Observable<number>;
|
public keyspaceThroughput: ko.Observable<number>;
|
||||||
public keyspaceCreateNew: ko.Observable<boolean>;
|
public keyspaceCreateNew: ko.Observable<boolean>;
|
||||||
public dedicateTableThroughput: ko.Observable<boolean>;
|
public dedicateTableThroughput: ko.Observable<boolean>;
|
||||||
public canRequestSupport: ko.PureComputed<boolean>;
|
|
||||||
public throughputSpendAckText: ko.Observable<string>;
|
public throughputSpendAckText: ko.Observable<string>;
|
||||||
public throughputSpendAck: ko.Observable<boolean>;
|
public throughputSpendAck: ko.Observable<boolean>;
|
||||||
public sharedThroughputSpendAck: ko.Observable<boolean>;
|
public sharedThroughputSpendAck: ko.Observable<boolean>;
|
||||||
@ -228,15 +227,6 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
|
|||||||
return configContext.platform !== Platform.Emulator;
|
return configContext.platform !== Platform.Emulator;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (configContext.platform !== Platform.Emulator && !this.container.isTryCosmosDBSubscription()) {
|
|
||||||
const offerThroughput: number = this.throughput();
|
|
||||||
return offerThroughput <= 100000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sharedThroughputSpendAckVisible = ko.computed<boolean>(() => {
|
this.sharedThroughputSpendAckVisible = ko.computed<boolean>(() => {
|
||||||
const autoscaleThroughput = this.sharedAutoPilotThroughput() * 1;
|
const autoscaleThroughput = this.sharedAutoPilotThroughput() * 1;
|
||||||
if (this.isSharedAutoPilotSelected()) {
|
if (this.isSharedAutoPilotSelected()) {
|
||||||
|
@ -3,11 +3,6 @@ export var Int32 = {
|
|||||||
Max: 2147483647
|
Max: 2147483647
|
||||||
};
|
};
|
||||||
|
|
||||||
export var Int64 = {
|
|
||||||
Min: -9223372036854775808,
|
|
||||||
Max: 9223372036854775807
|
|
||||||
};
|
|
||||||
|
|
||||||
var yearMonthDay = "\\d{4}[- ][01]\\d[- ][0-3]\\d";
|
var yearMonthDay = "\\d{4}[- ][01]\\d[- ][0-3]\\d";
|
||||||
var timeOfDay = "T[0-2]\\d:[0-5]\\d(:[0-5]\\d(\\.\\d+)?)?";
|
var timeOfDay = "T[0-2]\\d:[0-5]\\d(:[0-5]\\d(\\.\\d+)?)?";
|
||||||
var timeZone = "Z|[+-][0-2]\\d:[0-5]\\d";
|
var timeZone = "Z|[+-][0-2]\\d:[0-5]\\d";
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
class: 'scaleForm dirty',
|
class: 'scaleForm dirty',
|
||||||
value: throughput,
|
value: throughput,
|
||||||
minimum: minRUs,
|
minimum: minRUs,
|
||||||
maximum: maxRUThroughputInputLimit,
|
|
||||||
canExceedMaximumValue: canThroughputExceedMaximumValue,
|
canExceedMaximumValue: canThroughputExceedMaximumValue,
|
||||||
step: throughputIncreaseFactor,
|
step: throughputIncreaseFactor,
|
||||||
label: throughputTitle,
|
label: throughputTitle,
|
||||||
|
@ -17,7 +17,6 @@ import Explorer from "../Explorer";
|
|||||||
import { updateOffer } from "../../Common/dataAccess/updateOffer";
|
import { updateOffer } from "../../Common/dataAccess/updateOffer";
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
|
|
||||||
import { configContext, Platform } from "../../ConfigContext";
|
import { configContext, Platform } from "../../ConfigContext";
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||||
|
|
||||||
@ -59,9 +58,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
|
|
||||||
public saveSettingsButton: ViewModels.Button;
|
public saveSettingsButton: ViewModels.Button;
|
||||||
public discardSettingsChangesButton: ViewModels.Button;
|
public discardSettingsChangesButton: ViewModels.Button;
|
||||||
|
|
||||||
public canRequestSupport: ko.PureComputed<boolean>;
|
|
||||||
public canThroughputExceedMaximumValue: ko.Computed<boolean>;
|
|
||||||
public costsVisible: ko.Computed<boolean>;
|
public costsVisible: ko.Computed<boolean>;
|
||||||
public displayedError: ko.Observable<string>;
|
public displayedError: ko.Observable<string>;
|
||||||
public isTemplateReady: ko.Observable<boolean>;
|
public isTemplateReady: ko.Observable<boolean>;
|
||||||
@ -69,13 +65,11 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
public minRUs: ko.Computed<number>;
|
public minRUs: ko.Computed<number>;
|
||||||
public maxRUs: ko.Computed<number>;
|
public maxRUs: ko.Computed<number>;
|
||||||
public maxRUsText: ko.PureComputed<string>;
|
public maxRUsText: ko.PureComputed<string>;
|
||||||
public maxRUThroughputInputLimit: ko.Computed<number>;
|
|
||||||
public notificationStatusInfo: ko.Observable<string>;
|
public notificationStatusInfo: ko.Observable<string>;
|
||||||
public pendingNotification: ko.Observable<DataModels.Notification>;
|
public pendingNotification: ko.Observable<DataModels.Notification>;
|
||||||
public requestUnitsUsageCost: ko.PureComputed<string>;
|
public requestUnitsUsageCost: ko.PureComputed<string>;
|
||||||
public autoscaleCost: ko.PureComputed<string>;
|
public autoscaleCost: ko.PureComputed<string>;
|
||||||
public shouldShowNotificationStatusPrompt: ko.Computed<boolean>;
|
public shouldShowNotificationStatusPrompt: ko.Computed<boolean>;
|
||||||
public shouldDisplayPortalUsePrompt: ko.Computed<boolean>;
|
|
||||||
public shouldShowStatusBar: ko.Computed<boolean>;
|
public shouldShowStatusBar: ko.Computed<boolean>;
|
||||||
public throughputTitle: ko.PureComputed<string>;
|
public throughputTitle: ko.PureComputed<string>;
|
||||||
public throughputAriaLabel: ko.PureComputed<string>;
|
public throughputAriaLabel: ko.PureComputed<string>;
|
||||||
@ -181,22 +175,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
return configContext.platform !== Platform.Emulator;
|
return configContext.platform !== Platform.Emulator;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.shouldDisplayPortalUsePrompt = ko.pureComputed<boolean>(() => configContext.platform === Platform.Hosted);
|
|
||||||
this.canThroughputExceedMaximumValue = ko.pureComputed<boolean>(
|
|
||||||
() => configContext.platform === Platform.Portal && !this.container.isRunningOnNationalCloud()
|
|
||||||
);
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (
|
|
||||||
configContext.platform === Platform.Emulator ||
|
|
||||||
configContext.platform === Platform.Hosted ||
|
|
||||||
this.canThroughputExceedMaximumValue()
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.overrideWithAutoPilotSettings = ko.pureComputed(() => {
|
this.overrideWithAutoPilotSettings = ko.pureComputed(() => {
|
||||||
return this._hasProvisioningTypeChanged() && this._wasAutopilotOriginallySet();
|
return this._hasProvisioningTypeChanged() && this._wasAutopilotOriginallySet();
|
||||||
});
|
});
|
||||||
@ -245,14 +223,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
return throughputDefaults.unlimitedmax;
|
return throughputDefaults.unlimitedmax;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.maxRUThroughputInputLimit = ko.pureComputed<number>(() => {
|
|
||||||
if (configContext.platform === Platform.Hosted) {
|
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.maxRUs();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.maxRUsText = ko.pureComputed(() => {
|
this.maxRUsText = ko.pureComputed(() => {
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million.toLocaleString();
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million.toLocaleString();
|
||||||
});
|
});
|
||||||
@ -300,8 +270,7 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million
|
||||||
this.canThroughputExceedMaximumValue()
|
|
||||||
) {
|
) {
|
||||||
return updateThroughputBeyondLimitWarningMessage;
|
return updateThroughputBeyondLimitWarningMessage;
|
||||||
}
|
}
|
||||||
@ -368,13 +337,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
!this.canThroughputExceedMaximumValue() &&
|
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.throughput.editableIsDirty()) {
|
if (this.throughput.editableIsDirty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -450,27 +412,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
const originalThroughputValue = this.throughput.getEditableOriginalValue();
|
const originalThroughputValue = this.throughput.getEditableOriginalValue();
|
||||||
const newThroughput = this.throughput();
|
const newThroughput = this.throughput();
|
||||||
|
|
||||||
if (
|
|
||||||
this.canThroughputExceedMaximumValue() &&
|
|
||||||
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million
|
|
||||||
) {
|
|
||||||
const requestPayload = {
|
|
||||||
subscriptionId: userContext.subscriptionId,
|
|
||||||
databaseAccountName: userContext.databaseAccount.name,
|
|
||||||
resourceGroup: userContext.resourceGroup,
|
|
||||||
databaseName: this.database.id(),
|
|
||||||
throughput: newThroughput,
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: false
|
|
||||||
};
|
|
||||||
await updateOfferThroughputBeyondLimit(requestPayload);
|
|
||||||
this.database.offer().content.offerThroughput = originalThroughputValue;
|
|
||||||
this.throughput(originalThroughputValue);
|
|
||||||
this.notificationStatusInfo(
|
|
||||||
throughputApplyDelayedMessage(this.isAutoPilotSelected(), newThroughput, this.database.id())
|
|
||||||
);
|
|
||||||
this.throughput.valueHasMutated(); // force component re-render
|
|
||||||
} else {
|
|
||||||
const updateOfferParams: DataModels.UpdateOfferParams = {
|
const updateOfferParams: DataModels.UpdateOfferParams = {
|
||||||
databaseId: this.database.id(),
|
databaseId: this.database.id(),
|
||||||
currentOffer: this.database.offer(),
|
currentOffer: this.database.offer(),
|
||||||
@ -485,7 +426,6 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
|||||||
this.database.offer.valueHasMutated();
|
this.database.offer.valueHasMutated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.container.isRefreshingExplorer(false);
|
this.container.isRefreshingExplorer(false);
|
||||||
this.isExecutionError(true);
|
this.isExecutionError(true);
|
||||||
|
@ -57,9 +57,7 @@
|
|||||||
class: 'scaleForm dirty',
|
class: 'scaleForm dirty',
|
||||||
value: throughput,
|
value: throughput,
|
||||||
minimum: minRUs,
|
minimum: minRUs,
|
||||||
maximum: maxRUThroughputInputLimit,
|
|
||||||
isEnabled: !hasDatabaseSharedThroughput(),
|
isEnabled: !hasDatabaseSharedThroughput(),
|
||||||
canExceedMaximumValue: canThroughputExceedMaximumValue,
|
|
||||||
label: throughputTitle,
|
label: throughputTitle,
|
||||||
ariaLabel: throughputAriaLabel,
|
ariaLabel: throughputAriaLabel,
|
||||||
costsVisible: costsVisible,
|
costsVisible: costsVisible,
|
||||||
|
@ -34,17 +34,6 @@ describe("Settings tab", () => {
|
|||||||
collections: [baseCollection]
|
collections: [baseCollection]
|
||||||
};
|
};
|
||||||
|
|
||||||
const quotaInfo: DataModels.CollectionQuotaInfo = {
|
|
||||||
storedProcedures: 0,
|
|
||||||
triggers: 0,
|
|
||||||
functions: 0,
|
|
||||||
documentsSize: 0,
|
|
||||||
documentsCount: 0,
|
|
||||||
collectionSize: 0,
|
|
||||||
usageSizeInKB: 0,
|
|
||||||
numPartitions: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
describe("Conflict Resolution", () => {
|
describe("Conflict Resolution", () => {
|
||||||
describe("should show conflict resolution", () => {
|
describe("should show conflict resolution", () => {
|
||||||
let explorer: Explorer;
|
let explorer: Explorer;
|
||||||
@ -70,7 +59,6 @@ describe("Settings tab", () => {
|
|||||||
explorer,
|
explorer,
|
||||||
"mydb",
|
"mydb",
|
||||||
conflictResolution ? baseCollection : baseCollectionWithoutConflict,
|
conflictResolution ? baseCollection : baseCollectionWithoutConflict,
|
||||||
quotaInfo,
|
|
||||||
null
|
null
|
||||||
),
|
),
|
||||||
onUpdateTabsButtons: undefined
|
onUpdateTabsButtons: undefined
|
||||||
@ -186,7 +174,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -207,7 +195,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -223,7 +211,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -258,7 +246,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -272,7 +260,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -295,7 +283,7 @@ describe("Settings tab", () => {
|
|||||||
tabPath: "",
|
tabPath: "",
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, null),
|
||||||
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -354,7 +342,6 @@ describe("Settings tab", () => {
|
|||||||
_ts: 0,
|
_ts: 0,
|
||||||
id: "mycoll"
|
id: "mycoll"
|
||||||
},
|
},
|
||||||
quotaInfo,
|
|
||||||
offer
|
offer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import { updateOffer } from "../../Common/dataAccess/updateOffer";
|
|||||||
import { updateCollection } from "../../Common/dataAccess/updateCollection";
|
import { updateCollection } from "../../Common/dataAccess/updateCollection";
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
|
|
||||||
import { configContext, Platform } from "../../ConfigContext";
|
import { configContext, Platform } from "../../ConfigContext";
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||||
|
|
||||||
@ -151,9 +150,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
|
|
||||||
public saveSettingsButton: ViewModels.Button;
|
public saveSettingsButton: ViewModels.Button;
|
||||||
public discardSettingsChangesButton: ViewModels.Button;
|
public discardSettingsChangesButton: ViewModels.Button;
|
||||||
|
|
||||||
public canRequestSupport: ko.Computed<boolean>;
|
|
||||||
public canThroughputExceedMaximumValue: ko.Computed<boolean>;
|
|
||||||
public changeFeedPolicyOffId: string;
|
public changeFeedPolicyOffId: string;
|
||||||
public changeFeedPolicyOnId: string;
|
public changeFeedPolicyOnId: string;
|
||||||
public changeFeedPolicyToggled: ViewModels.Editable<ChangeFeedPolicyToggledState>;
|
public changeFeedPolicyToggled: ViewModels.Editable<ChangeFeedPolicyToggledState>;
|
||||||
@ -174,8 +170,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
public indexingPolicyElementFocused: ko.Observable<boolean>;
|
public indexingPolicyElementFocused: ko.Observable<boolean>;
|
||||||
public minRUs: ko.Computed<number>;
|
public minRUs: ko.Computed<number>;
|
||||||
public minRUAnotationVisible: ko.Computed<boolean>;
|
public minRUAnotationVisible: ko.Computed<boolean>;
|
||||||
public maxRUs: ko.Computed<number>;
|
|
||||||
public maxRUThroughputInputLimit: ko.Computed<number>;
|
|
||||||
public maxRUsText: ko.PureComputed<string>;
|
public maxRUsText: ko.PureComputed<string>;
|
||||||
public notificationStatusInfo: ko.Observable<string>;
|
public notificationStatusInfo: ko.Observable<string>;
|
||||||
public partitionKeyName: ko.Computed<string>;
|
public partitionKeyName: ko.Computed<string>;
|
||||||
@ -188,7 +182,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
public rupmVisible: ko.Computed<boolean>;
|
public rupmVisible: ko.Computed<boolean>;
|
||||||
public scaleExpanded: ko.Observable<boolean>;
|
public scaleExpanded: ko.Observable<boolean>;
|
||||||
public settingsExpanded: ko.Observable<boolean>;
|
public settingsExpanded: ko.Observable<boolean>;
|
||||||
public shouldDisplayPortalUsePrompt: ko.Computed<boolean>;
|
|
||||||
public shouldShowIndexingPolicyEditor: ko.Computed<boolean>;
|
public shouldShowIndexingPolicyEditor: ko.Computed<boolean>;
|
||||||
public shouldShowNotificationStatusPrompt: ko.Computed<boolean>;
|
public shouldShowNotificationStatusPrompt: ko.Computed<boolean>;
|
||||||
public shouldShowStatusBar: ko.Computed<boolean>;
|
public shouldShowStatusBar: ko.Computed<boolean>;
|
||||||
@ -461,43 +454,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return (this.container && this.container.isTryCosmosDBSubscription()) || false;
|
return (this.container && this.container.isTryCosmosDBSubscription()) || false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canThroughputExceedMaximumValue = ko.pureComputed<boolean>(() => {
|
|
||||||
return (
|
|
||||||
this._isFixedContainer() &&
|
|
||||||
configContext.platform === Platform.Portal &&
|
|
||||||
!this.container.isRunningOnNationalCloud()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.canRequestSupport = ko.pureComputed(() => {
|
|
||||||
if (configContext.platform === Platform.Emulator) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isTryCosmosDBSubscription()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.canThroughputExceedMaximumValue()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configContext.platform === Platform.Hosted) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.container.isServerlessEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numPartitions = this.collection.quotaInfo().numPartitions;
|
|
||||||
return !!this.collection.partitionKeyProperty || numPartitions > 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.shouldDisplayPortalUsePrompt = ko.pureComputed<boolean>(
|
|
||||||
() => configContext.platform === Platform.Hosted && !!this.collection.partitionKey
|
|
||||||
);
|
|
||||||
|
|
||||||
this.minRUs = ko.computed<number>(() => {
|
this.minRUs = ko.computed<number>(() => {
|
||||||
if (this.isTryCosmosDBSubscription() || this.container.isServerlessEnabled()) {
|
if (this.isTryCosmosDBSubscription() || this.container.isServerlessEnabled()) {
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
@ -507,7 +463,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
this.collection && this.collection.offer && this.collection.offer() && this.collection.offer().content;
|
this.collection && this.collection.offer && this.collection.offer() && this.collection.offer().content;
|
||||||
|
|
||||||
if (offerContent && offerContent.offerAutopilotSettings) {
|
if (offerContent && offerContent.offerAutopilotSettings) {
|
||||||
return 400;
|
SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
}
|
}
|
||||||
|
|
||||||
const collectionThroughputInfo: DataModels.OfferThroughputInfo =
|
const collectionThroughputInfo: DataModels.OfferThroughputInfo =
|
||||||
@ -521,58 +477,14 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return collectionThroughputInfo.minimumRUForCollection;
|
return collectionThroughputInfo.minimumRUForCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numPartitions =
|
// minimumRUForCollection should always be present, but just in case return a default
|
||||||
(collectionThroughputInfo && collectionThroughputInfo.numPhysicalPartitions) ||
|
|
||||||
this.collection.quotaInfo().numPartitions;
|
|
||||||
|
|
||||||
if (!numPartitions || numPartitions === 1) {
|
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
}
|
|
||||||
|
|
||||||
let baseRU = SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
|
||||||
|
|
||||||
const quotaInKb = this.collection.quotaInfo().collectionSize;
|
|
||||||
const quotaInGb = PricingUtils.usageInGB(quotaInKb);
|
|
||||||
|
|
||||||
const perPartitionGBQuota: number = Math.max(10, quotaInGb / numPartitions);
|
|
||||||
const baseRUbyPartitions: number = ((numPartitions * perPartitionGBQuota) / 10) * 100;
|
|
||||||
|
|
||||||
return Math.max(baseRU, baseRUbyPartitions);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.minRUAnotationVisible = ko.computed<boolean>(() => {
|
this.minRUAnotationVisible = ko.computed<boolean>(() => {
|
||||||
return PricingUtils.isLargerThanDefaultMinRU(this.minRUs());
|
return PricingUtils.isLargerThanDefaultMinRU(this.minRUs());
|
||||||
});
|
});
|
||||||
|
|
||||||
this.maxRUs = ko.computed<number>(() => {
|
|
||||||
const isTryCosmosDBSubscription = this.isTryCosmosDBSubscription();
|
|
||||||
if (isTryCosmosDBSubscription || this.container.isServerlessEnabled()) {
|
|
||||||
return Constants.TryCosmosExperience.maxRU;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numPartitionsFromOffer: number =
|
|
||||||
this.collection &&
|
|
||||||
this.collection.offer &&
|
|
||||||
this.collection.offer() &&
|
|
||||||
this.collection.offer().content &&
|
|
||||||
this.collection.offer().content.collectionThroughputInfo &&
|
|
||||||
this.collection.offer().content.collectionThroughputInfo.numPhysicalPartitions;
|
|
||||||
|
|
||||||
const numPartitionsFromQuotaInfo: number = this.collection && this.collection.quotaInfo().numPartitions;
|
|
||||||
|
|
||||||
const numPartitions = numPartitionsFromOffer || numPartitionsFromQuotaInfo || 1;
|
|
||||||
|
|
||||||
return SharedConstants.CollectionCreation.MaxRUPerPartition * numPartitions;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.maxRUThroughputInputLimit = ko.pureComputed<number>(() => {
|
|
||||||
if (configContext.platform === Platform.Hosted && this.collection.partitionKey) {
|
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.maxRUs();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.maxRUsText = ko.pureComputed(() => {
|
this.maxRUsText = ko.pureComputed(() => {
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million.toLocaleString();
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs1Million.toLocaleString();
|
||||||
});
|
});
|
||||||
@ -583,10 +495,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
}
|
}
|
||||||
|
|
||||||
const minThroughput: string = this.minRUs().toLocaleString();
|
const minThroughput: string = this.minRUs().toLocaleString();
|
||||||
const maxThroughput: string =
|
const maxThroughput: string = !this._isFixedContainer() ? "unlimited" : "10000";
|
||||||
this.canThroughputExceedMaximumValue() && !this._isFixedContainer()
|
|
||||||
? "unlimited"
|
|
||||||
: this.maxRUs().toLocaleString();
|
|
||||||
return `Throughput (${minThroughput} - ${maxThroughput} RU/s)`;
|
return `Throughput (${minThroughput} - ${maxThroughput} RU/s)`;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -675,22 +584,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isThroughputGreaterThanMaxRus = this.throughput() > this.maxRUs();
|
|
||||||
const isEmulator = configContext.platform === Platform.Emulator;
|
|
||||||
if (isThroughputGreaterThanMaxRus && isEmulator) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isThroughputGreaterThanMaxRus && this._isFixedContainer()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isThroughputMoreThan1Million =
|
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
if (!this.canThroughputExceedMaximumValue() && isThroughputMoreThan1Million) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.throughput.editableIsDirty()) {
|
if (this.throughput.editableIsDirty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -714,14 +607,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
this.rupm() === Constants.RUPMStates.on &&
|
|
||||||
this.throughput() >
|
|
||||||
SharedConstants.CollectionCreation.MaxRUPMPerPartition * this.collection.quotaInfo()?.numPartitions
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.timeToLive.editableIsDirty()) {
|
if (this.timeToLive.editableIsDirty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -841,14 +726,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
this.shouldShowNotificationStatusPrompt = ko.computed<boolean>(() => this.notificationStatusInfo().length > 0);
|
this.shouldShowNotificationStatusPrompt = ko.computed<boolean>(() => this.notificationStatusInfo().length > 0);
|
||||||
|
|
||||||
this.warningMessage = ko.computed<string>(() => {
|
this.warningMessage = ko.computed<string>(() => {
|
||||||
const throughputExceedsBackendLimits: boolean =
|
|
||||||
this.canThroughputExceedMaximumValue() &&
|
|
||||||
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million;
|
|
||||||
|
|
||||||
const throughputExceedsMaxValue: boolean =
|
|
||||||
configContext.platform !== Platform.Emulator && this.throughput() > this.maxRUs();
|
|
||||||
|
|
||||||
const ttlOptionDirty: boolean = this.timeToLive.editableIsDirty();
|
const ttlOptionDirty: boolean = this.timeToLive.editableIsDirty();
|
||||||
const ttlOrIndexingPolicyFieldsDirty: boolean =
|
const ttlOrIndexingPolicyFieldsDirty: boolean =
|
||||||
this.timeToLive.editableIsDirty() ||
|
this.timeToLive.editableIsDirty() ||
|
||||||
@ -890,26 +767,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return AutoPilotUtils.manualToAutoscaleDisclaimer;
|
return AutoPilotUtils.manualToAutoscaleDisclaimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
throughputExceedsBackendLimits &&
|
|
||||||
!!this.collection.partitionKey &&
|
|
||||||
!this._isFixedContainer() &&
|
|
||||||
!ttlFieldFocused &&
|
|
||||||
!this.indexingPolicyElementFocused()
|
|
||||||
) {
|
|
||||||
return updateThroughputBeyondLimitWarningMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
throughputExceedsMaxValue &&
|
|
||||||
!!this.collection.partitionKey &&
|
|
||||||
!this._isFixedContainer() &&
|
|
||||||
!ttlFieldFocused &&
|
|
||||||
!this.indexingPolicyElementFocused()
|
|
||||||
) {
|
|
||||||
return updateThroughputDelayedApplyWarningMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.pendingNotification()) {
|
if (this.pendingNotification()) {
|
||||||
const throughputUnit: string = this._getThroughputUnit();
|
const throughputUnit: string = this._getThroughputUnit();
|
||||||
const matches: string[] = this.pendingNotification().description.match(
|
const matches: string[] = this.pendingNotification().description.match(
|
||||||
@ -1099,36 +956,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
newThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
|
||||||
this.container != null
|
|
||||||
) {
|
|
||||||
const requestPayload = {
|
|
||||||
subscriptionId: userContext.subscriptionId,
|
|
||||||
databaseAccountName: userContext.databaseAccount.name,
|
|
||||||
resourceGroup: userContext.resourceGroup,
|
|
||||||
databaseName: this.collection.databaseId,
|
|
||||||
collectionName: this.collection.id(),
|
|
||||||
throughput: newThroughput,
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: isRUPerMinuteThroughputEnabled
|
|
||||||
};
|
|
||||||
|
|
||||||
await updateOfferThroughputBeyondLimit(requestPayload);
|
|
||||||
this.collection.offer().content.offerThroughput = originalThroughputValue;
|
|
||||||
this.throughput(originalThroughputValue);
|
|
||||||
this.notificationStatusInfo(
|
|
||||||
throughputApplyDelayedMessage(
|
|
||||||
this.isAutoPilotSelected(),
|
|
||||||
originalThroughputValue,
|
|
||||||
this._getThroughputUnit(),
|
|
||||||
this.collection.databaseId,
|
|
||||||
this.collection.id(),
|
|
||||||
newThroughput
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.throughput.valueHasMutated(); // force component re-render
|
|
||||||
} else {
|
|
||||||
const updateOfferParams: DataModels.UpdateOfferParams = {
|
const updateOfferParams: DataModels.UpdateOfferParams = {
|
||||||
databaseId: this.collection.databaseId,
|
databaseId: this.collection.databaseId,
|
||||||
collectionId: this.collection.id(),
|
collectionId: this.collection.id(),
|
||||||
@ -1147,7 +974,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
this.collection.offer(updatedOffer);
|
this.collection.offer(updatedOffer);
|
||||||
this.collection.offer.valueHasMutated();
|
this.collection.offer.valueHasMutated();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.container.isRefreshingExplorer(false);
|
this.container.isRefreshingExplorer(false);
|
||||||
this._setBaseline();
|
this._setBaseline();
|
||||||
|
@ -10,10 +10,9 @@ describe("Collection", () => {
|
|||||||
container: Explorer,
|
container: Explorer,
|
||||||
databaseId: string,
|
databaseId: string,
|
||||||
data: DataModels.Collection,
|
data: DataModels.Collection,
|
||||||
quotaInfo: DataModels.CollectionQuotaInfo,
|
|
||||||
offer: DataModels.Offer
|
offer: DataModels.Offer
|
||||||
): Collection {
|
): Collection {
|
||||||
return new Collection(container, databaseId, data, quotaInfo, offer);
|
return new Collection(container, databaseId, data, offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateMockCollectionsDataModelWithPartitionKey(
|
function generateMockCollectionsDataModelWithPartitionKey(
|
||||||
@ -50,7 +49,7 @@ describe("Collection", () => {
|
|||||||
});
|
});
|
||||||
mockContainer.deleteCollectionText = ko.observable<string>("delete collection");
|
mockContainer.deleteCollectionText = ko.observable<string>("delete collection");
|
||||||
|
|
||||||
return generateCollection(mockContainer, "abc", data, {} as DataModels.CollectionQuotaInfo, {} as DataModels.Offer);
|
return generateCollection(mockContainer, "abc", data, {} as DataModels.Offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Partition key path parsing", () => {
|
describe("Partition key path parsing", () => {
|
||||||
|
@ -10,7 +10,6 @@ import { readTriggers } from "../../Common/dataAccess/readTriggers";
|
|||||||
import { readUserDefinedFunctions } from "../../Common/dataAccess/readUserDefinedFunctions";
|
import { readUserDefinedFunctions } from "../../Common/dataAccess/readUserDefinedFunctions";
|
||||||
import { createDocument } from "../../Common/DocumentClientUtilityBase";
|
import { createDocument } from "../../Common/DocumentClientUtilityBase";
|
||||||
import { readCollectionOffer } from "../../Common/dataAccess/readCollectionOffer";
|
import { readCollectionOffer } from "../../Common/dataAccess/readCollectionOffer";
|
||||||
import { readCollectionQuotaInfo } from "../../Common/dataAccess/readCollectionQuotaInfo";
|
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
@ -55,7 +54,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
public defaultTtl: ko.Observable<number>;
|
public defaultTtl: ko.Observable<number>;
|
||||||
public indexingPolicy: ko.Observable<DataModels.IndexingPolicy>;
|
public indexingPolicy: ko.Observable<DataModels.IndexingPolicy>;
|
||||||
public uniqueKeyPolicy: DataModels.UniqueKeyPolicy;
|
public uniqueKeyPolicy: DataModels.UniqueKeyPolicy;
|
||||||
public quotaInfo: ko.Observable<DataModels.CollectionQuotaInfo>;
|
|
||||||
public offer: ko.Observable<DataModels.Offer>;
|
public offer: ko.Observable<DataModels.Offer>;
|
||||||
public conflictResolutionPolicy: ko.Observable<DataModels.ConflictResolutionPolicy>;
|
public conflictResolutionPolicy: ko.Observable<DataModels.ConflictResolutionPolicy>;
|
||||||
public changeFeedPolicy: ko.Observable<DataModels.ChangeFeedPolicy>;
|
public changeFeedPolicy: ko.Observable<DataModels.ChangeFeedPolicy>;
|
||||||
@ -94,13 +92,7 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
public userDefinedFunctionsFocused: ko.Observable<boolean>;
|
public userDefinedFunctionsFocused: ko.Observable<boolean>;
|
||||||
public triggersFocused: ko.Observable<boolean>;
|
public triggersFocused: ko.Observable<boolean>;
|
||||||
|
|
||||||
constructor(
|
constructor(container: Explorer, databaseId: string, data: DataModels.Collection, offer: DataModels.Offer) {
|
||||||
container: Explorer,
|
|
||||||
databaseId: string,
|
|
||||||
data: DataModels.Collection,
|
|
||||||
quotaInfo: DataModels.CollectionQuotaInfo,
|
|
||||||
offer: DataModels.Offer
|
|
||||||
) {
|
|
||||||
this.nodeKind = "Collection";
|
this.nodeKind = "Collection";
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.self = data._self;
|
this.self = data._self;
|
||||||
@ -112,7 +104,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
this.id = ko.observable(data.id);
|
this.id = ko.observable(data.id);
|
||||||
this.defaultTtl = ko.observable(data.defaultTtl);
|
this.defaultTtl = ko.observable(data.defaultTtl);
|
||||||
this.indexingPolicy = ko.observable(data.indexingPolicy);
|
this.indexingPolicy = ko.observable(data.indexingPolicy);
|
||||||
this.quotaInfo = ko.observable(quotaInfo);
|
|
||||||
this.offer = ko.observable(offer);
|
this.offer = ko.observable(offer);
|
||||||
this.conflictResolutionPolicy = ko.observable(data.conflictResolutionPolicy);
|
this.conflictResolutionPolicy = ko.observable(data.conflictResolutionPolicy);
|
||||||
this.changeFeedPolicy = ko.observable<DataModels.ChangeFeedPolicy>(data.changeFeedPolicy);
|
this.changeFeedPolicy = ko.observable<DataModels.ChangeFeedPolicy>(data.changeFeedPolicy);
|
||||||
@ -669,14 +660,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private async loadCollectionQuotaInfo(): Promise<void> {
|
|
||||||
// TODO: Use the collection entity cache to get quota info
|
|
||||||
const quotaInfoWithUniqueKeyPolicy = await readCollectionQuotaInfo(this);
|
|
||||||
this.uniqueKeyPolicy = quotaInfoWithUniqueKeyPolicy.uniqueKeyPolicy;
|
|
||||||
const quotaInfo = _.omit(quotaInfoWithUniqueKeyPolicy, "uniqueKeyPolicy");
|
|
||||||
this.quotaInfo(quotaInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public onNewQueryClick(source: any, event: MouseEvent, queryText?: string) {
|
public onNewQueryClick(source: any, event: MouseEvent, queryText?: string) {
|
||||||
const collection: ViewModels.Collection = source.collection || source;
|
const collection: ViewModels.Collection = source.collection || source;
|
||||||
const id = this.container.tabsManager.getTabs(ViewModels.CollectionTabKind.Query).length + 1;
|
const id = this.container.tabsManager.getTabs(ViewModels.CollectionTabKind.Query).length + 1;
|
||||||
@ -1349,7 +1332,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
this.offer(await readCollectionOffer(params));
|
this.offer(await readCollectionOffer(params));
|
||||||
await this.loadCollectionQuotaInfo();
|
|
||||||
|
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
Action.LoadOffers,
|
Action.LoadOffers,
|
||||||
|
@ -185,7 +185,7 @@ export default class Database implements ViewModels.Database {
|
|||||||
const deltaCollections = this.getDeltaCollections(collections);
|
const deltaCollections = this.getDeltaCollections(collections);
|
||||||
|
|
||||||
deltaCollections.toAdd.forEach((collection: DataModels.Collection) => {
|
deltaCollections.toAdd.forEach((collection: DataModels.Collection) => {
|
||||||
const collectionVM: Collection = new Collection(this.container, this.id(), collection, null, null);
|
const collectionVM: Collection = new Collection(this.container, this.id(), collection, null);
|
||||||
collectionVMs.push(collectionVM);
|
collectionVMs.push(collectionVM);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user