mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-16 17:25:58 +00:00
Support serverless accounts (#109)
* Changes for serverless accounts * Dont show upsell message for serverless accounts * Update CassandraAddCollectionPane to support serverless
This commit is contained in:
parent
dc67c5f40b
commit
33969581ac
@ -101,6 +101,7 @@ export class CapabilityNames {
|
|||||||
public static readonly EnableNotebooks: string = "EnableNotebooks";
|
public static readonly EnableNotebooks: string = "EnableNotebooks";
|
||||||
public static readonly EnableStorageAnalytics: string = "EnableStorageAnalytics";
|
public static readonly EnableStorageAnalytics: string = "EnableStorageAnalytics";
|
||||||
public static readonly EnableMongo: string = "EnableMongo";
|
public static readonly EnableMongo: string = "EnableMongo";
|
||||||
|
public static readonly EnableServerless: string = "EnableServerless";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Features {
|
export class Features {
|
||||||
|
@ -118,6 +118,7 @@ export default class Explorer {
|
|||||||
public isPreferredApiGraph: ko.Computed<boolean>;
|
public isPreferredApiGraph: ko.Computed<boolean>;
|
||||||
public isPreferredApiTable: ko.Computed<boolean>;
|
public isPreferredApiTable: ko.Computed<boolean>;
|
||||||
public isFixedCollectionWithSharedThroughputSupported: ko.Computed<boolean>;
|
public isFixedCollectionWithSharedThroughputSupported: ko.Computed<boolean>;
|
||||||
|
public isServerlessEnabled: ko.Computed<boolean>;
|
||||||
public isEmulator: boolean;
|
public isEmulator: boolean;
|
||||||
public isAccountReady: ko.Observable<boolean>;
|
public isAccountReady: ko.Observable<boolean>;
|
||||||
public canSaveQueries: ko.Computed<boolean>;
|
public canSaveQueries: ko.Computed<boolean>;
|
||||||
@ -509,6 +510,14 @@ export default class Explorer {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.isServerlessEnabled = ko.computed(
|
||||||
|
() =>
|
||||||
|
this.databaseAccount &&
|
||||||
|
this.databaseAccount()?.properties?.capabilities?.find(
|
||||||
|
item => item.name === Constants.CapabilityNames.EnableServerless
|
||||||
|
) !== undefined
|
||||||
|
);
|
||||||
|
|
||||||
this.isPreferredApiMongoDB = ko.computed(() => {
|
this.isPreferredApiMongoDB = ko.computed(() => {
|
||||||
const defaultExperience = (this.defaultExperience && this.defaultExperience()) || "";
|
const defaultExperience = (this.defaultExperience && this.defaultExperience()) || "";
|
||||||
if (defaultExperience.toLowerCase() === Constants.DefaultAccountExperience.MongoDB.toLowerCase()) {
|
if (defaultExperience.toLowerCase() === Constants.DefaultAccountExperience.MongoDB.toLowerCase()) {
|
||||||
@ -1406,87 +1415,97 @@ export default class Explorer {
|
|||||||
dataExplorerArea: Constants.Areas.ResourceTree
|
dataExplorerArea: Constants.Areas.ResourceTree
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor
|
// TODO: Refactor
|
||||||
const deferred: Q.Deferred<any> = Q.defer();
|
const deferred: Q.Deferred<any> = Q.defer();
|
||||||
const offerPromise: Q.Promise<DataModels.Offer[]> = this.documentClientUtility.readOffers();
|
|
||||||
this._setLoadingStatusText("Fetching offers...");
|
|
||||||
|
|
||||||
offerPromise.then(
|
const refreshDatabases = (offers?: DataModels.Offer[]) => {
|
||||||
(offers: DataModels.Offer[]) => {
|
this._setLoadingStatusText("Fetching databases...");
|
||||||
this._setLoadingStatusText("Successfully fetched offers.");
|
this.documentClientUtility.readDatabases(null /*options*/).then(
|
||||||
this._setLoadingStatusText("Fetching databases...");
|
(databases: DataModels.Database[]) => {
|
||||||
this.documentClientUtility.readDatabases(null /*options*/).then(
|
this._setLoadingStatusText("Successfully fetched databases.");
|
||||||
(databases: DataModels.Database[]) => {
|
TelemetryProcessor.traceSuccess(
|
||||||
this._setLoadingStatusText("Successfully fetched databases.");
|
Action.LoadDatabases,
|
||||||
TelemetryProcessor.traceSuccess(
|
{
|
||||||
Action.LoadDatabases,
|
databaseAccountName: this.databaseAccount().name,
|
||||||
{
|
defaultExperience: this.defaultExperience(),
|
||||||
databaseAccountName: this.databaseAccount().name,
|
dataExplorerArea: Constants.Areas.ResourceTree
|
||||||
defaultExperience: this.defaultExperience(),
|
},
|
||||||
dataExplorerArea: Constants.Areas.ResourceTree
|
startKey
|
||||||
|
);
|
||||||
|
const currentlySelectedNode: ViewModels.TreeNode = this.selectedNode();
|
||||||
|
const deltaDatabases = this.getDeltaDatabases(databases, offers);
|
||||||
|
this.addDatabasesToList(deltaDatabases.toAdd);
|
||||||
|
this.deleteDatabasesFromList(deltaDatabases.toDelete);
|
||||||
|
this.selectedNode(currentlySelectedNode);
|
||||||
|
this._setLoadingStatusText("Fetching containers...");
|
||||||
|
this.refreshAndExpandNewDatabases(deltaDatabases.toAdd)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
this._setLoadingStatusText("Successfully fetched containers.");
|
||||||
|
deferred.resolve();
|
||||||
},
|
},
|
||||||
startKey
|
reason => {
|
||||||
);
|
this._setLoadingStatusText("Failed to fetch containers.");
|
||||||
const currentlySelectedNode: ViewModels.TreeNode = this.selectedNode();
|
deferred.reject(reason);
|
||||||
const deltaDatabases = this.getDeltaDatabases(databases, offers);
|
}
|
||||||
this.addDatabasesToList(deltaDatabases.toAdd);
|
)
|
||||||
this.deleteDatabasesFromList(deltaDatabases.toDelete);
|
.finally(() => this.isRefreshingExplorer(false));
|
||||||
this.selectedNode(currentlySelectedNode);
|
},
|
||||||
this._setLoadingStatusText("Fetching containers...");
|
error => {
|
||||||
this.refreshAndExpandNewDatabases(deltaDatabases.toAdd)
|
this._setLoadingStatusText("Failed to fetch databases.");
|
||||||
.then(
|
this.isRefreshingExplorer(false);
|
||||||
() => {
|
deferred.reject(error);
|
||||||
this._setLoadingStatusText("Successfully fetched containers.");
|
TelemetryProcessor.traceFailure(
|
||||||
deferred.resolve();
|
Action.LoadDatabases,
|
||||||
},
|
{
|
||||||
reason => {
|
databaseAccountName: this.databaseAccount().name,
|
||||||
this._setLoadingStatusText("Failed to fetch containers.");
|
defaultExperience: this.defaultExperience(),
|
||||||
deferred.reject(reason);
|
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||||
}
|
error: JSON.stringify(error)
|
||||||
)
|
},
|
||||||
.finally(() => this.isRefreshingExplorer(false));
|
startKey
|
||||||
},
|
);
|
||||||
error => {
|
NotificationConsoleUtils.logConsoleMessage(
|
||||||
this._setLoadingStatusText("Failed to fetch databases.");
|
ConsoleDataType.Error,
|
||||||
this.isRefreshingExplorer(false);
|
`Error while refreshing databases: ${JSON.stringify(error)}`
|
||||||
deferred.reject(error);
|
);
|
||||||
TelemetryProcessor.traceFailure(
|
}
|
||||||
Action.LoadDatabases,
|
);
|
||||||
{
|
};
|
||||||
databaseAccountName: this.databaseAccount().name,
|
|
||||||
defaultExperience: this.defaultExperience(),
|
if (this.isServerlessEnabled()) {
|
||||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
// Serverless accounts don't support offers call
|
||||||
error: JSON.stringify(error)
|
refreshDatabases();
|
||||||
},
|
} else {
|
||||||
startKey
|
const offerPromise: Q.Promise<DataModels.Offer[]> = this.documentClientUtility.readOffers();
|
||||||
);
|
this._setLoadingStatusText("Fetching offers...");
|
||||||
NotificationConsoleUtils.logConsoleMessage(
|
offerPromise.then(
|
||||||
ConsoleDataType.Error,
|
(offers: DataModels.Offer[]) => {
|
||||||
`Error while refreshing databases: ${JSON.stringify(error)}`
|
this._setLoadingStatusText("Successfully fetched offers.");
|
||||||
);
|
refreshDatabases(offers);
|
||||||
}
|
},
|
||||||
);
|
error => {
|
||||||
},
|
this._setLoadingStatusText("Failed to fetch offers.");
|
||||||
error => {
|
this.isRefreshingExplorer(false);
|
||||||
this._setLoadingStatusText("Failed to fetch offers.");
|
deferred.reject(error);
|
||||||
this.isRefreshingExplorer(false);
|
TelemetryProcessor.traceFailure(
|
||||||
deferred.reject(error);
|
Action.LoadDatabases,
|
||||||
TelemetryProcessor.traceFailure(
|
{
|
||||||
Action.LoadDatabases,
|
databaseAccountName: this.databaseAccount().name,
|
||||||
{
|
defaultExperience: this.defaultExperience(),
|
||||||
databaseAccountName: this.databaseAccount().name,
|
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||||
defaultExperience: this.defaultExperience(),
|
error: JSON.stringify(error)
|
||||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
},
|
||||||
error: JSON.stringify(error)
|
startKey
|
||||||
},
|
);
|
||||||
startKey
|
NotificationConsoleUtils.logConsoleMessage(
|
||||||
);
|
ConsoleDataType.Error,
|
||||||
NotificationConsoleUtils.logConsoleMessage(
|
`Error while refreshing databases: ${JSON.stringify(error)}`
|
||||||
ConsoleDataType.Error,
|
);
|
||||||
`Error while refreshing databases: ${JSON.stringify(error)}`
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return deferred.promise.then(
|
return deferred.promise.then(
|
||||||
() => {
|
() => {
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
<!-- Add collection errors - End -->
|
<!-- Add collection errors - End -->
|
||||||
|
|
||||||
<!-- upsell message - start -->
|
<!-- upsell message - start -->
|
||||||
<div class="infoBoxContainer" aria-live="assertive" data-bind="visible: formErrors && !formErrors()">
|
<div class="infoBoxContainer" aria-live="assertive" data-bind="visible: showUpsellMessage && showUpsellMessage() && formErrors && !formErrors()">
|
||||||
<div class="infoBoxContent">
|
<div class="infoBoxContent">
|
||||||
<span><img class="infoBoxIcon" src="/info_color.svg" alt="Promo"></span>
|
<span><img class="infoBoxIcon" src="/info_color.svg" alt="Promo"></span>
|
||||||
<span class="infoBoxDetails">
|
<span class="infoBoxDetails">
|
||||||
@ -112,7 +112,9 @@
|
|||||||
<datalist id="databasesList" data-bind="foreach: databaseIds" data-bind="visible: databaseCreateNew">
|
<datalist id="databasesList" data-bind="foreach: databaseIds" data-bind="visible: databaseCreateNew">
|
||||||
<option data-bind="value: $data">
|
<option data-bind="value: $data">
|
||||||
</datalist>
|
</datalist>
|
||||||
|
|
||||||
<!-- Database provisioned throughput - Start -->
|
<!-- Database provisioned throughput - Start -->
|
||||||
|
<!-- ko if: canConfigureThroughput -->
|
||||||
<div class="databaseProvision" aria-label="New database provision support"
|
<div class="databaseProvision" aria-label="New database provision support"
|
||||||
data-bind="visible: databaseCreateNew">
|
data-bind="visible: databaseCreateNew">
|
||||||
<input tabindex="0" type="checkbox" data-test="addCollectionPane-databaseSharedThroughput"
|
<input tabindex="0" type="checkbox" data-test="addCollectionPane-databaseSharedThroughput"
|
||||||
@ -187,6 +189,7 @@
|
|||||||
</throughput-input>
|
</throughput-input>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
<!-- /ko -->
|
||||||
<!-- Database provisioned throughput - End -->
|
<!-- Database provisioned throughput - End -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -414,7 +417,10 @@
|
|||||||
more</a></p>
|
more</a></p>
|
||||||
</div>
|
</div>
|
||||||
<!-- large parition key - end -->
|
<!-- large parition key - end -->
|
||||||
<!-- Provision collection throughput checkox - start -->
|
|
||||||
|
<!-- Provision collection throughput - start -->
|
||||||
|
<!-- ko if: canConfigureThroughput -->
|
||||||
|
<!-- Provision collection throughput checkbox - start -->
|
||||||
<div class="pkPadding" data-bind="visible: databaseHasSharedOffer() && !databaseCreateNew()">
|
<div class="pkPadding" data-bind="visible: databaseHasSharedOffer() && !databaseCreateNew()">
|
||||||
<input type="checkbox" id="collectionSharedThroughput"
|
<input type="checkbox" id="collectionSharedThroughput"
|
||||||
data-bind="checked: collectionWithThroughputInShared, attr: {title:collectionWithThroughputInSharedTitle}" />
|
data-bind="checked: collectionWithThroughputInShared, attr: {title:collectionWithThroughputInSharedTitle}" />
|
||||||
@ -434,7 +440,8 @@
|
|||||||
level.</span>
|
level.</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Provision collection throughput checkox - end -->
|
<!-- Provision collection throughput checkbox - end -->
|
||||||
|
|
||||||
<!-- Provision collection throughput spinner - start -->
|
<!-- Provision collection throughput spinner - start -->
|
||||||
<!-- ko if: hasAutoPilotV2FeatureFlag && !hasAutoPilotV2FeatureFlag() -->
|
<!-- ko if: hasAutoPilotV2FeatureFlag && !hasAutoPilotV2FeatureFlag() -->
|
||||||
<div data-bind="visible: displayCollectionThroughput" data-test="addCollection-displayCollectionThroughput">
|
<div data-bind="visible: displayCollectionThroughput" data-test="addCollection-displayCollectionThroughput">
|
||||||
@ -467,6 +474,7 @@
|
|||||||
</throughput-input-autopilot-v3>
|
</throughput-input-autopilot-v3>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
|
||||||
<!-- ko if: hasAutoPilotV2FeatureFlag && hasAutoPilotV2FeatureFlag() -->
|
<!-- ko if: hasAutoPilotV2FeatureFlag && hasAutoPilotV2FeatureFlag() -->
|
||||||
<div data-bind="visible: displayCollectionThroughput" data-test="addCollection-displayCollectionThroughput">
|
<div data-bind="visible: displayCollectionThroughput" data-test="addCollection-displayCollectionThroughput">
|
||||||
<!-- 3 -->
|
<!-- 3 -->
|
||||||
@ -499,8 +507,10 @@
|
|||||||
</throughput-input>
|
</throughput-input>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
|
||||||
<!-- Provision collection throughput spinner - end -->
|
<!-- Provision collection throughput spinner - end -->
|
||||||
|
<!-- /ko -->
|
||||||
|
<!-- Provision collection throughput - end -->
|
||||||
|
|
||||||
<!-- Enable analytical storage - start -->
|
<!-- Enable analytical storage - start -->
|
||||||
<div class="enableAnalyticalStorage pkPadding" aria-label="Enable Analytical Store"
|
<div class="enableAnalyticalStorage pkPadding" aria-label="Enable Analytical Store"
|
||||||
data-bind="visible: isSynapseLinkSupported">
|
data-bind="visible: isSynapseLinkSupported">
|
||||||
|
@ -93,6 +93,8 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
public canExceedMaximumValue: ko.PureComputed<boolean>;
|
public canExceedMaximumValue: ko.PureComputed<boolean>;
|
||||||
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
||||||
public ruToolTipText: ko.Computed<string>;
|
public ruToolTipText: ko.Computed<string>;
|
||||||
|
public canConfigureThroughput: ko.PureComputed<boolean>;
|
||||||
|
public showUpsellMessage: ko.PureComputed<boolean>;
|
||||||
|
|
||||||
private _databaseOffers: HashMap<DataModels.Offer>;
|
private _databaseOffers: HashMap<DataModels.Offer>;
|
||||||
private _isSynapseLinkEnabled: ko.Computed<boolean>;
|
private _isSynapseLinkEnabled: ko.Computed<boolean>;
|
||||||
@ -102,6 +104,8 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
this._databaseOffers = new HashMap<DataModels.Offer>();
|
this._databaseOffers = new HashMap<DataModels.Offer>();
|
||||||
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
||||||
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
||||||
|
this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
||||||
|
this.showUpsellMessage = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
||||||
this.formWarnings = ko.observable<string>();
|
this.formWarnings = ko.observable<string>();
|
||||||
this.collectionId = ko.observable<string>();
|
this.collectionId = ko.observable<string>();
|
||||||
this.databaseId = ko.observable<string>();
|
this.databaseId = ko.observable<string>();
|
||||||
@ -591,6 +595,11 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
if (config.platform === Platform.Emulator) {
|
if (config.platform === Platform.Emulator) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.container.isServerlessEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.container.isPreferredApiDocumentDB()) {
|
if (this.container.isPreferredApiDocumentDB()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -723,10 +732,19 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _computeOfferThroughput(): number {
|
private _computeOfferThroughput(): number {
|
||||||
if (this.databaseCreateNewShared()) {
|
if (!this.canConfigureThroughput()) {
|
||||||
return this.isSharedAutoPilotSelected() ? undefined : this._getThroughput();
|
return undefined;
|
||||||
}
|
}
|
||||||
return this.isAutoPilotSelected() ? undefined : this._getThroughput();
|
|
||||||
|
if (this.isAutoPilotSelected()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.databaseCreateNewShared() && this.isSharedAutoPilotSelected()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._getThroughput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public submit() {
|
public submit() {
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<!-- Add database errors - End -->
|
<!-- Add database errors - End -->
|
||||||
|
|
||||||
<!-- upsell message - start -->
|
<!-- upsell message - start -->
|
||||||
<div class="infoBoxContainer" aria-live="assertive" data-bind="visible: formErrors && !formErrors()">
|
<div class="infoBoxContainer" aria-live="assertive" data-bind="visible: showUpsellMessage && showUpsellMessage() && formErrors && !formErrors()">
|
||||||
<div class="infoBoxContent">
|
<div class="infoBoxContent">
|
||||||
<span><img class="infoBoxIcon" src="/info_color.svg" alt="Promo"></span>
|
<span><img class="infoBoxIcon" src="/info_color.svg" alt="Promo"></span>
|
||||||
<span class="infoBoxDetails">
|
<span class="infoBoxDetails">
|
||||||
@ -76,6 +76,9 @@
|
|||||||
title="May not end with space nor contain characters '\' '/' '#' '?'" placeholder="Type a new database id"
|
title="May not end with space nor contain characters '\' '/' '#' '?'" placeholder="Type a new database id"
|
||||||
size="40" class="collid" data-bind="textInput: databaseId, hasFocus: firstFieldHasFocus"
|
size="40" class="collid" data-bind="textInput: databaseId, hasFocus: firstFieldHasFocus"
|
||||||
aria-label="Database id" autofocus>
|
aria-label="Database id" autofocus>
|
||||||
|
|
||||||
|
<!-- Database provisioned throughput - Start -->
|
||||||
|
<!-- ko if: canConfigureThroughput -->
|
||||||
<div class="databaseProvision" aria-label="New database provision support">
|
<div class="databaseProvision" aria-label="New database provision support">
|
||||||
<input tabindex="0" type="checkbox" id="addDatabasePane-databaseSharedThroughput"
|
<input tabindex="0" type="checkbox" id="addDatabasePane-databaseSharedThroughput"
|
||||||
title="Provision shared throughput" data-bind="checked: databaseCreateNewShared" />
|
title="Provision shared throughput" data-bind="checked: databaseCreateNewShared" />
|
||||||
@ -156,6 +159,7 @@
|
|||||||
support</a> for more than <span data-bind="text: maxThroughputRUText"></span> RU/s.</p>
|
support</a> for more than <span data-bind="text: maxThroughputRUText"></span> RU/s.</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
<!-- /ko -->
|
||||||
<!-- Database provisioned throughput - End -->
|
<!-- Database provisioned throughput - End -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,6 +49,8 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
||||||
public ruToolTipText: ko.Computed<string>;
|
public ruToolTipText: ko.Computed<string>;
|
||||||
public isFreeTierAccount: ko.Computed<boolean>;
|
public isFreeTierAccount: ko.Computed<boolean>;
|
||||||
|
public canConfigureThroughput: ko.PureComputed<boolean>;
|
||||||
|
public showUpsellMessage: ko.PureComputed<boolean>;
|
||||||
|
|
||||||
constructor(options: ViewModels.PaneOptions) {
|
constructor(options: ViewModels.PaneOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
@ -56,6 +58,8 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
this.databaseId = ko.observable<string>();
|
this.databaseId = ko.observable<string>();
|
||||||
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
||||||
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
||||||
|
this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
||||||
|
this.showUpsellMessage = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
||||||
|
|
||||||
this.canExceedMaximumValue = ko.pureComputed(() => this.container.canExceedMaximumValue());
|
this.canExceedMaximumValue = ko.pureComputed(() => this.container.canExceedMaximumValue());
|
||||||
|
|
||||||
@ -522,7 +526,15 @@ export default class AddDatabasePane extends ContextualPaneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _computeOfferThroughput(): number {
|
private _computeOfferThroughput(): number {
|
||||||
return this.isAutoPilotSelected() ? undefined : this._getThroughput();
|
if (!this.canConfigureThroughput()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isAutoPilotSelected()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._getThroughput();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isValid(): boolean {
|
private _isValid(): boolean {
|
||||||
|
@ -118,6 +118,8 @@
|
|||||||
<option data-bind="value: $data.id"> </option>
|
<option data-bind="value: $data.id"> </option>
|
||||||
</datalist>
|
</datalist>
|
||||||
|
|
||||||
|
<!-- Database provisioned throughput - Start -->
|
||||||
|
<!-- ko if: canConfigureThroughput -->
|
||||||
<div
|
<div
|
||||||
class="databaseProvision"
|
class="databaseProvision"
|
||||||
aria-label="New database provision support"
|
aria-label="New database provision support"
|
||||||
@ -202,6 +204,8 @@
|
|||||||
</throughput-input>
|
</throughput-input>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
<!-- /ko -->
|
||||||
|
<!-- Database provisioned throughput - End -->
|
||||||
</div>
|
</div>
|
||||||
<div class="seconddivpadding">
|
<div class="seconddivpadding">
|
||||||
<p>
|
<p>
|
||||||
@ -231,6 +235,9 @@
|
|||||||
style="height:125px; width: calc(100% - 80px); resize: vertical;"
|
style="height:125px; width: calc(100% - 80px); resize: vertical;"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Provision table throughput - start -->
|
||||||
|
<!-- ko if: canConfigureThroughput -->
|
||||||
<div class="seconddivpadding" data-bind="visible: keyspaceHasSharedOffer() && !keyspaceCreateNew()">
|
<div class="seconddivpadding" data-bind="visible: keyspaceHasSharedOffer() && !keyspaceCreateNew()">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -315,6 +322,8 @@
|
|||||||
</throughput-input>
|
</throughput-input>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
<!-- /ko -->
|
||||||
|
<!-- Provision table throughput - end -->
|
||||||
</div>
|
</div>
|
||||||
<div class="paneFooter">
|
<div class="paneFooter">
|
||||||
<div class="leftpanel-okbut">
|
<div class="leftpanel-okbut">
|
||||||
|
@ -51,6 +51,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
|
|||||||
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
public hasAutoPilotV2FeatureFlag: ko.PureComputed<boolean>;
|
||||||
public isFreeTierAccount: ko.Computed<boolean>;
|
public isFreeTierAccount: ko.Computed<boolean>;
|
||||||
public ruToolTipText: ko.Computed<string>;
|
public ruToolTipText: ko.Computed<string>;
|
||||||
|
public canConfigureThroughput: ko.PureComputed<boolean>;
|
||||||
|
|
||||||
private keyspaceOffers: HashMap<DataModels.Offer>;
|
private keyspaceOffers: HashMap<DataModels.Offer>;
|
||||||
|
|
||||||
@ -61,6 +62,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
|
|||||||
this.keyspaceCreateNew = ko.observable<boolean>(true);
|
this.keyspaceCreateNew = ko.observable<boolean>(true);
|
||||||
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
||||||
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText(this.hasAutoPilotV2FeatureFlag()));
|
||||||
|
this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled());
|
||||||
this.keyspaceOffers = new HashMap<DataModels.Offer>();
|
this.keyspaceOffers = new HashMap<DataModels.Offer>();
|
||||||
this.keyspaceIds = ko.observableArray<string>();
|
this.keyspaceIds = ko.observableArray<string>();
|
||||||
this.keyspaceHasSharedOffer = ko.observable<boolean>(false);
|
this.keyspaceHasSharedOffer = ko.observable<boolean>(false);
|
||||||
@ -365,7 +367,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
|
|||||||
const createTableQueryPrefix: string = `${this.createTableQuery()}${this.tableId().trim()} ${this.userTableQuery()}`;
|
const createTableQueryPrefix: string = `${this.createTableQuery()}${this.tableId().trim()} ${this.userTableQuery()}`;
|
||||||
let createTableQuery: string;
|
let createTableQuery: string;
|
||||||
|
|
||||||
if (this.dedicateTableThroughput() || !this.keyspaceHasSharedOffer()) {
|
if (this.canConfigureThroughput() && (this.dedicateTableThroughput() || !this.keyspaceHasSharedOffer())) {
|
||||||
if (this.isAutoPilotSelected() && this.selectedAutoPilotThroughput()) {
|
if (this.isAutoPilotSelected() && this.selectedAutoPilotThroughput()) {
|
||||||
createTableQuery = `${createTableQueryPrefix} WITH ${autoPilotCommand}=${this.selectedAutoPilotThroughput()};`;
|
createTableQuery = `${createTableQueryPrefix} WITH ${autoPilotCommand}=${this.selectedAutoPilotThroughput()};`;
|
||||||
} else {
|
} else {
|
||||||
|
@ -553,7 +553,7 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
dataExplorerArea: Constants.Areas.ResourceTree
|
dataExplorerArea: Constants.Areas.ResourceTree
|
||||||
});
|
});
|
||||||
|
|
||||||
const tabTitle = "Scale & Settings";
|
const tabTitle = !this.offer() ? "Settings" : "Scale & Settings";
|
||||||
const pendingNotificationsPromise: Q.Promise<DataModels.Notification> = this._getPendingThroughputSplitNotification();
|
const pendingNotificationsPromise: Q.Promise<DataModels.Notification> = this._getPendingThroughputSplitNotification();
|
||||||
const matchingTabs: ViewModels.Tab[] = this.container.tabsManager.getTabs(
|
const matchingTabs: ViewModels.Tab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Settings,
|
ViewModels.CollectionTabKind.Settings,
|
||||||
@ -561,6 +561,7 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
return tab.collection && tab.collection.rid === this.rid;
|
return tab.collection && tab.collection.rid === this.rid;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let settingsTab: SettingsTab = matchingTabs && (matchingTabs[0] as SettingsTab);
|
let settingsTab: SettingsTab = matchingTabs && (matchingTabs[0] as SettingsTab);
|
||||||
if (!settingsTab) {
|
if (!settingsTab) {
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.Tab, {
|
const startKey: number = TelemetryProcessor.traceStart(Action.Tab, {
|
||||||
@ -582,7 +583,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
documentClientUtility: this.container.documentClientUtility,
|
documentClientUtility: this.container.documentClientUtility,
|
||||||
collection: this,
|
collection: this,
|
||||||
node: this,
|
node: this,
|
||||||
|
|
||||||
selfLink: this.self,
|
selfLink: this.self,
|
||||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/settings`,
|
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/settings`,
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
@ -658,7 +658,8 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
|
|
||||||
const collectionOffer = this._getOfferForCollection(offerInfoPromise.valueOf(), collectionDataModel);
|
const collectionOffer = this._getOfferForCollection(offerInfoPromise.valueOf(), collectionDataModel);
|
||||||
const isDatabaseShared = this.getDatabase() && this.getDatabase().isDatabaseShared();
|
const isDatabaseShared = this.getDatabase() && this.getDatabase().isDatabaseShared();
|
||||||
if (isDatabaseShared && !collectionOffer) {
|
const isServerless = this.container.isServerlessEnabled();
|
||||||
|
if ((isDatabaseShared || isServerless) && !collectionOffer) {
|
||||||
this.quotaInfo(quotaInfo);
|
this.quotaInfo(quotaInfo);
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
Action.LoadOffers,
|
Action.LoadOffers,
|
||||||
|
@ -122,6 +122,10 @@ export default class Database implements ViewModels.Database {
|
|||||||
|
|
||||||
public readSettings(): Q.Promise<void> {
|
public readSettings(): Q.Promise<void> {
|
||||||
const deferred: Q.Deferred<void> = Q.defer<void>();
|
const deferred: Q.Deferred<void> = Q.defer<void>();
|
||||||
|
if (this.container.isServerlessEnabled()) {
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
this.container.isRefreshingExplorer(true);
|
this.container.isRefreshingExplorer(true);
|
||||||
const databaseDataModel: DataModels.Database = <DataModels.Database>{
|
const databaseDataModel: DataModels.Database = <DataModels.Database>{
|
||||||
id: this.id(),
|
id: this.id(),
|
||||||
|
@ -235,7 +235,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
children.push({
|
children.push({
|
||||||
label: database.isDatabaseShared() ? "Settings" : "Scale & Settings",
|
label: database.isDatabaseShared() || this.container.isServerlessEnabled() ? "Settings" : "Scale & Settings",
|
||||||
onClick: collection.onSettingsClick.bind(collection),
|
onClick: collection.onSettingsClick.bind(collection),
|
||||||
isSelected: () => this.isDataNodeSelected(collection.rid, "Collection", ViewModels.CollectionTabKind.Settings)
|
isSelected: () => this.isDataNodeSelected(collection.rid, "Collection", ViewModels.CollectionTabKind.Settings)
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user