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:
Tanuj Mittal 2020-07-24 13:13:54 -07:00 committed by GitHub
parent dc67c5f40b
commit 33969581ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 171 additions and 91 deletions

View File

@ -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 {

View File

@ -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(
() => { () => {

View File

@ -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">

View File

@ -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() {

View File

@ -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>

View File

@ -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 {

View File

@ -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">

View File

@ -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 {

View File

@ -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,

View File

@ -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(),

View File

@ -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)
}); });