mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
More ViewModel cleanup (#116)
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import AddCollectionPane from "./AddCollectionPane";
|
||||
import Explorer from "../Explorer";
|
||||
import ko from "knockout";
|
||||
import { AutopilotTier } from "../../Contracts/DataModels";
|
||||
import { AutopilotTier, DatabaseAccount } from "../../Contracts/DataModels";
|
||||
|
||||
describe("Add Collection Pane", () => {
|
||||
describe("isValid()", () => {
|
||||
let explorer: Explorer;
|
||||
const mockDatabaseAccount: ViewModels.DatabaseAccount = {
|
||||
const mockDatabaseAccount: DatabaseAccount = {
|
||||
id: "mock",
|
||||
kind: "DocumentDB",
|
||||
location: "",
|
||||
@@ -24,7 +23,7 @@ describe("Add Collection Pane", () => {
|
||||
tags: []
|
||||
};
|
||||
|
||||
const mockFreeTierDatabaseAccount: ViewModels.DatabaseAccount = {
|
||||
const mockFreeTierDatabaseAccount: DatabaseAccount = {
|
||||
id: "mock",
|
||||
kind: "DocumentDB",
|
||||
location: "",
|
||||
|
||||
@@ -22,6 +22,12 @@ import { HashMap } from "../../Common/HashMap";
|
||||
import { PlatformType } from "../../PlatformType";
|
||||
import { refreshCachedResources, getOrCreateDatabaseAndCollection } from "../../Common/DocumentClientUtilityBase";
|
||||
|
||||
export interface AddCollectionPaneOptions extends ViewModels.PaneOptions {
|
||||
isPreferredApiTable: ko.Computed<boolean>;
|
||||
databaseId?: string;
|
||||
databaseSelfLink?: string;
|
||||
}
|
||||
|
||||
export default class AddCollectionPane extends ContextualPaneBase {
|
||||
public defaultExperience: ko.Computed<string>;
|
||||
public databaseIds: ko.ObservableArray<string>;
|
||||
@@ -100,7 +106,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
private _databaseOffers: HashMap<DataModels.Offer>;
|
||||
private _isSynapseLinkEnabled: ko.Computed<boolean>;
|
||||
|
||||
constructor(options: ViewModels.AddCollectionPaneOptions) {
|
||||
constructor(options: AddCollectionPaneOptions) {
|
||||
super(options);
|
||||
this._databaseOffers = new HashMap<DataModels.Offer>();
|
||||
this.hasAutoPilotV2FeatureFlag = ko.pureComputed(() => this.container.hasAutoPilotV2FeatureFlag());
|
||||
@@ -619,7 +625,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
this._isSynapseLinkEnabled = ko.computed(() => {
|
||||
const databaseAccount =
|
||||
(this.container && this.container.databaseAccount && this.container.databaseAccount()) ||
|
||||
({} as ViewModels.DatabaseAccount);
|
||||
({} as DataModels.DatabaseAccount);
|
||||
const properties = databaseAccount.properties || ({} as DataModels.DatabaseAccountExtendedProperties);
|
||||
|
||||
// TODO: remove check for capability once all accounts have been migrated
|
||||
@@ -1266,10 +1272,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
: SharedConstants.CollectionCreation.NumberOfPartitionsInUnlimitedCollection;
|
||||
}
|
||||
|
||||
private _convertShardKeyToPartitionKey(
|
||||
shardKey: string,
|
||||
configurationOverrides: ViewModels.ConfigurationOverrides
|
||||
): string {
|
||||
private _convertShardKeyToPartitionKey(shardKey: string): string {
|
||||
if (!shardKey) {
|
||||
return shardKey;
|
||||
}
|
||||
@@ -1331,10 +1334,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
};
|
||||
if (this.container.isPreferredApiMongoDB()) {
|
||||
transform = (value: string) => {
|
||||
return this._convertShardKeyToPartitionKey(
|
||||
value,
|
||||
this.container.databaseAccount().properties.configurationOverrides
|
||||
);
|
||||
return this._convertShardKeyToPartitionKey(value);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ import * as Constants from "../../Common/Constants";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import Explorer from "../Explorer";
|
||||
import AddDatabasePane from "./AddDatabasePane";
|
||||
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||
|
||||
describe("Add Database Pane", () => {
|
||||
describe("getSharedThroughputDefault()", () => {
|
||||
let explorer: Explorer;
|
||||
const mockDatabaseAccount: ViewModels.DatabaseAccount = {
|
||||
const mockDatabaseAccount: DatabaseAccount = {
|
||||
id: "mock",
|
||||
kind: "DocumentDB",
|
||||
location: "",
|
||||
@@ -22,7 +23,7 @@ describe("Add Database Pane", () => {
|
||||
tags: []
|
||||
};
|
||||
|
||||
const mockFreeTierDatabaseAccount: ViewModels.DatabaseAccount = {
|
||||
const mockFreeTierDatabaseAccount: DatabaseAccount = {
|
||||
id: "mock",
|
||||
kind: "DocumentDB",
|
||||
location: "",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { QueriesGridComponentAdapter } from "../Controls/QueriesGridReactComponent/QueriesGridComponentAdapter";
|
||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import QueryTab from "../Tabs/QueryTab";
|
||||
|
||||
export class BrowseQueriesPane extends ContextualPaneBase {
|
||||
public queriesGridComponentAdapter: QueriesGridComponentAdapter;
|
||||
@@ -87,7 +88,7 @@ export class BrowseQueriesPane extends ContextualPaneBase {
|
||||
} else {
|
||||
selectedCollection.onNewQueryClick(selectedCollection, null);
|
||||
}
|
||||
const queryTab: ViewModels.QueryTab = this.container.tabsManager.activeTab() as ViewModels.QueryTab;
|
||||
const queryTab = this.container.tabsManager.activeTab() as QueryTab;
|
||||
queryTab.tabTitle(savedQuery.queryName);
|
||||
queryTab.tabPath(`${selectedCollection.databaseId}>${selectedCollection.id()}>${savedQuery.queryName}`);
|
||||
queryTab.initialEditorContent(savedQuery.query);
|
||||
|
||||
@@ -8,7 +8,7 @@ import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import Explorer from "../Explorer";
|
||||
|
||||
// TODO: Use specific actions for logging telemetry data
|
||||
export abstract class ContextualPaneBase extends WaitsForTemplateViewModel implements ViewModels.ContextualPane {
|
||||
export abstract class ContextualPaneBase extends WaitsForTemplateViewModel {
|
||||
public id: string;
|
||||
public container: Explorer;
|
||||
public firstFieldHasFocus: ko.Observable<boolean>;
|
||||
|
||||
@@ -106,10 +106,10 @@ describe("Delete Collection Confirmation Pane", () => {
|
||||
fakeExplorer.isSelectedDatabaseShared = () => false;
|
||||
const SubscriptionId = "testId";
|
||||
const AccountName = "testAccount";
|
||||
fakeExplorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
|
||||
fakeExplorer.databaseAccount = ko.observable<DataModels.DatabaseAccount>({
|
||||
id: SubscriptionId,
|
||||
name: AccountName
|
||||
} as ViewModels.DatabaseAccount);
|
||||
} as DataModels.DatabaseAccount);
|
||||
|
||||
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
||||
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
||||
|
||||
@@ -66,9 +66,7 @@ export default class DeleteCollectionConfirmationPane extends ContextualPaneBase
|
||||
this.isExecuting(false);
|
||||
this.close();
|
||||
this.container.selectedNode(selectedCollection.database);
|
||||
this.container.tabsManager?.closeTabsByComparator(
|
||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === selectedCollection.rid
|
||||
);
|
||||
this.container.tabsManager?.closeTabsByComparator(tab => tab.node && tab.node.rid === selectedCollection.rid);
|
||||
this.container.refreshAllDatabases();
|
||||
this.resetData();
|
||||
TelemetryProcessor.traceSuccess(
|
||||
|
||||
@@ -97,10 +97,10 @@ describe("Delete Database Confirmation Pane", () => {
|
||||
fakeExplorer.isSelectedDatabaseShared = () => false;
|
||||
const SubscriptionId = "testId";
|
||||
const AccountName = "testAccount";
|
||||
fakeExplorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
|
||||
fakeExplorer.databaseAccount = ko.observable<DataModels.DatabaseAccount>({
|
||||
id: SubscriptionId,
|
||||
name: AccountName
|
||||
} as ViewModels.DatabaseAccount);
|
||||
} as DataModels.DatabaseAccount);
|
||||
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
||||
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
||||
return false;
|
||||
|
||||
@@ -67,16 +67,12 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
|
||||
this.isExecuting(false);
|
||||
this.close();
|
||||
this.container.refreshAllDatabases();
|
||||
this.container.tabsManager.closeTabsByComparator(
|
||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === selectedDatabase.rid
|
||||
);
|
||||
this.container.tabsManager.closeTabsByComparator(tab => tab.node && tab.node.rid === selectedDatabase.rid);
|
||||
this.container.selectedNode(null);
|
||||
selectedDatabase
|
||||
.collections()
|
||||
.forEach((collection: ViewModels.Collection) =>
|
||||
this.container.tabsManager.closeTabsByComparator(
|
||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === collection.rid
|
||||
)
|
||||
this.container.tabsManager.closeTabsByComparator(tab => tab.node && tab.node.rid === collection.rid)
|
||||
);
|
||||
this.resetData();
|
||||
TelemetryProcessor.traceSuccess(
|
||||
|
||||
@@ -16,6 +16,11 @@ import { BranchesProps, PinnedReposProps, UnpinnedReposProps } from "../Controls
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
|
||||
interface GitHubReposPaneOptions extends ViewModels.PaneOptions {
|
||||
gitHubClient: GitHubClient;
|
||||
junoClient: JunoClient;
|
||||
}
|
||||
|
||||
export class GitHubReposPane extends ContextualPaneBase {
|
||||
private static readonly PageSize = 30;
|
||||
|
||||
@@ -33,7 +38,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
||||
private pinnedReposUpdated: boolean;
|
||||
|
||||
constructor(options: ViewModels.GitHubReposPaneOptions) {
|
||||
constructor(options: GitHubReposPaneOptions) {
|
||||
super(options);
|
||||
|
||||
this.gitHubClient = options.gitHubClient;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||
import QueryTab from "../Tabs/QueryTab";
|
||||
|
||||
export class LoadQueryPane extends ContextualPaneBase {
|
||||
public selectedFilesTitle: ko.Observable<string>;
|
||||
@@ -111,7 +112,7 @@ export class LoadQueryPane extends ContextualPaneBase {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (evt: any): void => {
|
||||
const fileData: string = evt.target.result;
|
||||
const queryTab: ViewModels.QueryTab = this.container.tabsManager.activeTab() as ViewModels.QueryTab;
|
||||
const queryTab = this.container.tabsManager.activeTab() as QueryTab;
|
||||
queryTab.initialEditorContent(fileData);
|
||||
queryTab.sqlQueryEditorContent(fileData);
|
||||
deferred.resolve();
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import QueryTab from "../Tabs/QueryTab";
|
||||
|
||||
export class SaveQueryPane extends ContextualPaneBase {
|
||||
public queryName: ko.Observable<string>;
|
||||
@@ -34,8 +35,7 @@ export class SaveQueryPane extends ContextualPaneBase {
|
||||
}
|
||||
|
||||
const queryName: string = this.queryName();
|
||||
const queryTab: ViewModels.QueryTab =
|
||||
this.container && (this.container.tabsManager.activeTab() as ViewModels.QueryTab);
|
||||
const queryTab = this.container && (this.container.tabsManager.activeTab() as QueryTab);
|
||||
const query: string = queryTab && queryTab.sqlQueryEditorContent();
|
||||
if (!queryName || queryName.length === 0) {
|
||||
this.formErrors("No query name specified");
|
||||
|
||||
@@ -5,11 +5,22 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||
|
||||
export interface StringInputPaneOpenOptions {
|
||||
paneTitle: string;
|
||||
inputLabel: string;
|
||||
errorMessage: string;
|
||||
inProgressMessage: string;
|
||||
successMessage: string;
|
||||
onSubmit: (input: string) => Promise<any>;
|
||||
submitButtonLabel: string;
|
||||
defaultInput?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic pane to get a single string input from user
|
||||
*/
|
||||
export class StringInputPane extends ContextualPaneBase {
|
||||
private openOptions: ViewModels.StringInputPaneOpenOptions;
|
||||
private openOptions: StringInputPaneOpenOptions;
|
||||
private submitButtonLabel: ko.Observable<string>;
|
||||
private inputLabel: ko.Observable<string>;
|
||||
private stringInput: ko.Observable<string>;
|
||||
@@ -78,7 +89,7 @@ export class StringInputPane extends ContextualPaneBase {
|
||||
this.resetFileInput();
|
||||
}
|
||||
|
||||
public openWithOptions<T>(options: ViewModels.StringInputPaneOpenOptions): Q.Promise<T> {
|
||||
public openWithOptions<T>(options: StringInputPaneOpenOptions): Q.Promise<T> {
|
||||
this.openOptions = options;
|
||||
this.title(this.openOptions.paneTitle);
|
||||
if (this.openOptions.submitButtonLabel) {
|
||||
|
||||
@@ -5,10 +5,21 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||
|
||||
export interface UploadFilePaneOpenOptions {
|
||||
paneTitle: string;
|
||||
selectFileInputLabel: string;
|
||||
errorMessage: string; // Could not upload notebook
|
||||
inProgressMessage: string; // Uploading notebook
|
||||
successMessage: string; // Successfully uploaded notebook
|
||||
onSubmit: (file: File) => Promise<any>;
|
||||
extensions?: string; // input accept field. E.g: .ipynb
|
||||
submitButtonLabel?: string;
|
||||
}
|
||||
|
||||
export class UploadFilePane extends ContextualPaneBase {
|
||||
public selectedFilesTitle: ko.Observable<string>;
|
||||
public files: ko.Observable<FileList>;
|
||||
private openOptions: ViewModels.UploadFilePaneOpenOptions;
|
||||
private openOptions: UploadFilePaneOpenOptions;
|
||||
private submitButtonLabel: ko.Observable<string>;
|
||||
private selectFileInputLabel: ko.Observable<string>;
|
||||
private extensions: ko.Observable<string>;
|
||||
@@ -79,7 +90,7 @@ export class UploadFilePane extends ContextualPaneBase {
|
||||
this.resetFileInput();
|
||||
}
|
||||
|
||||
public openWithOptions(options: ViewModels.UploadFilePaneOpenOptions): void {
|
||||
public openWithOptions(options: UploadFilePaneOpenOptions): void {
|
||||
this.openOptions = options;
|
||||
this.title(this.openOptions.paneTitle);
|
||||
if (this.openOptions.submitButtonLabel) {
|
||||
|
||||
Reference in New Issue
Block a user