mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 00:41:31 +00:00
Move database settings tab to react (#386)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
@@ -26,7 +26,7 @@ import MongoQueryTab from "../Tabs/MongoQueryTab";
|
||||
import MongoShellTab from "../Tabs/MongoShellTab";
|
||||
import QueryTab from "../Tabs/QueryTab";
|
||||
import QueryTablesTab from "../Tabs/QueryTablesTab";
|
||||
import SettingsTabV2 from "../Tabs/SettingsTabV2";
|
||||
import { CollectionSettingsTabV2 } from "../Tabs/SettingsTabV2";
|
||||
import ConflictId from "./ConflictId";
|
||||
import DocumentId from "./DocumentId";
|
||||
import StoredProcedure from "./StoredProcedure";
|
||||
@@ -544,10 +544,12 @@ export default class Collection implements ViewModels.Collection {
|
||||
});
|
||||
|
||||
const tabTitle = !this.offer() ? "Settings" : "Scale & Settings";
|
||||
const pendingNotificationsPromise: Promise<DataModels.Notification> = this._getPendingThroughputSplitNotification();
|
||||
const matchingTabs = this.container.tabsManager.getTabs(ViewModels.CollectionTabKind.SettingsV2, (tab) => {
|
||||
return tab.collection && tab.collection.databaseId === this.databaseId && tab.collection.id() === this.id();
|
||||
});
|
||||
const matchingTabs = this.container.tabsManager.getTabs(
|
||||
ViewModels.CollectionTabKind.CollectionSettingsV2,
|
||||
(tab) => {
|
||||
return tab.collection && tab.collection.databaseId === this.databaseId && tab.collection.id() === this.id();
|
||||
}
|
||||
);
|
||||
|
||||
const traceStartData = {
|
||||
databaseAccountName: this.container.databaseAccount().name,
|
||||
@@ -569,26 +571,20 @@ export default class Collection implements ViewModels.Collection {
|
||||
onUpdateTabsButtons: this.container.onUpdateTabsButtons,
|
||||
};
|
||||
|
||||
let settingsTabV2 = matchingTabs && (matchingTabs[0] as SettingsTabV2);
|
||||
this.launchSettingsTabV2(settingsTabV2, traceStartData, settingsTabOptions, pendingNotificationsPromise);
|
||||
let settingsTabV2 = matchingTabs && (matchingTabs[0] as CollectionSettingsTabV2);
|
||||
this.launchSettingsTabV2(settingsTabV2, traceStartData, settingsTabOptions);
|
||||
};
|
||||
|
||||
private launchSettingsTabV2 = (
|
||||
settingsTabV2: SettingsTabV2,
|
||||
settingsTabV2: CollectionSettingsTabV2,
|
||||
traceStartData: any,
|
||||
settingsTabOptions: ViewModels.TabOptions,
|
||||
getPendingNotification: Promise<DataModels.Notification>
|
||||
settingsTabOptions: ViewModels.TabOptions
|
||||
): void => {
|
||||
const settingsTabV2Options: ViewModels.SettingsTabV2Options = {
|
||||
...settingsTabOptions,
|
||||
getPendingNotification: getPendingNotification,
|
||||
};
|
||||
|
||||
if (!settingsTabV2) {
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.Tab, traceStartData);
|
||||
settingsTabV2Options.onLoadStartKey = startKey;
|
||||
settingsTabV2Options.tabKind = ViewModels.CollectionTabKind.SettingsV2;
|
||||
settingsTabV2 = new SettingsTabV2(settingsTabV2Options);
|
||||
settingsTabOptions.onLoadStartKey = startKey;
|
||||
settingsTabOptions.tabKind = ViewModels.CollectionTabKind.CollectionSettingsV2;
|
||||
settingsTabV2 = new CollectionSettingsTabV2(settingsTabOptions);
|
||||
this.container.tabsManager.activateNewTab(settingsTabV2);
|
||||
} else {
|
||||
this.container.tabsManager.activateTab(settingsTabV2);
|
||||
@@ -1040,6 +1036,41 @@ export default class Collection implements ViewModels.Collection {
|
||||
});
|
||||
};
|
||||
|
||||
public async getPendingThroughputSplitNotification(): Promise<DataModels.Notification> {
|
||||
if (!this.container) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const notifications: DataModels.Notification[] = await fetchPortalNotifications();
|
||||
if (!notifications || notifications.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return _.find(notifications, (notification: DataModels.Notification) => {
|
||||
const throughputUpdateRegExp: RegExp = new RegExp("Throughput update (.*) in progress");
|
||||
return (
|
||||
notification.kind === "message" &&
|
||||
notification.collectionName === this.id() &&
|
||||
notification.description &&
|
||||
throughputUpdateRegExp.test(notification.description)
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
Logger.logError(
|
||||
JSON.stringify({
|
||||
error: getErrorMessage(error),
|
||||
accountName: this.container && this.container.databaseAccount(),
|
||||
databaseName: this.databaseId,
|
||||
collectionName: this.id(),
|
||||
}),
|
||||
"Settings tree node"
|
||||
);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async _uploadFilesCors(files: FileList): Promise<UploadDetails> {
|
||||
const data = await Promise.all(Array.from(files).map((file) => this._uploadFile(file)));
|
||||
|
||||
@@ -1100,37 +1131,6 @@ export default class Collection implements ViewModels.Collection {
|
||||
}
|
||||
}
|
||||
|
||||
private async _getPendingThroughputSplitNotification(): Promise<DataModels.Notification> {
|
||||
if (!this.container) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const throughputUpdateRegExp = new RegExp("Throughput update (.*) in progress");
|
||||
try {
|
||||
const notifications = await fetchPortalNotifications();
|
||||
if (!notifications) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return notifications.find(
|
||||
({ kind, collectionName, description = "" }) =>
|
||||
kind === "message" && collectionName === this.id() && throughputUpdateRegExp.test(description)
|
||||
);
|
||||
} catch (error) {
|
||||
Logger.logError(
|
||||
JSON.stringify({
|
||||
error: getErrorMessage(error),
|
||||
accountName: this.container && this.container.databaseAccount(),
|
||||
databaseName: this.databaseId,
|
||||
collectionName: this.id(),
|
||||
}),
|
||||
"Settings tree node"
|
||||
);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _logUploadDetailsInConsole(uploadDetails: UploadDetails): void {
|
||||
const uploadDetailsRecords: UploadDetailsRecord[] = uploadDetails.data;
|
||||
const numFiles: number = uploadDetailsRecords.length;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as _ from "underscore";
|
||||
import * as ko from "knockout";
|
||||
import Q from "q";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import DatabaseSettingsTab from "../Tabs/DatabaseSettingsTab";
|
||||
import { DatabaseSettingsTabV2 } from "../Tabs/SettingsTabV2";
|
||||
import Collection from "./Collection";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
|
||||
@@ -16,7 +16,6 @@ import { readCollections } from "../../Common/dataAccess/readCollections";
|
||||
import { JunoClient, IJunoResponse } from "../../Juno/JunoClient";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { readDatabaseOffer } from "../../Common/dataAccess/readDatabaseOffer";
|
||||
import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType";
|
||||
import { fetchPortalNotifications } from "../../Common/PortalNotifications";
|
||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||
|
||||
@@ -59,12 +58,17 @@ export default class Database implements ViewModels.Database {
|
||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||
});
|
||||
|
||||
const pendingNotificationsPromise: Q.Promise<DataModels.Notification> = this._getPendingThroughputSplitNotification();
|
||||
const matchingTabs = this.container.tabsManager.getTabs(
|
||||
ViewModels.CollectionTabKind.DatabaseSettings,
|
||||
(tab) => tab.node?.id() === this.id()
|
||||
const pendingNotificationsPromise: Promise<DataModels.Notification> = this.getPendingThroughputSplitNotification();
|
||||
const useDatabaseSettingsTabV1: boolean = this.container.isFeatureEnabled(
|
||||
Constants.Features.enableDatabaseSettingsTabV1
|
||||
);
|
||||
let settingsTab: DatabaseSettingsTab = matchingTabs && (matchingTabs[0] as DatabaseSettingsTab);
|
||||
const tabKind: ViewModels.CollectionTabKind = useDatabaseSettingsTabV1
|
||||
? ViewModels.CollectionTabKind.DatabaseSettings
|
||||
: ViewModels.CollectionTabKind.DatabaseSettingsV2;
|
||||
const matchingTabs = this.container.tabsManager.getTabs(tabKind, (tab) => tab.node?.id() === this.id());
|
||||
let settingsTab: DatabaseSettingsTab | DatabaseSettingsTabV2 = useDatabaseSettingsTabV1
|
||||
? (matchingTabs?.[0] as DatabaseSettingsTab)
|
||||
: (matchingTabs?.[0] as DatabaseSettingsTabV2);
|
||||
if (!settingsTab) {
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.Tab, {
|
||||
databaseAccountName: this.container.databaseAccount().name,
|
||||
@@ -75,9 +79,11 @@ export default class Database implements ViewModels.Database {
|
||||
});
|
||||
pendingNotificationsPromise.then(
|
||||
(data: any) => {
|
||||
const pendingNotification: DataModels.Notification = data && data[0];
|
||||
settingsTab = new DatabaseSettingsTab({
|
||||
tabKind: ViewModels.CollectionTabKind.DatabaseSettings,
|
||||
const pendingNotification: DataModels.Notification = data?.[0];
|
||||
const tabOptions: ViewModels.TabOptions = {
|
||||
tabKind: useDatabaseSettingsTabV1
|
||||
? ViewModels.CollectionTabKind.DatabaseSettings
|
||||
: ViewModels.CollectionTabKind.DatabaseSettingsV2,
|
||||
title: "Scale",
|
||||
tabPath: "",
|
||||
node: this,
|
||||
@@ -87,8 +93,10 @@ export default class Database implements ViewModels.Database {
|
||||
isActive: ko.observable(false),
|
||||
onLoadStartKey: startKey,
|
||||
onUpdateTabsButtons: this.container.onUpdateTabsButtons,
|
||||
});
|
||||
|
||||
};
|
||||
settingsTab = useDatabaseSettingsTabV1
|
||||
? new DatabaseSettingsTab(tabOptions)
|
||||
: new DatabaseSettingsTabV2(tabOptions);
|
||||
settingsTab.pendingNotification(pendingNotification);
|
||||
this.container.tabsManager.activateNewTab(settingsTab);
|
||||
},
|
||||
@@ -221,47 +229,40 @@ export default class Database implements ViewModels.Database {
|
||||
}
|
||||
}
|
||||
|
||||
private _getPendingThroughputSplitNotification(): Q.Promise<DataModels.Notification> {
|
||||
public async getPendingThroughputSplitNotification(): Promise<DataModels.Notification> {
|
||||
if (!this.container) {
|
||||
return Q.resolve(undefined);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const deferred: Q.Deferred<DataModels.Notification> = Q.defer<DataModels.Notification>();
|
||||
fetchPortalNotifications().then(
|
||||
(notifications) => {
|
||||
if (!notifications || notifications.length === 0) {
|
||||
deferred.resolve(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
const pendingNotification = _.find(notifications, (notification: DataModels.Notification) => {
|
||||
const throughputUpdateRegExp: RegExp = new RegExp("Throughput update (.*) in progress");
|
||||
return (
|
||||
notification.kind === "message" &&
|
||||
!notification.collectionName &&
|
||||
notification.databaseName === this.id() &&
|
||||
notification.description &&
|
||||
throughputUpdateRegExp.test(notification.description)
|
||||
);
|
||||
});
|
||||
|
||||
deferred.resolve(pendingNotification);
|
||||
},
|
||||
(error: any) => {
|
||||
Logger.logError(
|
||||
JSON.stringify({
|
||||
error: getErrorMessage(error),
|
||||
accountName: this.container && this.container.databaseAccount(),
|
||||
databaseName: this.id(),
|
||||
collectionName: this.id(),
|
||||
}),
|
||||
"Settings tree node"
|
||||
);
|
||||
deferred.resolve(undefined);
|
||||
try {
|
||||
const notifications: DataModels.Notification[] = await fetchPortalNotifications();
|
||||
if (!notifications || notifications.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
return _.find(notifications, (notification: DataModels.Notification) => {
|
||||
const throughputUpdateRegExp: RegExp = new RegExp("Throughput update (.*) in progress");
|
||||
return (
|
||||
notification.kind === "message" &&
|
||||
!notification.collectionName &&
|
||||
notification.databaseName === this.id() &&
|
||||
notification.description &&
|
||||
throughputUpdateRegExp.test(notification.description)
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
Logger.logError(
|
||||
JSON.stringify({
|
||||
error: getErrorMessage(error),
|
||||
accountName: this.container && this.container.databaseAccount(),
|
||||
databaseName: this.id(),
|
||||
collectionName: this.id(),
|
||||
}),
|
||||
"Settings tree node"
|
||||
);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private getDeltaCollections(
|
||||
|
||||
Reference in New Issue
Block a user