More ViewModel cleanup (#116)
This commit is contained in:
parent
2e49ed45c3
commit
fea321cd68
|
@ -42,7 +42,7 @@ module.exports = {
|
||||||
branches: 19.5,
|
branches: 19.5,
|
||||||
functions: 24,
|
functions: 24,
|
||||||
lines: 29.5,
|
lines: 29.5,
|
||||||
statements: 28.5
|
statements: 29.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
|
||||||
|
|
||||||
export class DefaultApi implements ViewModels.CosmosDbApi {
|
|
||||||
public isSystemDatabasePredicate = (database: ViewModels.Database): boolean => {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CassandraApi implements ViewModels.CosmosDbApi {
|
|
||||||
public isSystemDatabasePredicate = (database: ViewModels.Database): boolean => {
|
|
||||||
return database.id() === "system";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -27,6 +27,8 @@ import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||||
import { Platform, config } from "../Config";
|
import { Platform, config } from "../Config";
|
||||||
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||||
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
|
import ConflictId from "../Explorer/Tree/ConflictId";
|
||||||
|
|
||||||
export function getCommonQueryOptions(options: FeedOptions): any {
|
export function getCommonQueryOptions(options: FeedOptions): any {
|
||||||
const storedItemPerPageSetting: number = LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage);
|
const storedItemPerPageSetting: number = LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage);
|
||||||
|
@ -169,7 +171,7 @@ export function executeStoredProcedure(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
|
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
|
||||||
const partitionKey = documentId.partitionKeyValue;
|
const partitionKey = documentId.partitionKeyValue;
|
||||||
|
|
||||||
return Q(
|
return Q(
|
||||||
|
@ -182,7 +184,7 @@ export function readDocument(collection: ViewModels.CollectionBase, documentId:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPartitionKeyHeaderForConflict(conflictId: ViewModels.ConflictId): Object {
|
export function getPartitionKeyHeaderForConflict(conflictId: ConflictId): Object {
|
||||||
const partitionKeyDefinition: DataModels.PartitionKey = conflictId.partitionKey;
|
const partitionKeyDefinition: DataModels.PartitionKey = conflictId.partitionKey;
|
||||||
const partitionKeyValue: any = conflictId.partitionKeyValue;
|
const partitionKeyValue: any = conflictId.partitionKeyValue;
|
||||||
|
|
||||||
|
@ -220,7 +222,7 @@ export function updateCollection(
|
||||||
|
|
||||||
export function updateDocument(
|
export function updateDocument(
|
||||||
collection: ViewModels.CollectionBase,
|
collection: ViewModels.CollectionBase,
|
||||||
documentId: ViewModels.DocumentId,
|
documentId: DocumentId,
|
||||||
newDocument: any
|
newDocument: any
|
||||||
): Q.Promise<any> {
|
): Q.Promise<any> {
|
||||||
const partitionKey = documentId.partitionKeyValue;
|
const partitionKey = documentId.partitionKeyValue;
|
||||||
|
@ -347,10 +349,7 @@ export function createTrigger(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteDocument(
|
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
|
||||||
collection: ViewModels.CollectionBase,
|
|
||||||
documentId: ViewModels.DocumentId
|
|
||||||
): Q.Promise<any> {
|
|
||||||
const partitionKey = documentId.partitionKeyValue;
|
const partitionKey = documentId.partitionKeyValue;
|
||||||
|
|
||||||
return Q(
|
return Q(
|
||||||
|
@ -364,7 +363,7 @@ export function deleteDocument(
|
||||||
|
|
||||||
export function deleteConflict(
|
export function deleteConflict(
|
||||||
collection: ViewModels.CollectionBase,
|
collection: ViewModels.CollectionBase,
|
||||||
conflictId: ViewModels.ConflictId,
|
conflictId: ConflictId,
|
||||||
options: any = {}
|
options: any = {}
|
||||||
): Q.Promise<any> {
|
): Q.Promise<any> {
|
||||||
options.partitionKey = options.partitionKey || getPartitionKeyHeaderForConflict(conflictId);
|
options.partitionKey = options.partitionKey || getPartitionKeyHeaderForConflict(conflictId);
|
||||||
|
|
|
@ -13,6 +13,8 @@ import { MinimalQueryIterator, nextPage } from "./IteratorUtilities";
|
||||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||||
|
import ConflictId from "../Explorer/Tree/ConflictId";
|
||||||
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
|
|
||||||
// TODO: Log all promise resolutions and errors with verbosity levels
|
// TODO: Log all promise resolutions and errors with verbosity levels
|
||||||
export function queryDocuments(
|
export function queryDocuments(
|
||||||
|
@ -236,7 +238,7 @@ export function queryDocumentsPage(
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
|
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
|
||||||
var deferred = Q.defer<any>();
|
var deferred = Q.defer<any>();
|
||||||
const entityName = getEntityName();
|
const entityName = getEntityName();
|
||||||
const id = NotificationConsoleUtils.logConsoleMessage(
|
const id = NotificationConsoleUtils.logConsoleMessage(
|
||||||
|
@ -303,7 +305,7 @@ export function updateCollection(
|
||||||
|
|
||||||
export function updateDocument(
|
export function updateDocument(
|
||||||
collection: ViewModels.CollectionBase,
|
collection: ViewModels.CollectionBase,
|
||||||
documentId: ViewModels.DocumentId,
|
documentId: DocumentId,
|
||||||
newDocument: any
|
newDocument: any
|
||||||
): Q.Promise<any> {
|
): Q.Promise<any> {
|
||||||
var deferred = Q.defer<any>();
|
var deferred = Q.defer<any>();
|
||||||
|
@ -658,10 +660,7 @@ export function createTrigger(
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteDocument(
|
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
|
||||||
collection: ViewModels.CollectionBase,
|
|
||||||
documentId: ViewModels.DocumentId
|
|
||||||
): Q.Promise<any> {
|
|
||||||
var deferred = Q.defer<any>();
|
var deferred = Q.defer<any>();
|
||||||
const entityName = getEntityName();
|
const entityName = getEntityName();
|
||||||
const id = NotificationConsoleUtils.logConsoleMessage(
|
const id = NotificationConsoleUtils.logConsoleMessage(
|
||||||
|
@ -696,7 +695,7 @@ export function deleteDocument(
|
||||||
|
|
||||||
export function deleteConflict(
|
export function deleteConflict(
|
||||||
collection: ViewModels.CollectionBase,
|
collection: ViewModels.CollectionBase,
|
||||||
conflictId: ViewModels.ConflictId,
|
conflictId: ConflictId,
|
||||||
options?: any
|
options?: any
|
||||||
): Q.Promise<any> {
|
): Q.Promise<any> {
|
||||||
var deferred = Q.defer<any>();
|
var deferred = Q.defer<any>();
|
||||||
|
|
|
@ -7,10 +7,12 @@ import {
|
||||||
updateDocument
|
updateDocument
|
||||||
} from "./MongoProxyClient";
|
} from "./MongoProxyClient";
|
||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { Collection, DatabaseAccount, DocumentId } from "../Contracts/ViewModels";
|
import { Collection } from "../Contracts/ViewModels";
|
||||||
import { config } from "../Config";
|
import { config } from "../Config";
|
||||||
import { CosmosClient } from "./CosmosClient";
|
import { CosmosClient } from "./CosmosClient";
|
||||||
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
||||||
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
|
import { DatabaseAccount } from "../Contracts/DataModels";
|
||||||
jest.mock("../ResourceProvider/ResourceProviderClient.ts");
|
jest.mock("../ResourceProvider/ResourceProviderClient.ts");
|
||||||
|
|
||||||
const databaseId = "testDB";
|
const databaseId = "testDB";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import * as Constants from "../Common/Constants";
|
import * as Constants from "../Common/Constants";
|
||||||
import * as DataExplorerConstants from "../Common/Constants";
|
import * as DataExplorerConstants from "../Common/Constants";
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
|
||||||
import EnvironmentUtility from "./EnvironmentUtility";
|
import EnvironmentUtility from "./EnvironmentUtility";
|
||||||
import queryString from "querystring";
|
import queryString from "querystring";
|
||||||
import { AddDbUtilities } from "../Shared/AddDatabaseUtility";
|
import { AddDbUtilities } from "../Shared/AddDatabaseUtility";
|
||||||
|
@ -17,6 +16,7 @@ import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||||
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
||||||
import { MinimalQueryIterator } from "./IteratorUtilities";
|
import { MinimalQueryIterator } from "./IteratorUtilities";
|
||||||
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
|
|
||||||
const defaultHeaders = {
|
const defaultHeaders = {
|
||||||
[HttpHeaders.apiType]: ApiType.MongoDB.toString(),
|
[HttpHeaders.apiType]: ApiType.MongoDB.toString(),
|
||||||
|
@ -123,7 +123,7 @@ export function queryDocuments(
|
||||||
export function readDocument(
|
export function readDocument(
|
||||||
databaseId: string,
|
databaseId: string,
|
||||||
collection: Collection,
|
collection: Collection,
|
||||||
documentId: ViewModels.DocumentId
|
documentId: DocumentId
|
||||||
): Promise<DataModels.DocumentId> {
|
): Promise<DataModels.DocumentId> {
|
||||||
const databaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
|
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
|
||||||
|
@ -205,7 +205,7 @@ export function createDocument(
|
||||||
export function updateDocument(
|
export function updateDocument(
|
||||||
databaseId: string,
|
databaseId: string,
|
||||||
collection: Collection,
|
collection: Collection,
|
||||||
documentId: ViewModels.DocumentId,
|
documentId: DocumentId,
|
||||||
documentContent: unknown
|
documentContent: unknown
|
||||||
): Promise<DataModels.DocumentId> {
|
): Promise<DataModels.DocumentId> {
|
||||||
const databaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
|
@ -246,11 +246,7 @@ export function updateDocument(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteDocument(
|
export function deleteDocument(databaseId: string, collection: Collection, documentId: DocumentId): Promise<void> {
|
||||||
databaseId: string,
|
|
||||||
collection: Collection,
|
|
||||||
documentId: ViewModels.DocumentId
|
|
||||||
): Promise<void> {
|
|
||||||
const databaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
|
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
|
||||||
const idComponents = documentId.self.split("/");
|
const idComponents = documentId.self.split("/");
|
||||||
|
@ -385,7 +381,7 @@ export function createMongoCollectionWithARM(
|
||||||
return _createMongoCollectionWithARM(armEndpoint, params, additionalOptions);
|
return _createMongoCollectionWithARM(armEndpoint, params, additionalOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEndpoint(databaseAccount: ViewModels.DatabaseAccount): string {
|
export function getEndpoint(databaseAccount: DataModels.DatabaseAccount): string {
|
||||||
const serverId = window.dataExplorer.serverId();
|
const serverId = window.dataExplorer.serverId();
|
||||||
const extensionEndpoint = window.dataExplorer.extensionEndpoint();
|
const extensionEndpoint = window.dataExplorer.extensionEndpoint();
|
||||||
let url = config.MONGO_BACKEND_ENDPOINT
|
let url = config.MONGO_BACKEND_ENDPOINT
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as ViewModels from "../Contracts/ViewModels";
|
||||||
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||||
import { CosmosClient } from "./CosmosClient";
|
import { CosmosClient } from "./CosmosClient";
|
||||||
|
|
||||||
export class NotificationsClientBase implements ViewModels.NotificationsClient {
|
export class NotificationsClientBase {
|
||||||
private _extensionEndpoint: string;
|
private _extensionEndpoint: string;
|
||||||
private _notificationsApiSuffix: string;
|
private _notificationsApiSuffix: string;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export class NotificationsClientBase implements ViewModels.NotificationsClient {
|
||||||
|
|
||||||
public fetchNotifications(): Q.Promise<DataModels.Notification[]> {
|
public fetchNotifications(): Q.Promise<DataModels.Notification[]> {
|
||||||
const deferred: Q.Deferred<DataModels.Notification[]> = Q.defer<DataModels.Notification[]>();
|
const deferred: Q.Deferred<DataModels.Notification[]> = Q.defer<DataModels.Notification[]>();
|
||||||
const databaseAccount: ViewModels.DatabaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
const subscriptionId: string = CosmosClient.subscriptionId();
|
const subscriptionId: string = CosmosClient.subscriptionId();
|
||||||
const resourceGroup: string = CosmosClient.resourceGroup();
|
const resourceGroup: string = CosmosClient.resourceGroup();
|
||||||
const url: string = `${this._extensionEndpoint}${this._notificationsApiSuffix}?accountName=${databaseAccount.name}&subscriptionId=${subscriptionId}&resourceGroup=${resourceGroup}`;
|
const url: string = `${this._extensionEndpoint}${this._notificationsApiSuffix}?accountName=${databaseAccount.name}&subscriptionId=${subscriptionId}&resourceGroup=${resourceGroup}`;
|
||||||
|
|
|
@ -18,8 +18,9 @@ import {
|
||||||
queryDocumentsPage,
|
queryDocumentsPage,
|
||||||
deleteDocument
|
deleteDocument
|
||||||
} from "./DocumentClientUtilityBase";
|
} from "./DocumentClientUtilityBase";
|
||||||
|
import DocumentsTab from "../Explorer/Tabs/DocumentsTab";
|
||||||
|
|
||||||
export class QueriesClient implements ViewModels.QueriesClient {
|
export class QueriesClient {
|
||||||
private static readonly PartitionKey: DataModels.PartitionKey = {
|
private static readonly PartitionKey: DataModels.PartitionKey = {
|
||||||
paths: [`/${SavedQueries.PartitionKeyProperty}`],
|
paths: [`/${SavedQueries.PartitionKeyProperty}`],
|
||||||
kind: BackendDefaults.partitionKeyKind,
|
kind: BackendDefaults.partitionKeyKind,
|
||||||
|
@ -216,11 +217,11 @@ export class QueriesClient implements ViewModels.QueriesClient {
|
||||||
`Deleting query ${query.queryName}`
|
`Deleting query ${query.queryName}`
|
||||||
);
|
);
|
||||||
query.id = query.queryName;
|
query.id = query.queryName;
|
||||||
const documentId: ViewModels.DocumentId = new DocumentId(
|
const documentId = new DocumentId(
|
||||||
{
|
{
|
||||||
partitionKey: QueriesClient.PartitionKey,
|
partitionKey: QueriesClient.PartitionKey,
|
||||||
partitionKeyProperty: "id"
|
partitionKeyProperty: "id"
|
||||||
} as ViewModels.DocumentsTab,
|
} as DocumentsTab,
|
||||||
query,
|
query,
|
||||||
query.queryName
|
query.queryName
|
||||||
); // TODO: Remove DocumentId's dependency on DocumentsTab
|
); // TODO: Remove DocumentId's dependency on DocumentsTab
|
||||||
|
@ -248,7 +249,7 @@ export class QueriesClient implements ViewModels.QueriesClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getResourceId(): string {
|
public getResourceId(): string {
|
||||||
const databaseAccount: ViewModels.DatabaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
const databaseAccountName: string = (databaseAccount && databaseAccount.name) || "";
|
const databaseAccountName: string = (databaseAccount && databaseAccount.name) || "";
|
||||||
const subscriptionId: string = CosmosClient.subscriptionId() || "";
|
const subscriptionId: string = CosmosClient.subscriptionId() || "";
|
||||||
const resourceGroup: string = CosmosClient.resourceGroup() || "";
|
const resourceGroup: string = CosmosClient.resourceGroup() || "";
|
||||||
|
|
|
@ -1,39 +1,16 @@
|
||||||
import * as DataModels from "./DataModels";
|
import * as DataModels from "./DataModels";
|
||||||
import * as monaco from "monaco-editor";
|
|
||||||
import Q from "q";
|
import Q from "q";
|
||||||
import { AccessibleVerticalList } from "../Explorer/Tree/AccessibleVerticalList";
|
|
||||||
import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient";
|
import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient";
|
||||||
import { CommandButtonComponentProps } from "../Explorer/Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||||
import { ConsoleData } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleData } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { GitHubClient } from "../GitHub/GitHubClient";
|
|
||||||
import { JunoClient, IGalleryItem } from "../Juno/JunoClient";
|
|
||||||
import { NotebookContentItem } from "../Explorer/Notebook/NotebookContentItem";
|
|
||||||
import { QueryMetrics } from "@azure/cosmos";
|
import { QueryMetrics } from "@azure/cosmos";
|
||||||
import { UploadDetails } from "../workers/upload/definitions";
|
import { UploadDetails } from "../workers/upload/definitions";
|
||||||
import Explorer from "../Explorer/Explorer";
|
import Explorer from "../Explorer/Explorer";
|
||||||
import UserDefinedFunction from "../Explorer/Tree/UserDefinedFunction";
|
import UserDefinedFunction from "../Explorer/Tree/UserDefinedFunction";
|
||||||
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||||
import ConflictsTab from "../Explorer/Tabs/ConflictsTab";
|
|
||||||
import Trigger from "../Explorer/Tree/Trigger";
|
import Trigger from "../Explorer/Tree/Trigger";
|
||||||
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
export interface ExplorerOptions {
|
import ConflictId from "../Explorer/Tree/ConflictId";
|
||||||
notificationsClient: NotificationsClient;
|
|
||||||
isEmulator: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Capability extends DataModels.Capability {}
|
|
||||||
|
|
||||||
export interface ConfigurationOverrides extends DataModels.ConfigurationOverrides {}
|
|
||||||
|
|
||||||
export interface NavbarButtonConfig extends CommandButtonComponentProps {}
|
|
||||||
|
|
||||||
export interface DatabaseAccount extends DataModels.DatabaseAccount {}
|
|
||||||
|
|
||||||
export interface KernelConnectionMetadata {
|
|
||||||
name: string;
|
|
||||||
configurationEndpoints: DataModels.NotebookConfigurationEndpoints;
|
|
||||||
notebookConnectionInfo: DataModels.NotebookWorkspaceConnectionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TokenProvider {
|
export interface TokenProvider {
|
||||||
getAuthHeader(): Promise<Headers>;
|
getAuthHeader(): Promise<Headers>;
|
||||||
|
@ -73,11 +50,6 @@ export interface WaitsForTemplate {
|
||||||
isTemplateReady: ko.Observable<boolean>;
|
isTemplateReady: ko.Observable<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AdHocAccessData {
|
|
||||||
readWriteUrl: string;
|
|
||||||
readUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TreeNode {
|
export interface TreeNode {
|
||||||
nodeKind: string;
|
nodeKind: string;
|
||||||
rid: string;
|
rid: string;
|
||||||
|
@ -199,45 +171,6 @@ export interface Collection extends CollectionBase {
|
||||||
getLabel(): string;
|
getLabel(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DocumentId {
|
|
||||||
container: DocumentsTab;
|
|
||||||
rid: string;
|
|
||||||
self: string;
|
|
||||||
ts: string;
|
|
||||||
partitionKeyValue: any;
|
|
||||||
partitionKeyProperty: string;
|
|
||||||
partitionKey: DataModels.PartitionKey;
|
|
||||||
stringPartitionKeyValue: string;
|
|
||||||
id: ko.Observable<string>;
|
|
||||||
|
|
||||||
isDirty: ko.Observable<boolean>;
|
|
||||||
click(): void;
|
|
||||||
getPartitionKeyValueAsString(): string;
|
|
||||||
loadDocument(): Q.Promise<any>;
|
|
||||||
partitionKeyHeader(): Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConflictId {
|
|
||||||
container: ConflictsTab;
|
|
||||||
rid: string;
|
|
||||||
self: string;
|
|
||||||
ts: string;
|
|
||||||
partitionKeyValue: any;
|
|
||||||
partitionKeyProperty: string;
|
|
||||||
partitionKey: DataModels.PartitionKey;
|
|
||||||
stringPartitionKeyValue: string;
|
|
||||||
id: ko.Observable<string>;
|
|
||||||
operationType: string;
|
|
||||||
resourceId: string;
|
|
||||||
resourceType: string;
|
|
||||||
|
|
||||||
isDirty: ko.Observable<boolean>;
|
|
||||||
click(): void;
|
|
||||||
buildDocumentIdFromConflict(partitionKeyValue: any): DocumentId;
|
|
||||||
getPartitionKeyValueAsString(): string;
|
|
||||||
loadConflict(): Q.Promise<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options used to initialize pane
|
* Options used to initialize pane
|
||||||
*/
|
*/
|
||||||
|
@ -247,68 +180,6 @@ export interface PaneOptions {
|
||||||
container?: Explorer;
|
container?: Explorer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContextualPane {
|
|
||||||
formErrors: ko.Observable<string>;
|
|
||||||
formErrorsDetails: ko.Observable<string>;
|
|
||||||
id: string;
|
|
||||||
title: ko.Observable<string>;
|
|
||||||
visible: ko.Observable<boolean>;
|
|
||||||
firstFieldHasFocus: ko.Observable<boolean>;
|
|
||||||
isExecuting: ko.Observable<boolean>;
|
|
||||||
|
|
||||||
submit: () => void;
|
|
||||||
cancel: () => void;
|
|
||||||
open: () => void;
|
|
||||||
close: () => void;
|
|
||||||
resetData: () => void;
|
|
||||||
showErrorDetails: () => void;
|
|
||||||
onCloseKeyPress(source: any, event: KeyboardEvent): void;
|
|
||||||
onPaneKeyDown(source: any, event: KeyboardEvent): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GitHubReposPaneOptions extends PaneOptions {
|
|
||||||
gitHubClient: GitHubClient;
|
|
||||||
junoClient: JunoClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PublishNotebookPaneOptions extends PaneOptions {
|
|
||||||
junoClient: JunoClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PublishNotebookPaneOpenOptions {
|
|
||||||
name: string;
|
|
||||||
author: string;
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AddCollectionPaneOptions extends PaneOptions {
|
|
||||||
isPreferredApiTable: ko.Computed<boolean>;
|
|
||||||
databaseId?: string;
|
|
||||||
databaseSelfLink?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 interface StringInputPaneOpenOptions {
|
|
||||||
paneTitle: string;
|
|
||||||
inputLabel: string;
|
|
||||||
errorMessage: string;
|
|
||||||
inProgressMessage: string;
|
|
||||||
successMessage: string;
|
|
||||||
onSubmit: (input: string) => Promise<any>;
|
|
||||||
submitButtonLabel: string;
|
|
||||||
defaultInput?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Graph configuration
|
* Graph configuration
|
||||||
*/
|
*/
|
||||||
|
@ -378,19 +249,6 @@ export interface DocumentRequestContainer {
|
||||||
resourceName?: string;
|
resourceName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationsClient {
|
|
||||||
fetchNotifications(): Q.Promise<DataModels.Notification[]>;
|
|
||||||
setExtensionEndpoint(extensionEndpoint: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QueriesClient {
|
|
||||||
setupQueriesCollection(): Promise<DataModels.Collection>;
|
|
||||||
saveQuery(query: DataModels.Query): Promise<void>;
|
|
||||||
getQueries(): Promise<DataModels.Query[]>;
|
|
||||||
deleteQuery(query: DataModels.Query): Promise<void>;
|
|
||||||
getResourceId(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DocumentClientOption {
|
export interface DocumentClientOption {
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
masterKey?: string;
|
masterKey?: string;
|
||||||
|
@ -405,7 +263,7 @@ export interface TabOptions {
|
||||||
selfLink: string;
|
selfLink: string;
|
||||||
isActive: ko.Observable<boolean>;
|
isActive: ko.Observable<boolean>;
|
||||||
hashLocation: string;
|
hashLocation: string;
|
||||||
onUpdateTabsButtons: (buttons: NavbarButtonConfig[]) => void;
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]) => void;
|
||||||
isTabsContentExpanded?: ko.Observable<boolean>;
|
isTabsContentExpanded?: ko.Observable<boolean>;
|
||||||
onLoadStartKey?: number;
|
onLoadStartKey?: number;
|
||||||
|
|
||||||
|
@ -418,47 +276,6 @@ export interface TabOptions {
|
||||||
theme?: string;
|
theme?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SparkMasterTabOptions extends TabOptions {
|
|
||||||
clusterConnectionInfo: DataModels.SparkClusterConnectionInfo;
|
|
||||||
container: Explorer;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GraphTabOptions extends TabOptions {
|
|
||||||
account: DatabaseAccount;
|
|
||||||
masterKey: string;
|
|
||||||
collectionId: string;
|
|
||||||
databaseId: string;
|
|
||||||
collectionPartitionKeyProperty: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NotebookTabOptions extends TabOptions {
|
|
||||||
account: DatabaseAccount;
|
|
||||||
masterKey: string;
|
|
||||||
container: Explorer;
|
|
||||||
notebookContentItem: NotebookContentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TerminalTabOptions extends TabOptions {
|
|
||||||
account: DatabaseAccount;
|
|
||||||
container: Explorer;
|
|
||||||
kind: TerminalKind;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GalleryTabOptions extends TabOptions {
|
|
||||||
account: DatabaseAccount;
|
|
||||||
container: Explorer;
|
|
||||||
junoClient: JunoClient;
|
|
||||||
notebookUrl?: string;
|
|
||||||
galleryItem?: IGalleryItem;
|
|
||||||
isFavorite?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NotebookViewerTabOptions extends TabOptions {
|
|
||||||
account: DatabaseAccount;
|
|
||||||
container: Explorer;
|
|
||||||
notebookUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DocumentsTabOptions extends TabOptions {
|
export interface DocumentsTabOptions extends TabOptions {
|
||||||
partitionKey: DataModels.PartitionKey;
|
partitionKey: DataModels.PartitionKey;
|
||||||
documentIds: ko.ObservableArray<DocumentId>;
|
documentIds: ko.ObservableArray<DocumentId>;
|
||||||
|
@ -486,155 +303,15 @@ export interface ScriptTabOption extends TabOptions {
|
||||||
partitionKey?: DataModels.PartitionKey;
|
partitionKey?: DataModels.PartitionKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tabs
|
|
||||||
export interface Tab {
|
|
||||||
node: TreeNode; // Can be null
|
|
||||||
collection: CollectionBase;
|
|
||||||
rid: string;
|
|
||||||
tabKind: CollectionTabKind;
|
|
||||||
tabId: string;
|
|
||||||
isActive: ko.Observable<boolean>;
|
|
||||||
isMouseOver: ko.Observable<boolean>;
|
|
||||||
tabPath: ko.Observable<string>;
|
|
||||||
tabTitle: ko.Observable<string>;
|
|
||||||
hashLocation: ko.Observable<string>;
|
|
||||||
closeTabButton: Button;
|
|
||||||
onCloseTabButtonClick(): void;
|
|
||||||
onTabClick(): Q.Promise<any>;
|
|
||||||
onKeyPressActivate(source: any, event: KeyboardEvent): void;
|
|
||||||
onKeyPressClose(source: any, event: KeyboardEvent): void;
|
|
||||||
onActivate(): Q.Promise<any>;
|
|
||||||
refresh(): void;
|
|
||||||
closeButtonTabIndex: ko.Computed<number>;
|
|
||||||
isExecutionError: ko.Observable<boolean>;
|
|
||||||
isExecuting: ko.Observable<boolean>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DocumentsTab extends Tab {
|
|
||||||
/* Documents Grid */
|
|
||||||
selectDocument(documentId: DocumentId): Q.Promise<any>;
|
|
||||||
selectedDocumentId: ko.Observable<DocumentId>;
|
|
||||||
selectedDocumentContent: Editable<any>;
|
|
||||||
onDocumentIdClick(documentId: DocumentId): Q.Promise<any>;
|
|
||||||
dataContentsGridScrollHeight: ko.Observable<string>;
|
|
||||||
accessibleDocumentList: AccessibleVerticalList;
|
|
||||||
documentContentsGridId: string;
|
|
||||||
|
|
||||||
partitionKey: DataModels.PartitionKey;
|
|
||||||
idHeader: string;
|
|
||||||
partitionKeyPropertyHeader: string;
|
|
||||||
partitionKeyProperty: string;
|
|
||||||
documentIds: ko.ObservableArray<DocumentId>;
|
|
||||||
|
|
||||||
/* Documents Filter */
|
|
||||||
filterContent: ko.Observable<string>;
|
|
||||||
appliedFilter: ko.Observable<string>;
|
|
||||||
lastFilterContents: ko.ObservableArray<string>;
|
|
||||||
isFilterExpanded: ko.Observable<boolean>;
|
|
||||||
applyFilterButton: Button;
|
|
||||||
onShowFilterClick(): Q.Promise<any>;
|
|
||||||
onHideFilterClick(): Q.Promise<any>;
|
|
||||||
onApplyFilterClick(): Q.Promise<any>;
|
|
||||||
|
|
||||||
/* Document Editor */
|
|
||||||
isEditorDirty: ko.Computed<boolean>;
|
|
||||||
editorState: ko.Observable<DocumentExplorerState>;
|
|
||||||
onValidDocumentEdit(content: any): Q.Promise<any>;
|
|
||||||
onInvalidDocumentEdit(content: any): Q.Promise<any>;
|
|
||||||
|
|
||||||
onNewDocumentClick(): Q.Promise<any>;
|
|
||||||
onSaveNewDocumentClick(): Q.Promise<any>;
|
|
||||||
onRevertNewDocumentClick(): Q.Promise<any>;
|
|
||||||
onSaveExisitingDocumentClick(): Q.Promise<any>;
|
|
||||||
onRevertExisitingDocumentClick(): Q.Promise<any>;
|
|
||||||
onDeleteExisitingDocumentClick(): Q.Promise<any>;
|
|
||||||
|
|
||||||
/* Errors */
|
|
||||||
displayedError: ko.Observable<string>;
|
|
||||||
|
|
||||||
initDocumentEditor(documentId: DocumentId, content: any): Q.Promise<any>;
|
|
||||||
loadNextPage(): Q.Promise<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WaitsForTemplate {
|
export interface WaitsForTemplate {
|
||||||
isTemplateReady: ko.Observable<boolean>;
|
isTemplateReady: ko.Observable<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueryTab extends Tab {
|
|
||||||
queryEditorId: string;
|
|
||||||
isQueryMetricsEnabled: ko.Computed<boolean>;
|
|
||||||
activityId: ko.Observable<string>;
|
|
||||||
|
|
||||||
/* Command Bar */
|
|
||||||
executeQueryButton: Button;
|
|
||||||
fetchNextPageButton: Button;
|
|
||||||
saveQueryButton: Button;
|
|
||||||
onExecuteQueryClick(): Q.Promise<any>;
|
|
||||||
onFetchNextPageClick(): Q.Promise<any>;
|
|
||||||
|
|
||||||
/*Query Editor*/
|
|
||||||
initialEditorContent: ko.Observable<string>;
|
|
||||||
sqlQueryEditorContent: ko.Observable<string>;
|
|
||||||
sqlStatementToExecute: ko.Observable<string>;
|
|
||||||
|
|
||||||
/* Results */
|
|
||||||
allResultsMetadata: ko.ObservableArray<QueryResultsMetadata>;
|
|
||||||
|
|
||||||
/* Errors */
|
|
||||||
errors: ko.ObservableArray<QueryError>;
|
|
||||||
|
|
||||||
/* Status */
|
|
||||||
statusMessge: ko.Observable<string>;
|
|
||||||
statusIcon: ko.Observable<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScriptTab extends Tab {
|
|
||||||
id: Editable<string>;
|
|
||||||
editorId: string;
|
|
||||||
|
|
||||||
saveButton: Button;
|
|
||||||
updateButton: Button;
|
|
||||||
discardButton: Button;
|
|
||||||
deleteButton: Button;
|
|
||||||
|
|
||||||
editorState: ko.Observable<ScriptEditorState>;
|
|
||||||
editorContent: ko.Observable<string>;
|
|
||||||
editor: ko.Observable<monaco.editor.IStandaloneCodeEditor>;
|
|
||||||
|
|
||||||
errors: ko.ObservableArray<QueryError>;
|
|
||||||
statusMessge: ko.Observable<string>;
|
|
||||||
statusIcon: ko.Observable<string>;
|
|
||||||
|
|
||||||
formFields: ko.ObservableArray<Editable<any>>;
|
|
||||||
formIsValid: ko.Computed<boolean>;
|
|
||||||
formIsDirty: ko.Computed<boolean>;
|
|
||||||
|
|
||||||
isNew: ko.Observable<boolean>;
|
|
||||||
resource: ko.Observable<DataModels.Resource>;
|
|
||||||
|
|
||||||
setBaselines(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StoredProcedureTab extends ScriptTab {
|
|
||||||
onExecuteSprocsResult(result: any, logsData: any): void;
|
|
||||||
onExecuteSprocsError(error: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserDefinedFunctionTab extends ScriptTab {}
|
|
||||||
|
|
||||||
export interface TriggerTab extends ScriptTab {
|
|
||||||
triggerType: Editable<string>;
|
|
||||||
triggerOperation: Editable<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GraphTab extends Tab {}
|
|
||||||
export interface EditorPosition {
|
export interface EditorPosition {
|
||||||
line: number;
|
line: number;
|
||||||
column: number;
|
column: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MongoShellTab extends Tab {}
|
|
||||||
|
|
||||||
export enum DocumentExplorerState {
|
export enum DocumentExplorerState {
|
||||||
noDocumentSelected,
|
noDocumentSelected,
|
||||||
newDocumentValid,
|
newDocumentValid,
|
||||||
|
@ -752,40 +429,8 @@ export interface AuthorizationTokenHeaderMetadata {
|
||||||
token: string;
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TelemetryActions {
|
|
||||||
sendEvent(name: string, telemetryProperties?: { [propertyName: string]: string }): Q.Promise<any>;
|
|
||||||
sendError(errorInfo: DataModels.ITelemetryError): Q.Promise<any>;
|
|
||||||
sendMetric(
|
|
||||||
name: string,
|
|
||||||
metricNumber: number,
|
|
||||||
telemetryProperties?: { [propertyName: string]: string }
|
|
||||||
): Q.Promise<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConfigurationOverrides {
|
|
||||||
EnableBsonSchema: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CosmosDbApi {
|
|
||||||
isSystemDatabasePredicate: (database: Database) => boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DropdownOption<T> {
|
export interface DropdownOption<T> {
|
||||||
text: string;
|
text: string;
|
||||||
value: T;
|
value: T;
|
||||||
disable?: boolean;
|
disable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INotebookContainerClient {
|
|
||||||
resetWorkspace: () => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotebookContentClient {
|
|
||||||
updateItemChildren: (item: NotebookContentItem) => Promise<void>;
|
|
||||||
createNewNotebookFile: (parent: NotebookContentItem) => Promise<NotebookContentItem>;
|
|
||||||
deleteContentItem: (item: NotebookContentItem) => Promise<void>;
|
|
||||||
uploadFileAsync: (name: string, content: string, parent: NotebookContentItem) => Promise<NotebookContentItem>;
|
|
||||||
renameNotebook: (item: NotebookContentItem, targetName: string) => Promise<NotebookContentItem>;
|
|
||||||
createDirectory: (parent: NotebookContentItem, newDirectoryName: string) => Promise<NotebookContentItem>;
|
|
||||||
readFileContent: (filePath: string) => Promise<string>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,9 +13,7 @@ import { NewVertexComponent } from "./Graph/NewVertexComponent/NewVertexComponen
|
||||||
import { TabsManagerKOComponent } from "./Tabs/TabsManager";
|
import { TabsManagerKOComponent } from "./Tabs/TabsManager";
|
||||||
import { ThroughputInputComponent } from "./Controls/ThroughputInput/ThroughputInputComponent";
|
import { ThroughputInputComponent } from "./Controls/ThroughputInput/ThroughputInputComponent";
|
||||||
import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3";
|
import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3";
|
||||||
import { ToolbarComponent } from "./Controls/Toolbar/Toolbar";
|
|
||||||
|
|
||||||
ko.components.register("toolbar", new ToolbarComponent());
|
|
||||||
ko.components.register("input-typeahead", new InputTypeaheadComponent());
|
ko.components.register("input-typeahead", new InputTypeaheadComponent());
|
||||||
ko.components.register("new-vertex-form", NewVertexComponent);
|
ko.components.register("new-vertex-form", NewVertexComponent);
|
||||||
ko.components.register("error-display", new ErrorDisplayComponent());
|
ko.components.register("error-display", new ErrorDisplayComponent());
|
||||||
|
|
|
@ -27,9 +27,10 @@ import { TextField, ITextFieldProps, ITextField } from "office-ui-fabric-react/l
|
||||||
import TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
|
||||||
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";
|
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";
|
||||||
|
import { QueriesClient } from "../../../Common/QueriesClient";
|
||||||
|
|
||||||
export interface QueriesGridComponentProps {
|
export interface QueriesGridComponentProps {
|
||||||
queriesClient: ViewModels.QueriesClient;
|
queriesClient: QueriesClient;
|
||||||
onQuerySelect: (query: DataModels.Query) => void;
|
onQuerySelect: (query: DataModels.Query) => void;
|
||||||
containerVisible: boolean;
|
containerVisible: boolean;
|
||||||
saveQueryEnabled: boolean;
|
saveQueryEnabled: boolean;
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
|
||||||
|
|
||||||
interface IToolbarAction extends IToolbarDisplayable {
|
|
||||||
type: "action";
|
|
||||||
action: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IToolbarAction;
|
|
|
@ -1,18 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
interface IToolbarDisplayable {
|
|
||||||
id: string;
|
|
||||||
title: ko.Subscribable<string>;
|
|
||||||
displayName: ko.Subscribable<string>;
|
|
||||||
enabled: ko.Subscribable<boolean>;
|
|
||||||
visible: ko.Observable<boolean>;
|
|
||||||
focused: ko.Observable<boolean>;
|
|
||||||
icon: string;
|
|
||||||
mouseDown: (data: any, event: MouseEvent) => any;
|
|
||||||
keyUp: (data: any, event: KeyboardEvent) => any;
|
|
||||||
keyDown: (data: any, event: KeyboardEvent) => any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IToolbarDisplayable;
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
|
||||||
|
|
||||||
interface IToolbarDropDown extends IToolbarDisplayable {
|
|
||||||
type: "dropdown";
|
|
||||||
subgroup: IActionConfigItem[];
|
|
||||||
expanded: ko.Observable<boolean>;
|
|
||||||
open: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDropdown {
|
|
||||||
type: "dropdown";
|
|
||||||
title: string;
|
|
||||||
displayName: string;
|
|
||||||
id: string;
|
|
||||||
enabled: ko.Observable<boolean>;
|
|
||||||
visible?: ko.Observable<boolean>;
|
|
||||||
icon?: string;
|
|
||||||
subgroup?: IActionConfigItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISeperator {
|
|
||||||
type: "separator";
|
|
||||||
visible?: ko.Observable<boolean>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IToggle {
|
|
||||||
type: "toggle";
|
|
||||||
title: string;
|
|
||||||
displayName: string;
|
|
||||||
checkedTitle: string;
|
|
||||||
checkedDisplayName: string;
|
|
||||||
id: string;
|
|
||||||
checked: ko.Observable<boolean>;
|
|
||||||
enabled: ko.Observable<boolean>;
|
|
||||||
visible?: ko.Observable<boolean>;
|
|
||||||
icon?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAction {
|
|
||||||
type: "action";
|
|
||||||
title: string;
|
|
||||||
displayName: string;
|
|
||||||
id: string;
|
|
||||||
action: () => any;
|
|
||||||
enabled: ko.Subscribable<boolean>;
|
|
||||||
visible?: ko.Observable<boolean>;
|
|
||||||
icon?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IActionConfigItem = ISeperator | IAction | IToggle | IDropdown;
|
|
||||||
|
|
||||||
export default IToolbarDropDown;
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import IToolbarAction from "./IToolbarAction";
|
|
||||||
import IToolbarToggle from "./IToolbarToggle";
|
|
||||||
import IToolbarSeperator from "./IToolbarSeperator";
|
|
||||||
import IToolbarDropDown from "./IToolbarDropDown";
|
|
||||||
|
|
||||||
type IToolbarItem = IToolbarAction | IToolbarToggle | IToolbarSeperator | IToolbarDropDown;
|
|
||||||
|
|
||||||
export default IToolbarItem;
|
|
|
@ -1,10 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
interface IToolbarSeperator {
|
|
||||||
type: "separator";
|
|
||||||
visible: ko.Observable<boolean>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IToolbarSeperator;
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import IToolbarDisplayable from "./IToolbarDisplayable";
|
|
||||||
|
|
||||||
interface IToolbarToggle extends IToolbarDisplayable {
|
|
||||||
type: "toggle";
|
|
||||||
checked: ko.Observable<boolean>;
|
|
||||||
toggle: () => void;
|
|
||||||
}
|
|
||||||
export default IToolbarToggle;
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
var keyCodes = {
|
|
||||||
RightClick: 3,
|
|
||||||
Enter: 13,
|
|
||||||
Esc: 27,
|
|
||||||
Tab: 9,
|
|
||||||
LeftArrow: 37,
|
|
||||||
UpArrow: 38,
|
|
||||||
RightArrow: 39,
|
|
||||||
DownArrow: 40,
|
|
||||||
Delete: 46,
|
|
||||||
A: 65,
|
|
||||||
B: 66,
|
|
||||||
C: 67,
|
|
||||||
D: 68,
|
|
||||||
E: 69,
|
|
||||||
F: 70,
|
|
||||||
G: 71,
|
|
||||||
H: 72,
|
|
||||||
I: 73,
|
|
||||||
J: 74,
|
|
||||||
K: 75,
|
|
||||||
L: 76,
|
|
||||||
M: 77,
|
|
||||||
N: 78,
|
|
||||||
O: 79,
|
|
||||||
P: 80,
|
|
||||||
Q: 81,
|
|
||||||
R: 82,
|
|
||||||
S: 83,
|
|
||||||
T: 84,
|
|
||||||
U: 85,
|
|
||||||
V: 86,
|
|
||||||
W: 87,
|
|
||||||
X: 88,
|
|
||||||
Y: 89,
|
|
||||||
Z: 90,
|
|
||||||
Period: 190,
|
|
||||||
DecimalPoint: 110,
|
|
||||||
F1: 112,
|
|
||||||
F2: 113,
|
|
||||||
F3: 114,
|
|
||||||
F4: 115,
|
|
||||||
F5: 116,
|
|
||||||
F6: 117,
|
|
||||||
F7: 118,
|
|
||||||
F8: 119,
|
|
||||||
F9: 120,
|
|
||||||
F10: 121,
|
|
||||||
F11: 122,
|
|
||||||
F12: 123,
|
|
||||||
Dash: 189
|
|
||||||
};
|
|
||||||
|
|
||||||
export default keyCodes;
|
|
|
@ -1,145 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
import { IDropdown } from "./IToolbarDropDown";
|
|
||||||
import { IActionConfigItem } from "./IToolbarDropDown";
|
|
||||||
import IToolbarItem from "./IToolbarItem";
|
|
||||||
|
|
||||||
import * as ko from "knockout";
|
|
||||||
import ToolbarDropDown from "./ToolbarDropDown";
|
|
||||||
import ToolbarAction from "./ToolbarAction";
|
|
||||||
import ToolbarToggle from "./ToolbarToggle";
|
|
||||||
import template from "./toolbar.html";
|
|
||||||
|
|
||||||
export default class Toolbar {
|
|
||||||
private _toolbarWidth = ko.observable<number>();
|
|
||||||
private _actionConfigs: IActionConfigItem[];
|
|
||||||
private _afterExecute: (id: string) => void;
|
|
||||||
|
|
||||||
private _hasFocus: boolean = false;
|
|
||||||
private _focusedSubscription: ko.Subscription;
|
|
||||||
|
|
||||||
constructor(actionItems: IActionConfigItem[], afterExecute?: (id: string) => void) {
|
|
||||||
this._actionConfigs = actionItems;
|
|
||||||
this._afterExecute = afterExecute;
|
|
||||||
this.toolbarItems.subscribe(this._focusFirstEnabledItem);
|
|
||||||
|
|
||||||
$(window).resize(() => {
|
|
||||||
this._toolbarWidth($(".toolbar").width());
|
|
||||||
});
|
|
||||||
setTimeout(() => {
|
|
||||||
this._toolbarWidth($(".toolbar").width());
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
public toolbarItems: ko.PureComputed<IToolbarItem[]> = ko.pureComputed(() => {
|
|
||||||
var remainingToolbarSpace = this._toolbarWidth();
|
|
||||||
var toolbarItems: IToolbarItem[] = [];
|
|
||||||
|
|
||||||
var moreItem: IDropdown = {
|
|
||||||
type: "dropdown",
|
|
||||||
title: "More",
|
|
||||||
displayName: "More",
|
|
||||||
id: "more-actions-toggle",
|
|
||||||
enabled: ko.observable(true),
|
|
||||||
visible: ko.observable(true),
|
|
||||||
icon: "images/ASX_More.svg",
|
|
||||||
subgroup: []
|
|
||||||
};
|
|
||||||
|
|
||||||
var showHasMoreItem = false;
|
|
||||||
var addSeparator = false;
|
|
||||||
this._actionConfigs.forEach(actionConfig => {
|
|
||||||
if (actionConfig.type === "separator") {
|
|
||||||
addSeparator = true;
|
|
||||||
} else if (remainingToolbarSpace / 60 > 2) {
|
|
||||||
if (addSeparator) {
|
|
||||||
addSeparator = false;
|
|
||||||
toolbarItems.push(Toolbar._createToolbarItemFromConfig({ type: "separator" }));
|
|
||||||
remainingToolbarSpace -= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
toolbarItems.push(Toolbar._createToolbarItemFromConfig(actionConfig));
|
|
||||||
remainingToolbarSpace -= 60;
|
|
||||||
} else {
|
|
||||||
showHasMoreItem = true;
|
|
||||||
if (addSeparator) {
|
|
||||||
addSeparator = false;
|
|
||||||
moreItem.subgroup.push({
|
|
||||||
type: "separator"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!!actionConfig) {
|
|
||||||
moreItem.subgroup.push(actionConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (showHasMoreItem) {
|
|
||||||
toolbarItems.push(
|
|
||||||
Toolbar._createToolbarItemFromConfig({ type: "separator" }),
|
|
||||||
Toolbar._createToolbarItemFromConfig(moreItem)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toolbarItems;
|
|
||||||
});
|
|
||||||
|
|
||||||
public focus() {
|
|
||||||
this._hasFocus = true;
|
|
||||||
this._focusFirstEnabledItem(this.toolbarItems());
|
|
||||||
}
|
|
||||||
|
|
||||||
private _focusFirstEnabledItem = (items: IToolbarItem[]) => {
|
|
||||||
if (!!this._focusedSubscription) {
|
|
||||||
// no memory leaks! :D
|
|
||||||
this._focusedSubscription.dispose();
|
|
||||||
}
|
|
||||||
if (this._hasFocus) {
|
|
||||||
for (var i = 0; i < items.length; i++) {
|
|
||||||
if (items[i].type !== "separator" && (<any>items[i]).enabled()) {
|
|
||||||
(<any>items[i]).focused(true);
|
|
||||||
this._focusedSubscription = (<any>items[i]).focused.subscribe((newValue: any) => {
|
|
||||||
if (!newValue) {
|
|
||||||
this._hasFocus = false;
|
|
||||||
this._focusedSubscription.dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static _createToolbarItemFromConfig(
|
|
||||||
configItem: IActionConfigItem,
|
|
||||||
afterExecute?: (id: string) => void
|
|
||||||
): IToolbarItem {
|
|
||||||
switch (configItem.type) {
|
|
||||||
case "dropdown":
|
|
||||||
return new ToolbarDropDown(configItem, afterExecute);
|
|
||||||
case "action":
|
|
||||||
return new ToolbarAction(configItem, afterExecute);
|
|
||||||
case "toggle":
|
|
||||||
return new ToolbarToggle(configItem, afterExecute);
|
|
||||||
case "separator":
|
|
||||||
return {
|
|
||||||
type: "separator",
|
|
||||||
visible: ko.observable(true)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class for ko component registration
|
|
||||||
*/
|
|
||||||
export class ToolbarComponent {
|
|
||||||
constructor() {
|
|
||||||
return {
|
|
||||||
viewModel: Toolbar,
|
|
||||||
template
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import * as ko from "knockout";
|
|
||||||
import { IAction } from "./IToolbarDropDown";
|
|
||||||
import IToolbarAction from "./IToolbarAction";
|
|
||||||
import KeyCodes from "./KeyCodes";
|
|
||||||
import Utilities from "./Utilities";
|
|
||||||
|
|
||||||
export default class ToolbarAction implements IToolbarAction {
|
|
||||||
public type: "action" = "action";
|
|
||||||
public id: string;
|
|
||||||
public icon: string;
|
|
||||||
public title: ko.Observable<string>;
|
|
||||||
public displayName: ko.Observable<string>;
|
|
||||||
public enabled: ko.Subscribable<boolean>;
|
|
||||||
public visible: ko.Observable<boolean>;
|
|
||||||
public focused: ko.Observable<boolean>;
|
|
||||||
public action: () => void;
|
|
||||||
private _afterExecute: (id: string) => void;
|
|
||||||
|
|
||||||
constructor(actionItem: IAction, afterExecute?: (id: string) => void) {
|
|
||||||
this.action = actionItem.action;
|
|
||||||
this.title = ko.observable(actionItem.title);
|
|
||||||
this.displayName = ko.observable(actionItem.displayName);
|
|
||||||
this.id = actionItem.id;
|
|
||||||
this.enabled = actionItem.enabled;
|
|
||||||
this.visible = actionItem.visible ? actionItem.visible : ko.observable(true);
|
|
||||||
this.focused = ko.observable(false);
|
|
||||||
this.icon = actionItem.icon;
|
|
||||||
this._afterExecute = afterExecute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _executeAction = () => {
|
|
||||||
this.action();
|
|
||||||
if (!!this._afterExecute) {
|
|
||||||
this._afterExecute(this.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
|
||||||
this._executeAction();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
this._executeAction();
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!handled) {
|
|
||||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
|
||||||
Utilities.onKeys(
|
|
||||||
event,
|
|
||||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
|
||||||
($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import * as ko from "knockout";
|
|
||||||
import { IDropdown } from "./IToolbarDropDown";
|
|
||||||
import { IActionConfigItem } from "./IToolbarDropDown";
|
|
||||||
import IToolbarDropDown from "./IToolbarDropDown";
|
|
||||||
import KeyCodes from "./KeyCodes";
|
|
||||||
import Utilities from "./Utilities";
|
|
||||||
|
|
||||||
interface IMenuItem {
|
|
||||||
id?: string;
|
|
||||||
type: "normal" | "separator" | "submenu";
|
|
||||||
label?: string;
|
|
||||||
enabled?: boolean;
|
|
||||||
visible?: boolean;
|
|
||||||
submenu?: IMenuItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ToolbarDropDown implements IToolbarDropDown {
|
|
||||||
public type: "dropdown" = "dropdown";
|
|
||||||
public title: ko.Observable<string>;
|
|
||||||
public displayName: ko.Observable<string>;
|
|
||||||
public id: string;
|
|
||||||
public enabled: ko.Observable<boolean>;
|
|
||||||
public visible: ko.Observable<boolean>;
|
|
||||||
public focused: ko.Observable<boolean>;
|
|
||||||
public icon: string;
|
|
||||||
public subgroup: IActionConfigItem[] = [];
|
|
||||||
public expanded: ko.Observable<boolean> = ko.observable(false);
|
|
||||||
private _afterExecute: (id: string) => void;
|
|
||||||
|
|
||||||
constructor(dropdown: IDropdown, afterExecute?: (id: string) => void) {
|
|
||||||
this.subgroup = dropdown.subgroup;
|
|
||||||
this.title = ko.observable(dropdown.title);
|
|
||||||
this.displayName = ko.observable(dropdown.displayName);
|
|
||||||
this.id = dropdown.id;
|
|
||||||
this.enabled = dropdown.enabled;
|
|
||||||
this.visible = dropdown.visible ? dropdown.visible : ko.observable(true);
|
|
||||||
this.focused = ko.observable(false);
|
|
||||||
this.icon = dropdown.icon;
|
|
||||||
this._afterExecute = afterExecute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _convertToMenuItem = (
|
|
||||||
actionConfigs: IActionConfigItem[],
|
|
||||||
actionMap: { [id: string]: () => void } = {}
|
|
||||||
): { menuItems: IMenuItem[]; actionMap: { [id: string]: () => void } } => {
|
|
||||||
var returnValue = {
|
|
||||||
menuItems: actionConfigs.map<IMenuItem>((actionConfig: IActionConfigItem, index, array) => {
|
|
||||||
var menuItem: IMenuItem;
|
|
||||||
switch (actionConfig.type) {
|
|
||||||
case "action":
|
|
||||||
menuItem = <IMenuItem>{
|
|
||||||
id: actionConfig.id,
|
|
||||||
type: "normal",
|
|
||||||
label: actionConfig.displayName,
|
|
||||||
enabled: actionConfig.enabled(),
|
|
||||||
visible: actionConfig.visible ? actionConfig.visible() : true
|
|
||||||
};
|
|
||||||
actionMap[actionConfig.id] = actionConfig.action;
|
|
||||||
break;
|
|
||||||
case "dropdown":
|
|
||||||
menuItem = <IMenuItem>{
|
|
||||||
id: actionConfig.id,
|
|
||||||
type: "submenu",
|
|
||||||
label: actionConfig.displayName,
|
|
||||||
enabled: actionConfig.enabled(),
|
|
||||||
visible: actionConfig.visible ? actionConfig.visible() : true,
|
|
||||||
submenu: ToolbarDropDown._convertToMenuItem(actionConfig.subgroup, actionMap).menuItems
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "toggle":
|
|
||||||
menuItem = <IMenuItem>{
|
|
||||||
id: actionConfig.id,
|
|
||||||
type: "normal",
|
|
||||||
label: actionConfig.checked() ? actionConfig.checkedDisplayName : actionConfig.displayName,
|
|
||||||
enabled: actionConfig.enabled(),
|
|
||||||
visible: actionConfig.visible ? actionConfig.visible() : true
|
|
||||||
};
|
|
||||||
actionMap[actionConfig.id] = () => {
|
|
||||||
actionConfig.checked(!actionConfig.checked());
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "separator":
|
|
||||||
menuItem = <IMenuItem>{
|
|
||||||
type: "separator",
|
|
||||||
visible: true
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return menuItem;
|
|
||||||
}),
|
|
||||||
actionMap: actionMap
|
|
||||||
};
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
public open = () => {
|
|
||||||
if (!!(<any>window).host) {
|
|
||||||
var convertedMenuItem = ToolbarDropDown._convertToMenuItem(this.subgroup);
|
|
||||||
|
|
||||||
(<any>window).host
|
|
||||||
.executeProviderOperation("MenuManager.showMenu", {
|
|
||||||
iFrameStack: [`#${window.frameElement.id}`],
|
|
||||||
anchor: `#${this.id}`,
|
|
||||||
menuItems: convertedMenuItem.menuItems
|
|
||||||
})
|
|
||||||
.then((id?: string) => {
|
|
||||||
if (!!id && !!convertedMenuItem.actionMap[id]) {
|
|
||||||
convertedMenuItem.actionMap[id]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!!this._afterExecute) {
|
|
||||||
this._afterExecute(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
|
||||||
this.open();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
this.open();
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!handled) {
|
|
||||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
|
||||||
Utilities.onKeys(
|
|
||||||
event,
|
|
||||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
|
||||||
($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import * as ko from "knockout";
|
|
||||||
import { IToggle } from "./IToolbarDropDown";
|
|
||||||
import IToolbarToggle from "./IToolbarToggle";
|
|
||||||
import KeyCodes from "./KeyCodes";
|
|
||||||
import Utilities from "./Utilities";
|
|
||||||
|
|
||||||
export default class ToolbarToggle implements IToolbarToggle {
|
|
||||||
public type: "toggle" = "toggle";
|
|
||||||
public checked: ko.Observable<boolean>;
|
|
||||||
public id: string;
|
|
||||||
public enabled: ko.Observable<boolean>;
|
|
||||||
public visible: ko.Observable<boolean>;
|
|
||||||
public focused: ko.Observable<boolean>;
|
|
||||||
public icon: string;
|
|
||||||
|
|
||||||
private _title: string;
|
|
||||||
private _displayName: string;
|
|
||||||
private _checkedTitle: string;
|
|
||||||
private _checkedDisplayName: string;
|
|
||||||
|
|
||||||
private _afterExecute: (id: string) => void;
|
|
||||||
|
|
||||||
constructor(toggleItem: IToggle, afterExecute?: (id: string) => void) {
|
|
||||||
this._title = toggleItem.title;
|
|
||||||
this._displayName = toggleItem.displayName;
|
|
||||||
this.id = toggleItem.id;
|
|
||||||
this.enabled = toggleItem.enabled;
|
|
||||||
this.visible = toggleItem.visible ? toggleItem.visible : ko.observable(true);
|
|
||||||
this.focused = ko.observable(false);
|
|
||||||
this.icon = toggleItem.icon;
|
|
||||||
this.checked = toggleItem.checked;
|
|
||||||
this._checkedTitle = toggleItem.checkedTitle;
|
|
||||||
this._checkedDisplayName = toggleItem.checkedDisplayName;
|
|
||||||
this._afterExecute = afterExecute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public title = ko.pureComputed(() => {
|
|
||||||
if (this.checked()) {
|
|
||||||
return this._checkedTitle;
|
|
||||||
} else {
|
|
||||||
return this._title;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
public displayName = ko.pureComputed(() => {
|
|
||||||
if (this.checked()) {
|
|
||||||
return this._checkedDisplayName;
|
|
||||||
} else {
|
|
||||||
return this._displayName;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
public toggle = () => {
|
|
||||||
this.checked(!this.checked());
|
|
||||||
|
|
||||||
if (this.checked() && !!this._afterExecute) {
|
|
||||||
this._afterExecute(this.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public mouseDown = (data: any, event: MouseEvent): boolean => {
|
|
||||||
this.toggle();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyUp = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
this.toggle();
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
|
|
||||||
public keyDown = (data: any, event: KeyboardEvent): boolean => {
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
handled = Utilities.onEnter(event, ($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!handled) {
|
|
||||||
// Reset color if [shift-] tabbing, 'up/down arrowing', or 'esc'-aping away from button while holding down 'enter'
|
|
||||||
Utilities.onKeys(
|
|
||||||
event,
|
|
||||||
[KeyCodes.Tab, KeyCodes.UpArrow, KeyCodes.DownArrow, KeyCodes.Esc],
|
|
||||||
($sourceElement: JQuery) => {
|
|
||||||
if ($sourceElement.hasClass("active")) {
|
|
||||||
$sourceElement.removeClass("active");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !handled;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*!---------------------------------------------------------
|
|
||||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
import KeyCodes from "./KeyCodes";
|
|
||||||
|
|
||||||
export default class Utilities {
|
|
||||||
/**
|
|
||||||
* Executes an action on a keyboard event.
|
|
||||||
* Modifiers: ctrlKey - control/command key, shiftKey - shift key, altKey - alt/option key;
|
|
||||||
* pass on 'null' to ignore the modifier (default).
|
|
||||||
*/
|
|
||||||
public static onKey(
|
|
||||||
event: any,
|
|
||||||
eventKeyCode: number,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
var source: any = event.target || event.srcElement,
|
|
||||||
keyCode: number = event.keyCode,
|
|
||||||
$sourceElement = $(source),
|
|
||||||
handled: boolean = false;
|
|
||||||
|
|
||||||
if (
|
|
||||||
$sourceElement.length &&
|
|
||||||
keyCode === eventKeyCode &&
|
|
||||||
$.isFunction(action) &&
|
|
||||||
(metaKey === null || metaKey === event.metaKey) &&
|
|
||||||
(shiftKey === null || shiftKey === event.shiftKey) &&
|
|
||||||
(altKey === null || altKey === event.altKey)
|
|
||||||
) {
|
|
||||||
action($sourceElement);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on the first matched keyboard event.
|
|
||||||
*/
|
|
||||||
public static onKeys(
|
|
||||||
event: any,
|
|
||||||
eventKeyCodes: number[],
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
var handled: boolean = false,
|
|
||||||
keyCount: number,
|
|
||||||
i: number;
|
|
||||||
|
|
||||||
if ($.isArray(eventKeyCodes)) {
|
|
||||||
keyCount = eventKeyCodes.length;
|
|
||||||
|
|
||||||
for (i = 0; i < keyCount; ++i) {
|
|
||||||
handled = Utilities.onKey(event, eventKeyCodes[i], action, metaKey, shiftKey, altKey);
|
|
||||||
|
|
||||||
if (handled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on an 'enter' keyboard event.
|
|
||||||
*/
|
|
||||||
public static onEnter(
|
|
||||||
event: any,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
return Utilities.onKey(event, KeyCodes.Enter, action, metaKey, shiftKey, altKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on a 'tab' keyboard event.
|
|
||||||
*/
|
|
||||||
public static onTab(
|
|
||||||
event: any,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
return Utilities.onKey(event, KeyCodes.Tab, action, metaKey, shiftKey, altKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on an 'Esc' keyboard event.
|
|
||||||
*/
|
|
||||||
public static onEsc(
|
|
||||||
event: any,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
return Utilities.onKey(event, KeyCodes.Esc, action, metaKey, shiftKey, altKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on an 'UpArrow' keyboard event.
|
|
||||||
*/
|
|
||||||
public static onUpArrow(
|
|
||||||
event: any,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
return Utilities.onKey(event, KeyCodes.UpArrow, action, metaKey, shiftKey, altKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on a 'DownArrow' keyboard event.
|
|
||||||
*/
|
|
||||||
public static onDownArrow(
|
|
||||||
event: any,
|
|
||||||
action: ($sourceElement: JQuery) => void,
|
|
||||||
metaKey: boolean = null,
|
|
||||||
shiftKey: boolean = null,
|
|
||||||
altKey: boolean = null
|
|
||||||
): boolean {
|
|
||||||
return Utilities.onKey(event, KeyCodes.DownArrow, action, metaKey, shiftKey, altKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on a mouse event.
|
|
||||||
*/
|
|
||||||
public static onButton(event: any, eventButtonCode: number, action: ($sourceElement: JQuery) => void): boolean {
|
|
||||||
var source: any = event.currentTarget;
|
|
||||||
var buttonCode: number = event.button;
|
|
||||||
var $sourceElement = $(source);
|
|
||||||
var handled: boolean = false;
|
|
||||||
|
|
||||||
if ($sourceElement.length && buttonCode === eventButtonCode && $.isFunction(action)) {
|
|
||||||
action($sourceElement);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an action on a 'left' mouse event.
|
|
||||||
*/
|
|
||||||
public static onLeftButton(event: any, action: ($sourceElement: JQuery) => void): boolean {
|
|
||||||
return Utilities.onButton(event, buttonCodes.Left, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var buttonCodes = {
|
|
||||||
None: -1,
|
|
||||||
Left: 0,
|
|
||||||
Middle: 1,
|
|
||||||
Right: 2
|
|
||||||
};
|
|
|
@ -1,44 +0,0 @@
|
||||||
<div class="toolbar">
|
|
||||||
<!-- ko template: { name: 'toolbarItemTemplate', foreach: toolbarItems } -->
|
|
||||||
<!-- /ko -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/html" id="toolbarItemTemplate">
|
|
||||||
<!-- ko if: type === "action" -->
|
|
||||||
<div class="toolbar-group" data-bind="visible: visible">
|
|
||||||
<button class="toolbar-group-button" data-bind="hasFocus: focused, attr: {id: id, title: title, 'aria-label': displayName}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
|
||||||
<div class="toolbar-group-button-icon">
|
|
||||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
|
||||||
</div>
|
|
||||||
<span data-bind="text: displayName"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<!-- /ko -->
|
|
||||||
|
|
||||||
<!-- ko if: type === "toggle" -->
|
|
||||||
<div class="toolbar-group" data-bind="visible: visible">
|
|
||||||
<button class="toolbar-group-button toggle-button" data-bind="hasFocus: focused, attr: {id: id, title: title}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
|
||||||
<div class="toolbar-group-button-icon" data-bind="css: { 'toggle-checked': checked }">
|
|
||||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
|
||||||
</div>
|
|
||||||
<span data-bind="text: displayName"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<!-- /ko -->
|
|
||||||
<!-- ko if: type === "dropdown" -->
|
|
||||||
<div class="toolbar-group" data-bind="visible: visible">
|
|
||||||
<div class="dropdown" data-bind="attr: {id: (id + '-dropdown')}">
|
|
||||||
<button role="menu" class="toolbar-group-button" data-bind="hasFocus: focused, attr: {id: id, title: title, 'aria-label': displayName}, event: { mousedown: mouseDown, keydown: keyDown, keyup: keyUp }, enable: enabled">
|
|
||||||
<div class="toolbar-group-button-icon">
|
|
||||||
<div class="toolbar_icon" data-bind="icon: icon"></div>
|
|
||||||
</div>
|
|
||||||
<span data-bind="text: displayName"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- /ko -->
|
|
||||||
|
|
||||||
<!-- ko if: type === "separator" -->
|
|
||||||
<div class="toolbar-group vertical-separator" data-bind="visible: visible"></div>
|
|
||||||
<!-- /ko -->
|
|
||||||
</script>
|
|
|
@ -21,7 +21,7 @@ import EnvironmentUtility from "../Common/EnvironmentUtility";
|
||||||
import GraphStylingPane from "./Panes/GraphStylingPane";
|
import GraphStylingPane from "./Panes/GraphStylingPane";
|
||||||
import hasher from "hasher";
|
import hasher from "hasher";
|
||||||
import NewVertexPane from "./Panes/NewVertexPane";
|
import NewVertexPane from "./Panes/NewVertexPane";
|
||||||
import NotebookV2Tab from "./Tabs/NotebookV2Tab";
|
import NotebookV2Tab, { NotebookTabOptions } from "./Tabs/NotebookV2Tab";
|
||||||
import Q from "q";
|
import Q from "q";
|
||||||
import ResourceTokenCollection from "./Tree/ResourceTokenCollection";
|
import ResourceTokenCollection from "./Tree/ResourceTokenCollection";
|
||||||
import TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
@ -33,7 +33,6 @@ import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker";
|
||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
||||||
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
||||||
import { CassandraApi } from "../Api/Apis";
|
|
||||||
import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient";
|
import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient";
|
||||||
import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { config } from "../Config";
|
import { config } from "../Config";
|
||||||
|
@ -82,6 +81,10 @@ import { toRawContentUri, fromContentUri } from "../Utils/GitHubUtils";
|
||||||
import UserDefinedFunction from "./Tree/UserDefinedFunction";
|
import UserDefinedFunction from "./Tree/UserDefinedFunction";
|
||||||
import StoredProcedure from "./Tree/StoredProcedure";
|
import StoredProcedure from "./Tree/StoredProcedure";
|
||||||
import Trigger from "./Tree/Trigger";
|
import Trigger from "./Tree/Trigger";
|
||||||
|
import { NotificationsClientBase } from "../Common/NotificationsClientBase";
|
||||||
|
import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
||||||
|
import TabsBase from "./Tabs/TabsBase";
|
||||||
|
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
BindingHandlersRegisterer.registerBindingHandlers();
|
BindingHandlersRegisterer.registerBindingHandlers();
|
||||||
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
||||||
|
@ -92,6 +95,15 @@ enum ShareAccessToggleState {
|
||||||
Read
|
Read
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ExplorerOptions {
|
||||||
|
notificationsClient: NotificationsClientBase;
|
||||||
|
isEmulator: boolean;
|
||||||
|
}
|
||||||
|
interface AdHocAccessData {
|
||||||
|
readWriteUrl: string;
|
||||||
|
readUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default class Explorer {
|
export default class Explorer {
|
||||||
public flight: ko.Observable<string> = ko.observable<string>(
|
public flight: ko.Observable<string> = ko.observable<string>(
|
||||||
SharedConstants.CollectionCreation.DefaultAddCollectionDefaultFlight
|
SharedConstants.CollectionCreation.DefaultAddCollectionDefaultFlight
|
||||||
|
@ -107,7 +119,7 @@ export default class Explorer {
|
||||||
public hasWriteAccess: ko.Observable<boolean>;
|
public hasWriteAccess: ko.Observable<boolean>;
|
||||||
public collapsedResourceTreeWidth: number = ExplorerMetrics.CollapsedResourceTreeWidth;
|
public collapsedResourceTreeWidth: number = ExplorerMetrics.CollapsedResourceTreeWidth;
|
||||||
|
|
||||||
public databaseAccount: ko.Observable<ViewModels.DatabaseAccount>;
|
public databaseAccount: ko.Observable<DataModels.DatabaseAccount>;
|
||||||
public collectionCreationDefaults: ViewModels.CollectionCreationDefaults = SharedConstants.CollectionCreationDefaults;
|
public collectionCreationDefaults: ViewModels.CollectionCreationDefaults = SharedConstants.CollectionCreationDefaults;
|
||||||
public subscriptionType: ko.Observable<ViewModels.SubscriptionType>;
|
public subscriptionType: ko.Observable<ViewModels.SubscriptionType>;
|
||||||
public quotaId: ko.Observable<string>;
|
public quotaId: ko.Observable<string>;
|
||||||
|
@ -127,8 +139,8 @@ export default class Explorer {
|
||||||
public extensionEndpoint: ko.Observable<string>;
|
public extensionEndpoint: ko.Observable<string>;
|
||||||
public armEndpoint: ko.Observable<string>;
|
public armEndpoint: ko.Observable<string>;
|
||||||
public isTryCosmosDBSubscription: ko.Observable<boolean>;
|
public isTryCosmosDBSubscription: ko.Observable<boolean>;
|
||||||
public notificationsClient: ViewModels.NotificationsClient;
|
public notificationsClient: NotificationsClientBase;
|
||||||
public queriesClient: ViewModels.QueriesClient;
|
public queriesClient: QueriesClient;
|
||||||
public tableDataClient: TableDataClient;
|
public tableDataClient: TableDataClient;
|
||||||
public splitter: Splitter;
|
public splitter: Splitter;
|
||||||
public parentFrameDataExplorerVersion: ko.Observable<string> = ko.observable<string>("");
|
public parentFrameDataExplorerVersion: ko.Observable<string> = ko.observable<string>("");
|
||||||
|
@ -139,7 +151,7 @@ export default class Explorer {
|
||||||
public isNotificationConsoleExpanded: ko.Observable<boolean>;
|
public isNotificationConsoleExpanded: ko.Observable<boolean>;
|
||||||
|
|
||||||
// Panes
|
// Panes
|
||||||
public contextPanes: ViewModels.ContextualPane[];
|
public contextPanes: ContextualPaneBase[];
|
||||||
|
|
||||||
// Resource Tree
|
// Resource Tree
|
||||||
public databases: ko.ObservableArray<ViewModels.Database>;
|
public databases: ko.ObservableArray<ViewModels.Database>;
|
||||||
|
@ -184,12 +196,12 @@ export default class Explorer {
|
||||||
public uploadItemsPane: UploadItemsPane;
|
public uploadItemsPane: UploadItemsPane;
|
||||||
public uploadItemsPaneAdapter: UploadItemsPaneAdapter;
|
public uploadItemsPaneAdapter: UploadItemsPaneAdapter;
|
||||||
public loadQueryPane: LoadQueryPane;
|
public loadQueryPane: LoadQueryPane;
|
||||||
public saveQueryPane: ViewModels.ContextualPane;
|
public saveQueryPane: ContextualPaneBase;
|
||||||
public browseQueriesPane: BrowseQueriesPane;
|
public browseQueriesPane: BrowseQueriesPane;
|
||||||
public uploadFilePane: UploadFilePane;
|
public uploadFilePane: UploadFilePane;
|
||||||
public stringInputPane: StringInputPane;
|
public stringInputPane: StringInputPane;
|
||||||
public setupNotebooksPane: SetupNotebooksPane;
|
public setupNotebooksPane: SetupNotebooksPane;
|
||||||
public gitHubReposPane: ViewModels.ContextualPane;
|
public gitHubReposPane: ContextualPaneBase;
|
||||||
public publishNotebookPaneAdapter: ReactAdapter;
|
public publishNotebookPaneAdapter: ReactAdapter;
|
||||||
|
|
||||||
// features
|
// features
|
||||||
|
@ -202,7 +214,7 @@ export default class Explorer {
|
||||||
public hasAutoPilotV2FeatureFlag: ko.Computed<boolean>;
|
public hasAutoPilotV2FeatureFlag: ko.Computed<boolean>;
|
||||||
|
|
||||||
public shouldShowShareDialogContents: ko.Observable<boolean>;
|
public shouldShowShareDialogContents: ko.Observable<boolean>;
|
||||||
public shareAccessData: ko.Observable<ViewModels.AdHocAccessData>;
|
public shareAccessData: ko.Observable<AdHocAccessData>;
|
||||||
public renewExplorerShareAccess: (explorer: Explorer, token: string) => Q.Promise<void>;
|
public renewExplorerShareAccess: (explorer: Explorer, token: string) => Q.Promise<void>;
|
||||||
public renewTokenError: ko.Observable<string>;
|
public renewTokenError: ko.Observable<string>;
|
||||||
public tokenForRenewal: ko.Observable<string>;
|
public tokenForRenewal: ko.Observable<string>;
|
||||||
|
@ -228,7 +240,7 @@ export default class Explorer {
|
||||||
public memoryUsageInfo: ko.Observable<DataModels.MemoryUsageInfo>;
|
public memoryUsageInfo: ko.Observable<DataModels.MemoryUsageInfo>;
|
||||||
public notebookManager?: any; // This is dynamically loaded
|
public notebookManager?: any; // This is dynamically loaded
|
||||||
|
|
||||||
private _panes: ViewModels.ContextualPane[] = [];
|
private _panes: ContextualPaneBase[] = [];
|
||||||
private _importExplorerConfigComplete: boolean = false;
|
private _importExplorerConfigComplete: boolean = false;
|
||||||
private _isSystemDatabasePredicate: (database: ViewModels.Database) => boolean = database => false;
|
private _isSystemDatabasePredicate: (database: ViewModels.Database) => boolean = database => false;
|
||||||
private _isInitializingNotebooks: boolean;
|
private _isInitializingNotebooks: boolean;
|
||||||
|
@ -251,7 +263,7 @@ export default class Explorer {
|
||||||
|
|
||||||
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
||||||
|
|
||||||
constructor(options: ViewModels.ExplorerOptions) {
|
constructor(options: ExplorerOptions) {
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.InitializeDataExplorer, {
|
const startKey: number = TelemetryProcessor.traceStart(Action.InitializeDataExplorer, {
|
||||||
dataExplorerArea: Constants.Areas.ResourceTree
|
dataExplorerArea: Constants.Areas.ResourceTree
|
||||||
});
|
});
|
||||||
|
@ -264,7 +276,7 @@ export default class Explorer {
|
||||||
this.deleteDatabaseText = ko.observable<string>("Delete Database");
|
this.deleteDatabaseText = ko.observable<string>("Delete Database");
|
||||||
this.refreshTreeTitle = ko.observable<string>("Refresh collections");
|
this.refreshTreeTitle = ko.observable<string>("Refresh collections");
|
||||||
|
|
||||||
this.databaseAccount = ko.observable<ViewModels.DatabaseAccount>();
|
this.databaseAccount = ko.observable<DataModels.DatabaseAccount>();
|
||||||
this.subscriptionType = ko.observable<ViewModels.SubscriptionType>(
|
this.subscriptionType = ko.observable<ViewModels.SubscriptionType>(
|
||||||
SharedConstants.CollectionCreation.DefaultSubscriptionType
|
SharedConstants.CollectionCreation.DefaultSubscriptionType
|
||||||
);
|
);
|
||||||
|
@ -373,7 +385,7 @@ export default class Explorer {
|
||||||
this.resourceTokenPartitionKey = ko.observable<string>();
|
this.resourceTokenPartitionKey = ko.observable<string>();
|
||||||
this.isAuthWithResourceToken = ko.observable<boolean>(false);
|
this.isAuthWithResourceToken = ko.observable<boolean>(false);
|
||||||
|
|
||||||
this.shareAccessData = ko.observable<ViewModels.AdHocAccessData>({
|
this.shareAccessData = ko.observable<AdHocAccessData>({
|
||||||
readWriteUrl: undefined,
|
readWriteUrl: undefined,
|
||||||
readUrl: undefined
|
readUrl: undefined
|
||||||
});
|
});
|
||||||
|
@ -458,7 +470,7 @@ export default class Explorer {
|
||||||
});
|
});
|
||||||
this.notificationConsoleData = ko.observableArray<ConsoleData>([]);
|
this.notificationConsoleData = ko.observableArray<ConsoleData>([]);
|
||||||
this.defaultExperience = ko.observable<string>();
|
this.defaultExperience = ko.observable<string>();
|
||||||
this.databaseAccount.subscribe((databaseAccount: ViewModels.DatabaseAccount) => {
|
this.databaseAccount.subscribe(databaseAccount => {
|
||||||
this.defaultExperience(DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount));
|
this.defaultExperience(DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -551,8 +563,9 @@ export default class Explorer {
|
||||||
defaultExperience &&
|
defaultExperience &&
|
||||||
defaultExperience.toLowerCase() === Constants.DefaultAccountExperience.Cassandra.toLowerCase()
|
defaultExperience.toLowerCase() === Constants.DefaultAccountExperience.Cassandra.toLowerCase()
|
||||||
) {
|
) {
|
||||||
const api = new CassandraApi();
|
this._isSystemDatabasePredicate = (database: ViewModels.Database): boolean => {
|
||||||
this._isSystemDatabasePredicate = api.isSystemDatabasePredicate;
|
return database.id() === "system";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1003,7 +1016,7 @@ export default class Explorer {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const databaseAccount: ViewModels.DatabaseAccount = await resourceProviderClient.patchAsync(
|
const databaseAccount: DataModels.DatabaseAccount = await resourceProviderClient.patchAsync(
|
||||||
this.databaseAccount().id,
|
this.databaseAccount().id,
|
||||||
"2019-12-12",
|
"2019-12-12",
|
||||||
{
|
{
|
||||||
|
@ -1951,7 +1964,7 @@ export default class Explorer {
|
||||||
return _.find(selectedCollection.storedProcedures(), (storedProcedure: StoredProcedure) => {
|
return _.find(selectedCollection.storedProcedures(), (storedProcedure: StoredProcedure) => {
|
||||||
const openedSprocTab = this.tabsManager.getTabs(
|
const openedSprocTab = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.StoredProcedures,
|
ViewModels.CollectionTabKind.StoredProcedures,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === storedProcedure.rid
|
tab => tab.node && tab.node.rid === storedProcedure.rid
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
storedProcedure.rid === this.selectedNode().rid ||
|
storedProcedure.rid === this.selectedNode().rid ||
|
||||||
|
@ -1965,7 +1978,7 @@ export default class Explorer {
|
||||||
return _.find(selectedCollection.userDefinedFunctions(), (userDefinedFunction: UserDefinedFunction) => {
|
return _.find(selectedCollection.userDefinedFunctions(), (userDefinedFunction: UserDefinedFunction) => {
|
||||||
const openedUdfTab = this.tabsManager.getTabs(
|
const openedUdfTab = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === userDefinedFunction.rid
|
tab => tab.node && tab.node.rid === userDefinedFunction.rid
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
userDefinedFunction.rid === this.selectedNode().rid ||
|
userDefinedFunction.rid === this.selectedNode().rid ||
|
||||||
|
@ -1979,7 +1992,7 @@ export default class Explorer {
|
||||||
return _.find(selectedCollection.triggers(), (trigger: Trigger) => {
|
return _.find(selectedCollection.triggers(), (trigger: Trigger) => {
|
||||||
const openedTriggerTab = this.tabsManager.getTabs(
|
const openedTriggerTab = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Triggers,
|
ViewModels.CollectionTabKind.Triggers,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === trigger.rid
|
tab => tab.node && tab.node.rid === trigger.rid
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
trigger.rid === this.selectedNode().rid ||
|
trigger.rid === this.selectedNode().rid ||
|
||||||
|
@ -1989,7 +2002,7 @@ export default class Explorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeAllPanes(): void {
|
public closeAllPanes(): void {
|
||||||
this._panes.forEach((pane: ViewModels.ContextualPane) => pane.close());
|
this._panes.forEach((pane: ContextualPaneBase) => pane.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPlatformType(): PlatformType {
|
public getPlatformType(): PlatformType {
|
||||||
|
@ -2004,7 +2017,7 @@ export default class Explorer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUpdateTabsButtons(buttons: ViewModels.NavbarButtonConfig[]): void {
|
public onUpdateTabsButtons(buttons: CommandButtonComponentProps[]): void {
|
||||||
this.commandBarComponentAdapter.onUpdateTabsButtons(buttons);
|
this.commandBarComponentAdapter.onUpdateTabsButtons(buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2064,9 +2077,7 @@ export default class Explorer {
|
||||||
if (isNewDatabase) {
|
if (isNewDatabase) {
|
||||||
database.expandDatabase();
|
database.expandDatabase();
|
||||||
}
|
}
|
||||||
this.tabsManager.refreshActiveTab(
|
this.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.getDatabase().rid === database.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.getDatabase().rid === database.rid
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -2169,7 +2180,7 @@ export default class Explorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
const urlPrefixWithKeyParam: string = `${config.hostedExplorerURL}?key=`;
|
const urlPrefixWithKeyParam: string = `${config.hostedExplorerURL}?key=`;
|
||||||
const currentActiveTab: ViewModels.Tab = this.tabsManager.activeTab();
|
const currentActiveTab = this.tabsManager.activeTab();
|
||||||
|
|
||||||
return `${urlPrefixWithKeyParam}${token}#/${(currentActiveTab && currentActiveTab.hashLocation()) || ""}`;
|
return `${urlPrefixWithKeyParam}${token}#/${(currentActiveTab && currentActiveTab.hashLocation()) || ""}`;
|
||||||
}
|
}
|
||||||
|
@ -2432,18 +2443,18 @@ export default class Explorer {
|
||||||
throw new Error(`Invalid notebookContentItem: ${notebookContentItem}`);
|
throw new Error(`Invalid notebookContentItem: ${notebookContentItem}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const notebookTabs: NotebookV2Tab[] = this.tabsManager.getTabs(
|
const notebookTabs = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.NotebookV2,
|
ViewModels.CollectionTabKind.NotebookV2,
|
||||||
(tab: ViewModels.Tab) =>
|
tab =>
|
||||||
(tab as NotebookV2Tab).notebookPath &&
|
(tab as NotebookV2Tab).notebookPath &&
|
||||||
FileSystemUtil.isPathEqual((tab as NotebookV2Tab).notebookPath(), notebookContentItem.path)
|
FileSystemUtil.isPathEqual((tab as NotebookV2Tab).notebookPath(), notebookContentItem.path)
|
||||||
) as NotebookV2Tab[];
|
) as NotebookV2Tab[];
|
||||||
let notebookTab: NotebookV2Tab = notebookTabs && notebookTabs[0];
|
let notebookTab = notebookTabs && notebookTabs[0];
|
||||||
|
|
||||||
if (notebookTab) {
|
if (notebookTab) {
|
||||||
this.tabsManager.activateTab(notebookTab);
|
this.tabsManager.activateTab(notebookTab);
|
||||||
} else {
|
} else {
|
||||||
const options: ViewModels.NotebookTabOptions = {
|
const options: NotebookTabOptions = {
|
||||||
account: CosmosClient.databaseAccount(),
|
account: CosmosClient.databaseAccount(),
|
||||||
tabKind: ViewModels.CollectionTabKind.NotebookV2,
|
tabKind: ViewModels.CollectionTabKind.NotebookV2,
|
||||||
node: null,
|
node: null,
|
||||||
|
@ -2507,7 +2518,7 @@ export default class Explorer {
|
||||||
onSubmit: (input: string) => this.notebookManager?.notebookContentClient.renameNotebook(notebookFile, input)
|
onSubmit: (input: string) => this.notebookManager?.notebookContentClient.renameNotebook(notebookFile, input)
|
||||||
})
|
})
|
||||||
.then(newNotebookFile => {
|
.then(newNotebookFile => {
|
||||||
const notebookTabs: ViewModels.Tab[] = this.tabsManager.getTabs(
|
const notebookTabs = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.NotebookV2,
|
ViewModels.CollectionTabKind.NotebookV2,
|
||||||
(tab: NotebookV2Tab) => tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), originalPath)
|
(tab: NotebookV2Tab) => tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), originalPath)
|
||||||
);
|
);
|
||||||
|
@ -2877,7 +2888,7 @@ export default class Explorer {
|
||||||
|
|
||||||
const terminalTabs: TerminalTab[] = this.tabsManager.getTabs(
|
const terminalTabs: TerminalTab[] = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Terminal,
|
ViewModels.CollectionTabKind.Terminal,
|
||||||
(tab: ViewModels.Tab) => tab.hashLocation() == hashLocation
|
tab => tab.hashLocation() == hashLocation
|
||||||
) as TerminalTab[];
|
) as TerminalTab[];
|
||||||
let terminalTab: TerminalTab = terminalTabs && terminalTabs[0];
|
let terminalTab: TerminalTab = terminalTabs && terminalTabs[0];
|
||||||
|
|
||||||
|
@ -2911,7 +2922,7 @@ export default class Explorer {
|
||||||
|
|
||||||
const galleryTabs = this.tabsManager.getTabs(
|
const galleryTabs = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Gallery,
|
ViewModels.CollectionTabKind.Gallery,
|
||||||
(tab: ViewModels.Tab) => tab.hashLocation() == hashLocation
|
tab => tab.hashLocation() == hashLocation
|
||||||
);
|
);
|
||||||
let galleryTab = galleryTabs && galleryTabs[0];
|
let galleryTab = galleryTabs && galleryTabs[0];
|
||||||
|
|
||||||
|
@ -2957,17 +2968,14 @@ export default class Explorer {
|
||||||
|
|
||||||
const notebookViewerTabModule = this.notebookViewerTab;
|
const notebookViewerTabModule = this.notebookViewerTab;
|
||||||
|
|
||||||
let isNotebookViewerOpen = (tab: ViewModels.Tab) => {
|
let isNotebookViewerOpen = (tab: TabsBase) => {
|
||||||
const notebookViewerTab = tab as typeof notebookViewerTabModule.default;
|
const notebookViewerTab = tab as typeof notebookViewerTabModule.default;
|
||||||
return notebookViewerTab.notebookUrl === notebookUrl;
|
return notebookViewerTab.notebookUrl === notebookUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
const notebookViewerTabs = this.tabsManager.getTabs(
|
const notebookViewerTabs = this.tabsManager.getTabs(ViewModels.CollectionTabKind.NotebookV2, tab => {
|
||||||
ViewModels.CollectionTabKind.NotebookV2,
|
return tab.hashLocation() == hashLocation && isNotebookViewerOpen(tab);
|
||||||
(tab: ViewModels.Tab) => {
|
});
|
||||||
return tab.hashLocation() == hashLocation && isNotebookViewerOpen(tab);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
let notebookViewerTab = notebookViewerTabs && notebookViewerTabs[0];
|
let notebookViewerTab = notebookViewerTabs && notebookViewerTabs[0];
|
||||||
|
|
||||||
if (notebookViewerTab) {
|
if (notebookViewerTab) {
|
||||||
|
|
|
@ -12,11 +12,12 @@ import { CommandBar, ICommandBarItemProps } from "office-ui-fabric-react/lib/Com
|
||||||
import { StyleConstants } from "../../../Common/Constants";
|
import { StyleConstants } from "../../../Common/Constants";
|
||||||
import { CommandBarUtil } from "./CommandBarUtil";
|
import { CommandBarUtil } from "./CommandBarUtil";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export class CommandBarComponentAdapter implements ReactAdapter {
|
export class CommandBarComponentAdapter implements ReactAdapter {
|
||||||
public parameters: ko.Observable<number>;
|
public parameters: ko.Observable<number>;
|
||||||
public container: Explorer;
|
public container: Explorer;
|
||||||
private tabsButtons: ViewModels.NavbarButtonConfig[];
|
private tabsButtons: CommandButtonComponentProps[];
|
||||||
private isNotebookTabActive: ko.Computed<boolean>;
|
private isNotebookTabActive: ko.Computed<boolean>;
|
||||||
|
|
||||||
constructor(container: Explorer) {
|
constructor(container: Explorer) {
|
||||||
|
@ -51,7 +52,7 @@ export class CommandBarComponentAdapter implements ReactAdapter {
|
||||||
this.parameters = ko.observable(Date.now());
|
this.parameters = ko.observable(Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUpdateTabsButtons(buttons: ViewModels.NavbarButtonConfig[]): void {
|
public onUpdateTabsButtons(buttons: CommandButtonComponentProps[]): void {
|
||||||
this.tabsButtons = buttons;
|
this.tabsButtons = buttons;
|
||||||
this.triggerRender();
|
this.triggerRender();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,18 @@ import GitHubIcon from "../../../../images/github.svg";
|
||||||
import SynapseIcon from "../../../../images/synapse-link.svg";
|
import SynapseIcon from "../../../../images/synapse-link.svg";
|
||||||
import { config, Platform } from "../../../Config";
|
import { config, Platform } from "../../../Config";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export class CommandBarComponentButtonFactory {
|
export class CommandBarComponentButtonFactory {
|
||||||
private static counter: number = 0;
|
private static counter: number = 0;
|
||||||
|
|
||||||
public static createStaticCommandBarButtons(container: Explorer): ViewModels.NavbarButtonConfig[] {
|
public static createStaticCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||||
if (container.isAuthWithResourceToken()) {
|
if (container.isAuthWithResourceToken()) {
|
||||||
return CommandBarComponentButtonFactory.createStaticCommandBarButtonsForResourceToken(container);
|
return CommandBarComponentButtonFactory.createStaticCommandBarButtonsForResourceToken(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newCollectionBtn = CommandBarComponentButtonFactory.createNewCollectionGroup(container);
|
const newCollectionBtn = CommandBarComponentButtonFactory.createNewCollectionGroup(container);
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [newCollectionBtn];
|
const buttons: CommandButtonComponentProps[] = [newCollectionBtn];
|
||||||
|
|
||||||
const addSynapseLink = CommandBarComponentButtonFactory.createOpenSynapseLinkDialogButton(container);
|
const addSynapseLink = CommandBarComponentButtonFactory.createOpenSynapseLinkDialogButton(container);
|
||||||
if (addSynapseLink) {
|
if (addSynapseLink) {
|
||||||
|
@ -112,7 +113,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
|
|
||||||
if (CommandBarComponentButtonFactory.areScriptsSupported(container)) {
|
if (CommandBarComponentButtonFactory.areScriptsSupported(container)) {
|
||||||
const label = "New Stored Procedure";
|
const label = "New Stored Procedure";
|
||||||
const newStoredProcedureBtn: ViewModels.NavbarButtonConfig = {
|
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||||
iconSrc: AddStoredProcedureIcon,
|
iconSrc: AddStoredProcedureIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
|
@ -133,12 +134,12 @@ export class CommandBarComponentButtonFactory {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createContextCommandBarButtons(container: Explorer): ViewModels.NavbarButtonConfig[] {
|
public static createContextCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
|
|
||||||
if (!container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB()) {
|
if (!container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB()) {
|
||||||
const label = "New Shell";
|
const label = "New Shell";
|
||||||
const newMongoShellBtn: ViewModels.NavbarButtonConfig = {
|
const newMongoShellBtn: CommandButtonComponentProps = {
|
||||||
iconSrc: HostedTerminalIcon,
|
iconSrc: HostedTerminalIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
|
@ -156,15 +157,15 @@ export class CommandBarComponentButtonFactory {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createControlCommandBarButtons(container: Explorer): ViewModels.NavbarButtonConfig[] {
|
public static createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
if (window.dataExplorerPlatform === PlatformType.Hosted) {
|
if (window.dataExplorerPlatform === PlatformType.Hosted) {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!container.isPreferredApiCassandra()) {
|
if (!container.isPreferredApiCassandra()) {
|
||||||
const label = "Settings";
|
const label = "Settings";
|
||||||
const settingsPaneButton: ViewModels.NavbarButtonConfig = {
|
const settingsPaneButton: CommandButtonComponentProps = {
|
||||||
iconSrc: SettingsIcon,
|
iconSrc: SettingsIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => container.settingsPane.open(),
|
onCommandClick: () => container.settingsPane.open(),
|
||||||
|
@ -179,7 +180,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
|
|
||||||
if (container.isHostedDataExplorerEnabled()) {
|
if (container.isHostedDataExplorerEnabled()) {
|
||||||
const label = "Open Full Screen";
|
const label = "Open Full Screen";
|
||||||
const fullScreenButton: ViewModels.NavbarButtonConfig = {
|
const fullScreenButton: CommandButtonComponentProps = {
|
||||||
iconSrc: OpenInTabIcon,
|
iconSrc: OpenInTabIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => container.generateSharedAccessData(),
|
onCommandClick: () => container.generateSharedAccessData(),
|
||||||
|
@ -195,7 +196,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
|
|
||||||
if (!container.hasOwnProperty("isEmulator") || !container.isEmulator) {
|
if (!container.hasOwnProperty("isEmulator") || !container.isEmulator) {
|
||||||
const label = "Feedback";
|
const label = "Feedback";
|
||||||
const feedbackButtonOptions: ViewModels.NavbarButtonConfig = {
|
const feedbackButtonOptions: CommandButtonComponentProps = {
|
||||||
iconSrc: FeedbackIcon,
|
iconSrc: FeedbackIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => container.provideFeedbackEmail(),
|
onCommandClick: () => container.provideFeedbackEmail(),
|
||||||
|
@ -211,7 +212,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createDivider(): ViewModels.NavbarButtonConfig {
|
public static createDivider(): CommandButtonComponentProps {
|
||||||
const label = `divider${CommandBarComponentButtonFactory.counter++}`;
|
const label = `divider${CommandBarComponentButtonFactory.counter++}`;
|
||||||
return {
|
return {
|
||||||
isDivider: true,
|
isDivider: true,
|
||||||
|
@ -228,7 +229,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
return container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
return container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createNewCollectionGroup(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createNewCollectionGroup(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = container.addCollectionText();
|
const label = container.addCollectionText();
|
||||||
return {
|
return {
|
||||||
iconSrc: AddCollectionIcon,
|
iconSrc: AddCollectionIcon,
|
||||||
|
@ -241,7 +242,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenSynapseLinkDialogButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||||
if (config.platform === Platform.Emulator) {
|
if (config.platform === Platform.Emulator) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +277,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createNewDatabase(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createNewDatabase(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = container.addDatabaseText();
|
const label = container.addDatabaseText();
|
||||||
return {
|
return {
|
||||||
iconSrc: AddDatabaseIcon,
|
iconSrc: AddDatabaseIcon,
|
||||||
|
@ -291,7 +292,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createNewSQLQueryButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createNewSQLQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||||
if (container.isPreferredApiDocumentDB() || container.isPreferredApiGraph()) {
|
if (container.isPreferredApiDocumentDB() || container.isPreferredApiGraph()) {
|
||||||
const label = "New SQL Query";
|
const label = "New SQL Query";
|
||||||
return {
|
return {
|
||||||
|
@ -325,15 +326,15 @@ export class CommandBarComponentButtonFactory {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createScriptCommandButtons(container: Explorer): ViewModels.NavbarButtonConfig[] {
|
public static createScriptCommandButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
|
|
||||||
const shouldEnableScriptsCommands: boolean =
|
const shouldEnableScriptsCommands: boolean =
|
||||||
!container.isDatabaseNodeOrNoneSelected() && CommandBarComponentButtonFactory.areScriptsSupported(container);
|
!container.isDatabaseNodeOrNoneSelected() && CommandBarComponentButtonFactory.areScriptsSupported(container);
|
||||||
|
|
||||||
if (shouldEnableScriptsCommands) {
|
if (shouldEnableScriptsCommands) {
|
||||||
const label = "New Stored Procedure";
|
const label = "New Stored Procedure";
|
||||||
const newStoredProcedureBtn: ViewModels.NavbarButtonConfig = {
|
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||||
iconSrc: AddStoredProcedureIcon,
|
iconSrc: AddStoredProcedureIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
|
@ -350,7 +351,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
|
|
||||||
if (shouldEnableScriptsCommands) {
|
if (shouldEnableScriptsCommands) {
|
||||||
const label = "New UDF";
|
const label = "New UDF";
|
||||||
const newUserDefinedFunctionBtn: ViewModels.NavbarButtonConfig = {
|
const newUserDefinedFunctionBtn: CommandButtonComponentProps = {
|
||||||
iconSrc: AddUdfIcon,
|
iconSrc: AddUdfIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
|
@ -367,7 +368,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
|
|
||||||
if (shouldEnableScriptsCommands) {
|
if (shouldEnableScriptsCommands) {
|
||||||
const label = "New Trigger";
|
const label = "New Trigger";
|
||||||
const newTriggerBtn: ViewModels.NavbarButtonConfig = {
|
const newTriggerBtn: CommandButtonComponentProps = {
|
||||||
iconSrc: AddTriggerIcon,
|
iconSrc: AddTriggerIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
|
@ -385,7 +386,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createScaleAndSettingsButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createScaleAndSettingsButton(container: Explorer): CommandButtonComponentProps {
|
||||||
let isShared = false;
|
let isShared = false;
|
||||||
if (container.isDatabaseNodeSelected()) {
|
if (container.isDatabaseNodeSelected()) {
|
||||||
isShared = container.findSelectedDatabase().isDatabaseShared();
|
isShared = container.findSelectedDatabase().isDatabaseShared();
|
||||||
|
@ -410,7 +411,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createNewNotebookButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createNewNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "New Notebook";
|
const label = "New Notebook";
|
||||||
return {
|
return {
|
||||||
iconSrc: NewNotebookIcon,
|
iconSrc: NewNotebookIcon,
|
||||||
|
@ -423,7 +424,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createuploadNotebookButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createuploadNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Upload to Notebook Server";
|
const label = "Upload to Notebook Server";
|
||||||
return {
|
return {
|
||||||
iconSrc: NewNotebookIcon,
|
iconSrc: NewNotebookIcon,
|
||||||
|
@ -436,7 +437,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenQueryButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Open Query";
|
const label = "Open Query";
|
||||||
return {
|
return {
|
||||||
iconSrc: BrowseQueriesIcon,
|
iconSrc: BrowseQueriesIcon,
|
||||||
|
@ -449,7 +450,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenQueryFromDiskButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenQueryFromDiskButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Open Query From Disk";
|
const label = "Open Query From Disk";
|
||||||
return {
|
return {
|
||||||
iconSrc: OpenQueryFromDiskIcon,
|
iconSrc: OpenQueryFromDiskIcon,
|
||||||
|
@ -462,7 +463,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createEnableNotebooksButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createEnableNotebooksButton(container: Explorer): CommandButtonComponentProps {
|
||||||
if (config.platform === Platform.Emulator) {
|
if (config.platform === Platform.Emulator) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +484,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenTerminalButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Open Terminal";
|
const label = "Open Terminal";
|
||||||
return {
|
return {
|
||||||
iconSrc: CosmosTerminalIcon,
|
iconSrc: CosmosTerminalIcon,
|
||||||
|
@ -496,7 +497,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenMongoTerminalButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenMongoTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Open Mongo Shell";
|
const label = "Open Mongo Shell";
|
||||||
const tooltip =
|
const tooltip =
|
||||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||||
|
@ -522,7 +523,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createOpenCassandraTerminalButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createOpenCassandraTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Open Cassandra Shell";
|
const label = "Open Cassandra Shell";
|
||||||
const tooltip =
|
const tooltip =
|
||||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||||
|
@ -548,7 +549,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createNotebookWorkspaceResetButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createNotebookWorkspaceResetButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Reset Workspace";
|
const label = "Reset Workspace";
|
||||||
return {
|
return {
|
||||||
iconSrc: ResetWorkspaceIcon,
|
iconSrc: ResetWorkspaceIcon,
|
||||||
|
@ -561,7 +562,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createManageGitHubAccountButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
private static createManageGitHubAccountButton(container: Explorer): CommandButtonComponentProps {
|
||||||
let connectedToGitHub: boolean = container.notebookManager?.gitHubOAuthService.isLoggedIn();
|
let connectedToGitHub: boolean = container.notebookManager?.gitHubOAuthService.isLoggedIn();
|
||||||
const label = connectedToGitHub ? "Manage GitHub settings" : "Connect to GitHub";
|
const label = connectedToGitHub ? "Manage GitHub settings" : "Connect to GitHub";
|
||||||
return {
|
return {
|
||||||
|
@ -584,7 +585,7 @@ export class CommandBarComponentButtonFactory {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createStaticCommandBarButtonsForResourceToken(container: Explorer): ViewModels.NavbarButtonConfig[] {
|
private static createStaticCommandBarButtonsForResourceToken(container: Explorer): CommandButtonComponentProps[] {
|
||||||
const newSqlQueryBtn = CommandBarComponentButtonFactory.createNewSQLQueryButton(container);
|
const newSqlQueryBtn = CommandBarComponentButtonFactory.createNewSQLQueryButton(container);
|
||||||
const openQueryBtn = CommandBarComponentButtonFactory.createOpenQueryButton(container);
|
const openQueryBtn = CommandBarComponentButtonFactory.createOpenQueryButton(container);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { CommandBarUtil } from "./CommandBarUtil";
|
import { CommandBarUtil } from "./CommandBarUtil";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar";
|
import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar";
|
||||||
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
describe("CommandBarUtil tests", () => {
|
describe("CommandBarUtil tests", () => {
|
||||||
const createButton = (): ViewModels.NavbarButtonConfig => {
|
const createButton = (): CommandButtonComponentProps => {
|
||||||
return {
|
return {
|
||||||
iconSrc: "icon",
|
iconSrc: "icon",
|
||||||
iconAlt: "label",
|
iconAlt: "label",
|
||||||
|
@ -54,7 +55,7 @@ describe("CommandBarUtil tests", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create buttons with unique keys", () => {
|
it("should create buttons with unique keys", () => {
|
||||||
const btns: ViewModels.NavbarButtonConfig[] = [];
|
const btns: CommandButtonComponentProps[] = [];
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
btns.push(createButton());
|
btns.push(createButton());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import _ from "underscore";
|
import _ from "underscore";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
|
||||||
import { Observable } from "knockout";
|
import { Observable } from "knockout";
|
||||||
import { IconType } from "office-ui-fabric-react/lib/Icon";
|
import { IconType } from "office-ui-fabric-react/lib/Icon";
|
||||||
import { IComponentAsProps } from "office-ui-fabric-react/lib/Utilities";
|
import { IComponentAsProps } from "office-ui-fabric-react/lib/Utilities";
|
||||||
import { KeyCodes, StyleConstants } from "../../../Common/Constants";
|
import { StyleConstants } from "../../../Common/Constants";
|
||||||
import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar";
|
import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar";
|
||||||
import { Dropdown, DropdownMenuItemType, IDropdownStyles, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown";
|
import { Dropdown, IDropdownStyles, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown";
|
||||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
import ChevronDownIcon from "../../../../images/Chevron_down.svg";
|
import ChevronDownIcon from "../../../../images/Chevron_down.svg";
|
||||||
import { ArcadiaMenuPicker } from "../../Controls/Arcadia/ArcadiaMenuPicker";
|
import { ArcadiaMenuPicker } from "../../Controls/Arcadia/ArcadiaMenuPicker";
|
||||||
|
@ -21,13 +20,13 @@ export class CommandBarUtil {
|
||||||
* Convert our NavbarButtonConfig to UI Fabric buttons
|
* Convert our NavbarButtonConfig to UI Fabric buttons
|
||||||
* @param btns
|
* @param btns
|
||||||
*/
|
*/
|
||||||
public static convertButton(btns: ViewModels.NavbarButtonConfig[], backgroundColor: string): ICommandBarItemProps[] {
|
public static convertButton(btns: CommandButtonComponentProps[], backgroundColor: string): ICommandBarItemProps[] {
|
||||||
const buttonHeightPx = StyleConstants.CommandBarButtonHeight;
|
const buttonHeightPx = StyleConstants.CommandBarButtonHeight;
|
||||||
|
|
||||||
return btns
|
return btns
|
||||||
.filter(btn => btn)
|
.filter(btn => btn)
|
||||||
.map(
|
.map(
|
||||||
(btn: ViewModels.NavbarButtonConfig, index: number): ICommandBarItemProps => {
|
(btn: CommandButtonComponentProps, index: number): ICommandBarItemProps => {
|
||||||
if (btn.isDivider) {
|
if (btn.isDivider) {
|
||||||
return CommandBarUtil.createDivider(btn.commandButtonLabel);
|
return CommandBarUtil.createDivider(btn.commandButtonLabel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import {
|
||||||
import { CommandButtonComponent } from "../../Controls/CommandButton/CommandButtonComponent";
|
CommandButtonComponent,
|
||||||
|
CommandButtonComponentProps
|
||||||
|
} from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export interface ControlBarComponentProps {
|
export interface ControlBarComponentProps {
|
||||||
buttons: ViewModels.NavbarButtonConfig[];
|
buttons: CommandButtonComponentProps[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ControlBarComponent extends React.Component<ControlBarComponentProps> {
|
export class ControlBarComponent extends React.Component<ControlBarComponentProps> {
|
||||||
private static renderButtons(commandButtonOptions: ViewModels.NavbarButtonConfig[]): JSX.Element[] {
|
private static renderButtons(commandButtonOptions: CommandButtonComponentProps[]): JSX.Element[] {
|
||||||
return commandButtonOptions.map(
|
return commandButtonOptions.map(
|
||||||
(btn: ViewModels.NavbarButtonConfig, index: number): JSX.Element => {
|
(btn: CommandButtonComponentProps, index: number): JSX.Element => {
|
||||||
// Remove label
|
// Remove label
|
||||||
btn.commandButtonLabel = null;
|
btn.commandButtonLabel = null;
|
||||||
return CommandButtonComponent.renderButton(btn, `${index}`);
|
return CommandButtonComponent.renderButton(btn, `${index}`);
|
||||||
|
|
|
@ -8,12 +8,12 @@ import * as ko from "knockout";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||||
import { ControlBarComponent } from "./ControlBarComponent";
|
import { ControlBarComponent } from "./ControlBarComponent";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export class ControlBarComponentAdapter implements ReactAdapter {
|
export class ControlBarComponentAdapter implements ReactAdapter {
|
||||||
public parameters: ko.Observable<number>;
|
public parameters: ko.Observable<number>;
|
||||||
|
|
||||||
constructor(private buttons: ko.ObservableArray<ViewModels.NavbarButtonConfig>) {
|
constructor(private buttons: ko.ObservableArray<CommandButtonComponentProps>) {
|
||||||
this.buttons.subscribe(() => this.forceRender());
|
this.buttons.subscribe(() => this.forceRender());
|
||||||
this.parameters = ko.observable<number>(Date.now());
|
this.parameters = ko.observable<number>(Date.now());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
* Notebook container related stuff
|
* Notebook container related stuff
|
||||||
*/
|
*/
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import * as Constants from "../../Common/Constants";
|
import * as Constants from "../../Common/Constants";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
|
|
||||||
export class NotebookContainerClient implements ViewModels.INotebookContainerClient {
|
export class NotebookContainerClient {
|
||||||
private reconnectingNotificationId: string;
|
private reconnectingNotificationId: string;
|
||||||
private isResettingWorkspace: boolean;
|
private isResettingWorkspace: boolean;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem";
|
import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem";
|
||||||
import { StringUtils } from "../../Utils/StringUtils";
|
import { StringUtils } from "../../Utils/StringUtils";
|
||||||
import { FileSystemUtil } from "./FileSystemUtil";
|
import { FileSystemUtil } from "./FileSystemUtil";
|
||||||
|
@ -9,7 +8,7 @@ import { ServerConfig, IContent, IContentProvider, FileType, IEmptyContent } fro
|
||||||
import { AjaxResponse } from "rxjs/ajax";
|
import { AjaxResponse } from "rxjs/ajax";
|
||||||
import { stringifyNotebook } from "@nteract/commutable";
|
import { stringifyNotebook } from "@nteract/commutable";
|
||||||
|
|
||||||
export class NotebookContentClient implements ViewModels.INotebookContentClient {
|
export class NotebookContentClient {
|
||||||
constructor(
|
constructor(
|
||||||
private notebookServerInfo: ko.Observable<DataModels.NotebookWorkspaceConnectionInfo>,
|
private notebookServerInfo: ko.Observable<DataModels.NotebookWorkspaceConnectionInfo>,
|
||||||
private notebookBasePath: ko.Observable<string>,
|
private notebookBasePath: ko.Observable<string>,
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { JunoClient } from "../../Juno/JunoClient";
|
import { JunoClient } from "../../Juno/JunoClient";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
||||||
import { GitHubClient } from "../../GitHub/GitHubClient";
|
import { GitHubClient } from "../../GitHub/GitHubClient";
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
|
@ -25,6 +24,7 @@ import { PublishNotebookPaneAdapter } from "../Panes/PublishNotebookPaneAdapter"
|
||||||
import { getFullName } from "../../Utils/UserUtils";
|
import { getFullName } from "../../Utils/UserUtils";
|
||||||
import { ImmutableNotebook } from "@nteract/commutable";
|
import { ImmutableNotebook } from "@nteract/commutable";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||||
|
|
||||||
export interface NotebookManagerOptions {
|
export interface NotebookManagerOptions {
|
||||||
container: Explorer;
|
container: Explorer;
|
||||||
|
@ -40,14 +40,14 @@ export default class NotebookManager {
|
||||||
public junoClient: JunoClient;
|
public junoClient: JunoClient;
|
||||||
|
|
||||||
public notebookContentProvider: IContentProvider;
|
public notebookContentProvider: IContentProvider;
|
||||||
public notebookClient: ViewModels.INotebookContainerClient;
|
public notebookClient: NotebookContainerClient;
|
||||||
public notebookContentClient: ViewModels.INotebookContentClient;
|
public notebookContentClient: NotebookContentClient;
|
||||||
|
|
||||||
private gitHubContentProvider: GitHubContentProvider;
|
private gitHubContentProvider: GitHubContentProvider;
|
||||||
public gitHubOAuthService: GitHubOAuthService;
|
public gitHubOAuthService: GitHubOAuthService;
|
||||||
private gitHubClient: GitHubClient;
|
private gitHubClient: GitHubClient;
|
||||||
|
|
||||||
public gitHubReposPane: ViewModels.ContextualPane;
|
public gitHubReposPane: ContextualPaneBase;
|
||||||
public publishNotebookPaneAdapter: PublishNotebookPaneAdapter;
|
public publishNotebookPaneAdapter: PublishNotebookPaneAdapter;
|
||||||
|
|
||||||
public initialize(params: NotebookManagerOptions): void {
|
public initialize(params: NotebookManagerOptions): void {
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import * as Constants from "../../Common/Constants";
|
import * as Constants from "../../Common/Constants";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import AddCollectionPane from "./AddCollectionPane";
|
import AddCollectionPane from "./AddCollectionPane";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import { AutopilotTier } from "../../Contracts/DataModels";
|
import { AutopilotTier, DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
|
|
||||||
describe("Add Collection Pane", () => {
|
describe("Add Collection Pane", () => {
|
||||||
describe("isValid()", () => {
|
describe("isValid()", () => {
|
||||||
let explorer: Explorer;
|
let explorer: Explorer;
|
||||||
const mockDatabaseAccount: ViewModels.DatabaseAccount = {
|
const mockDatabaseAccount: DatabaseAccount = {
|
||||||
id: "mock",
|
id: "mock",
|
||||||
kind: "DocumentDB",
|
kind: "DocumentDB",
|
||||||
location: "",
|
location: "",
|
||||||
|
@ -24,7 +23,7 @@ describe("Add Collection Pane", () => {
|
||||||
tags: []
|
tags: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockFreeTierDatabaseAccount: ViewModels.DatabaseAccount = {
|
const mockFreeTierDatabaseAccount: DatabaseAccount = {
|
||||||
id: "mock",
|
id: "mock",
|
||||||
kind: "DocumentDB",
|
kind: "DocumentDB",
|
||||||
location: "",
|
location: "",
|
||||||
|
|
|
@ -22,6 +22,12 @@ import { HashMap } from "../../Common/HashMap";
|
||||||
import { PlatformType } from "../../PlatformType";
|
import { PlatformType } from "../../PlatformType";
|
||||||
import { refreshCachedResources, getOrCreateDatabaseAndCollection } from "../../Common/DocumentClientUtilityBase";
|
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 {
|
export default class AddCollectionPane extends ContextualPaneBase {
|
||||||
public defaultExperience: ko.Computed<string>;
|
public defaultExperience: ko.Computed<string>;
|
||||||
public databaseIds: ko.ObservableArray<string>;
|
public databaseIds: ko.ObservableArray<string>;
|
||||||
|
@ -100,7 +106,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||||
private _databaseOffers: HashMap<DataModels.Offer>;
|
private _databaseOffers: HashMap<DataModels.Offer>;
|
||||||
private _isSynapseLinkEnabled: ko.Computed<boolean>;
|
private _isSynapseLinkEnabled: ko.Computed<boolean>;
|
||||||
|
|
||||||
constructor(options: ViewModels.AddCollectionPaneOptions) {
|
constructor(options: AddCollectionPaneOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
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());
|
||||||
|
@ -619,7 +625,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||||
this._isSynapseLinkEnabled = ko.computed(() => {
|
this._isSynapseLinkEnabled = ko.computed(() => {
|
||||||
const databaseAccount =
|
const databaseAccount =
|
||||||
(this.container && this.container.databaseAccount && this.container.databaseAccount()) ||
|
(this.container && this.container.databaseAccount && this.container.databaseAccount()) ||
|
||||||
({} as ViewModels.DatabaseAccount);
|
({} as DataModels.DatabaseAccount);
|
||||||
const properties = databaseAccount.properties || ({} as DataModels.DatabaseAccountExtendedProperties);
|
const properties = databaseAccount.properties || ({} as DataModels.DatabaseAccountExtendedProperties);
|
||||||
|
|
||||||
// TODO: remove check for capability once all accounts have been migrated
|
// TODO: remove check for capability once all accounts have been migrated
|
||||||
|
@ -1266,10 +1272,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||||
: SharedConstants.CollectionCreation.NumberOfPartitionsInUnlimitedCollection;
|
: SharedConstants.CollectionCreation.NumberOfPartitionsInUnlimitedCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _convertShardKeyToPartitionKey(
|
private _convertShardKeyToPartitionKey(shardKey: string): string {
|
||||||
shardKey: string,
|
|
||||||
configurationOverrides: ViewModels.ConfigurationOverrides
|
|
||||||
): string {
|
|
||||||
if (!shardKey) {
|
if (!shardKey) {
|
||||||
return shardKey;
|
return shardKey;
|
||||||
}
|
}
|
||||||
|
@ -1331,10 +1334,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||||
};
|
};
|
||||||
if (this.container.isPreferredApiMongoDB()) {
|
if (this.container.isPreferredApiMongoDB()) {
|
||||||
transform = (value: string) => {
|
transform = (value: string) => {
|
||||||
return this._convertShardKeyToPartitionKey(
|
return this._convertShardKeyToPartitionKey(value);
|
||||||
value,
|
|
||||||
this.container.databaseAccount().properties.configurationOverrides
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@ import * as Constants from "../../Common/Constants";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import AddDatabasePane from "./AddDatabasePane";
|
import AddDatabasePane from "./AddDatabasePane";
|
||||||
|
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
|
|
||||||
describe("Add Database Pane", () => {
|
describe("Add Database Pane", () => {
|
||||||
describe("getSharedThroughputDefault()", () => {
|
describe("getSharedThroughputDefault()", () => {
|
||||||
let explorer: Explorer;
|
let explorer: Explorer;
|
||||||
const mockDatabaseAccount: ViewModels.DatabaseAccount = {
|
const mockDatabaseAccount: DatabaseAccount = {
|
||||||
id: "mock",
|
id: "mock",
|
||||||
kind: "DocumentDB",
|
kind: "DocumentDB",
|
||||||
location: "",
|
location: "",
|
||||||
|
@ -22,7 +23,7 @@ describe("Add Database Pane", () => {
|
||||||
tags: []
|
tags: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockFreeTierDatabaseAccount: ViewModels.DatabaseAccount = {
|
const mockFreeTierDatabaseAccount: DatabaseAccount = {
|
||||||
id: "mock",
|
id: "mock",
|
||||||
kind: "DocumentDB",
|
kind: "DocumentDB",
|
||||||
location: "",
|
location: "",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
import { QueriesGridComponentAdapter } from "../Controls/QueriesGridReactComponent/QueriesGridComponentAdapter";
|
import { QueriesGridComponentAdapter } from "../Controls/QueriesGridReactComponent/QueriesGridComponentAdapter";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import QueryTab from "../Tabs/QueryTab";
|
||||||
|
|
||||||
export class BrowseQueriesPane extends ContextualPaneBase {
|
export class BrowseQueriesPane extends ContextualPaneBase {
|
||||||
public queriesGridComponentAdapter: QueriesGridComponentAdapter;
|
public queriesGridComponentAdapter: QueriesGridComponentAdapter;
|
||||||
|
@ -87,7 +88,7 @@ export class BrowseQueriesPane extends ContextualPaneBase {
|
||||||
} else {
|
} else {
|
||||||
selectedCollection.onNewQueryClick(selectedCollection, null);
|
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.tabTitle(savedQuery.queryName);
|
||||||
queryTab.tabPath(`${selectedCollection.databaseId}>${selectedCollection.id()}>${savedQuery.queryName}`);
|
queryTab.tabPath(`${selectedCollection.databaseId}>${selectedCollection.id()}>${savedQuery.queryName}`);
|
||||||
queryTab.initialEditorContent(savedQuery.query);
|
queryTab.initialEditorContent(savedQuery.query);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
|
||||||
// TODO: Use specific actions for logging telemetry data
|
// 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 id: string;
|
||||||
public container: Explorer;
|
public container: Explorer;
|
||||||
public firstFieldHasFocus: ko.Observable<boolean>;
|
public firstFieldHasFocus: ko.Observable<boolean>;
|
||||||
|
|
|
@ -106,10 +106,10 @@ describe("Delete Collection Confirmation Pane", () => {
|
||||||
fakeExplorer.isSelectedDatabaseShared = () => false;
|
fakeExplorer.isSelectedDatabaseShared = () => false;
|
||||||
const SubscriptionId = "testId";
|
const SubscriptionId = "testId";
|
||||||
const AccountName = "testAccount";
|
const AccountName = "testAccount";
|
||||||
fakeExplorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
|
fakeExplorer.databaseAccount = ko.observable<DataModels.DatabaseAccount>({
|
||||||
id: SubscriptionId,
|
id: SubscriptionId,
|
||||||
name: AccountName
|
name: AccountName
|
||||||
} as ViewModels.DatabaseAccount);
|
} as DataModels.DatabaseAccount);
|
||||||
|
|
||||||
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
||||||
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
||||||
|
|
|
@ -66,9 +66,7 @@ export default class DeleteCollectionConfirmationPane extends ContextualPaneBase
|
||||||
this.isExecuting(false);
|
this.isExecuting(false);
|
||||||
this.close();
|
this.close();
|
||||||
this.container.selectedNode(selectedCollection.database);
|
this.container.selectedNode(selectedCollection.database);
|
||||||
this.container.tabsManager?.closeTabsByComparator(
|
this.container.tabsManager?.closeTabsByComparator(tab => tab.node && tab.node.rid === selectedCollection.rid);
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === selectedCollection.rid
|
|
||||||
);
|
|
||||||
this.container.refreshAllDatabases();
|
this.container.refreshAllDatabases();
|
||||||
this.resetData();
|
this.resetData();
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
|
|
|
@ -97,10 +97,10 @@ describe("Delete Database Confirmation Pane", () => {
|
||||||
fakeExplorer.isSelectedDatabaseShared = () => false;
|
fakeExplorer.isSelectedDatabaseShared = () => false;
|
||||||
const SubscriptionId = "testId";
|
const SubscriptionId = "testId";
|
||||||
const AccountName = "testAccount";
|
const AccountName = "testAccount";
|
||||||
fakeExplorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
|
fakeExplorer.databaseAccount = ko.observable<DataModels.DatabaseAccount>({
|
||||||
id: SubscriptionId,
|
id: SubscriptionId,
|
||||||
name: AccountName
|
name: AccountName
|
||||||
} as ViewModels.DatabaseAccount);
|
} as DataModels.DatabaseAccount);
|
||||||
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
fakeExplorer.defaultExperience = ko.observable<string>("DocumentDB");
|
||||||
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -67,16 +67,12 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
|
||||||
this.isExecuting(false);
|
this.isExecuting(false);
|
||||||
this.close();
|
this.close();
|
||||||
this.container.refreshAllDatabases();
|
this.container.refreshAllDatabases();
|
||||||
this.container.tabsManager.closeTabsByComparator(
|
this.container.tabsManager.closeTabsByComparator(tab => tab.node && tab.node.rid === selectedDatabase.rid);
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === selectedDatabase.rid
|
|
||||||
);
|
|
||||||
this.container.selectedNode(null);
|
this.container.selectedNode(null);
|
||||||
selectedDatabase
|
selectedDatabase
|
||||||
.collections()
|
.collections()
|
||||||
.forEach((collection: ViewModels.Collection) =>
|
.forEach((collection: ViewModels.Collection) =>
|
||||||
this.container.tabsManager.closeTabsByComparator(
|
this.container.tabsManager.closeTabsByComparator(tab => tab.node && tab.node.rid === collection.rid)
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === collection.rid
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
this.resetData();
|
this.resetData();
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
|
|
|
@ -16,6 +16,11 @@ import { BranchesProps, PinnedReposProps, UnpinnedReposProps } from "../Controls
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
|
|
||||||
|
interface GitHubReposPaneOptions extends ViewModels.PaneOptions {
|
||||||
|
gitHubClient: GitHubClient;
|
||||||
|
junoClient: JunoClient;
|
||||||
|
}
|
||||||
|
|
||||||
export class GitHubReposPane extends ContextualPaneBase {
|
export class GitHubReposPane extends ContextualPaneBase {
|
||||||
private static readonly PageSize = 30;
|
private static readonly PageSize = 30;
|
||||||
|
|
||||||
|
@ -33,7 +38,7 @@ export class GitHubReposPane extends ContextualPaneBase {
|
||||||
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
private allGitHubReposLastPageInfo?: IGitHubPageInfo;
|
||||||
private pinnedReposUpdated: boolean;
|
private pinnedReposUpdated: boolean;
|
||||||
|
|
||||||
constructor(options: ViewModels.GitHubReposPaneOptions) {
|
constructor(options: GitHubReposPaneOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.gitHubClient = options.gitHubClient;
|
this.gitHubClient = options.gitHubClient;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||||
|
import QueryTab from "../Tabs/QueryTab";
|
||||||
|
|
||||||
export class LoadQueryPane extends ContextualPaneBase {
|
export class LoadQueryPane extends ContextualPaneBase {
|
||||||
public selectedFilesTitle: ko.Observable<string>;
|
public selectedFilesTitle: ko.Observable<string>;
|
||||||
|
@ -111,7 +112,7 @@ export class LoadQueryPane extends ContextualPaneBase {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (evt: any): void => {
|
reader.onload = (evt: any): void => {
|
||||||
const fileData: string = evt.target.result;
|
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.initialEditorContent(fileData);
|
||||||
queryTab.sqlQueryEditorContent(fileData);
|
queryTab.sqlQueryEditorContent(fileData);
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import QueryTab from "../Tabs/QueryTab";
|
||||||
|
|
||||||
export class SaveQueryPane extends ContextualPaneBase {
|
export class SaveQueryPane extends ContextualPaneBase {
|
||||||
public queryName: ko.Observable<string>;
|
public queryName: ko.Observable<string>;
|
||||||
|
@ -34,8 +35,7 @@ export class SaveQueryPane extends ContextualPaneBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryName: string = this.queryName();
|
const queryName: string = this.queryName();
|
||||||
const queryTab: ViewModels.QueryTab =
|
const queryTab = this.container && (this.container.tabsManager.activeTab() as QueryTab);
|
||||||
this.container && (this.container.tabsManager.activeTab() as ViewModels.QueryTab);
|
|
||||||
const query: string = queryTab && queryTab.sqlQueryEditorContent();
|
const query: string = queryTab && queryTab.sqlQueryEditorContent();
|
||||||
if (!queryName || queryName.length === 0) {
|
if (!queryName || queryName.length === 0) {
|
||||||
this.formErrors("No query name specified");
|
this.formErrors("No query name specified");
|
||||||
|
|
|
@ -5,11 +5,22 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
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
|
* Generic pane to get a single string input from user
|
||||||
*/
|
*/
|
||||||
export class StringInputPane extends ContextualPaneBase {
|
export class StringInputPane extends ContextualPaneBase {
|
||||||
private openOptions: ViewModels.StringInputPaneOpenOptions;
|
private openOptions: StringInputPaneOpenOptions;
|
||||||
private submitButtonLabel: ko.Observable<string>;
|
private submitButtonLabel: ko.Observable<string>;
|
||||||
private inputLabel: ko.Observable<string>;
|
private inputLabel: ko.Observable<string>;
|
||||||
private stringInput: ko.Observable<string>;
|
private stringInput: ko.Observable<string>;
|
||||||
|
@ -78,7 +89,7 @@ export class StringInputPane extends ContextualPaneBase {
|
||||||
this.resetFileInput();
|
this.resetFileInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public openWithOptions<T>(options: ViewModels.StringInputPaneOpenOptions): Q.Promise<T> {
|
public openWithOptions<T>(options: StringInputPaneOpenOptions): Q.Promise<T> {
|
||||||
this.openOptions = options;
|
this.openOptions = options;
|
||||||
this.title(this.openOptions.paneTitle);
|
this.title(this.openOptions.paneTitle);
|
||||||
if (this.openOptions.submitButtonLabel) {
|
if (this.openOptions.submitButtonLabel) {
|
||||||
|
|
|
@ -5,10 +5,21 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
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 {
|
export class UploadFilePane extends ContextualPaneBase {
|
||||||
public selectedFilesTitle: ko.Observable<string>;
|
public selectedFilesTitle: ko.Observable<string>;
|
||||||
public files: ko.Observable<FileList>;
|
public files: ko.Observable<FileList>;
|
||||||
private openOptions: ViewModels.UploadFilePaneOpenOptions;
|
private openOptions: UploadFilePaneOpenOptions;
|
||||||
private submitButtonLabel: ko.Observable<string>;
|
private submitButtonLabel: ko.Observable<string>;
|
||||||
private selectFileInputLabel: ko.Observable<string>;
|
private selectFileInputLabel: ko.Observable<string>;
|
||||||
private extensions: ko.Observable<string>;
|
private extensions: ko.Observable<string>;
|
||||||
|
@ -79,7 +90,7 @@ export class UploadFilePane extends ContextualPaneBase {
|
||||||
this.resetFileInput();
|
this.resetFileInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public openWithOptions(options: ViewModels.UploadFilePaneOpenOptions): void {
|
public openWithOptions(options: UploadFilePaneOpenOptions): void {
|
||||||
this.openOptions = options;
|
this.openOptions = options;
|
||||||
this.title(this.openOptions.paneTitle);
|
this.title(this.openOptions.paneTitle);
|
||||||
if (this.openOptions.submitButtonLabel) {
|
if (this.openOptions.submitButtonLabel) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class SplashScreenComponentAdapter implements ReactAdapter {
|
||||||
|
|
||||||
constructor(private container: Explorer) {
|
constructor(private container: Explorer) {
|
||||||
this.parameters = ko.observable<number>(Date.now());
|
this.parameters = ko.observable<number>(Date.now());
|
||||||
this.container.tabsManager.openedTabs.subscribe((tabs: ViewModels.Tab[]) => {
|
this.container.tabsManager.openedTabs.subscribe(tabs => {
|
||||||
if (tabs.length === 0) {
|
if (tabs.length === 0) {
|
||||||
this.forceRender();
|
this.forceRender();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import TabsBase from "./TabsBase";
|
||||||
import { DocumentsGridMetrics } from "../../Common/Constants";
|
import { DocumentsGridMetrics } from "../../Common/Constants";
|
||||||
import { Splitter, SplitterBounds, SplitterDirection } from "../../Common/Splitter";
|
import { Splitter, SplitterBounds, SplitterDirection } from "../../Common/Splitter";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Toolbar from "../Controls/Toolbar/Toolbar";
|
|
||||||
import SaveIcon from "../../../images/save-cosmos.svg";
|
import SaveIcon from "../../../images/save-cosmos.svg";
|
||||||
import DiscardIcon from "../../../images/discard.svg";
|
import DiscardIcon from "../../../images/discard.svg";
|
||||||
import DeleteIcon from "../../../images/delete.svg";
|
import DeleteIcon from "../../../images/delete.svg";
|
||||||
|
@ -28,16 +27,16 @@ import {
|
||||||
createDocument,
|
createDocument,
|
||||||
updateDocument
|
updateDocument
|
||||||
} from "../../Common/DocumentClientUtilityBase";
|
} from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export default class ConflictsTab extends TabsBase {
|
export default class ConflictsTab extends TabsBase {
|
||||||
public selectedConflictId: ko.Observable<ViewModels.ConflictId>;
|
public selectedConflictId: ko.Observable<ConflictId>;
|
||||||
public selectedConflictContent: ViewModels.Editable<string>;
|
public selectedConflictContent: ViewModels.Editable<string>;
|
||||||
public selectedConflictCurrent: ViewModels.Editable<string>;
|
public selectedConflictCurrent: ViewModels.Editable<string>;
|
||||||
public documentContentsGridId: string;
|
public documentContentsGridId: string;
|
||||||
public documentContentsContainerId: string;
|
public documentContentsContainerId: string;
|
||||||
public isEditorDirty: ko.Computed<boolean>;
|
public isEditorDirty: ko.Computed<boolean>;
|
||||||
public editorState: ko.Observable<ViewModels.DocumentExplorerState>;
|
public editorState: ko.Observable<ViewModels.DocumentExplorerState>;
|
||||||
public toolbarViewModel = ko.observable<Toolbar>();
|
|
||||||
public acceptChangesButton: ViewModels.Button;
|
public acceptChangesButton: ViewModels.Button;
|
||||||
public discardButton: ViewModels.Button;
|
public discardButton: ViewModels.Button;
|
||||||
public deleteButton: ViewModels.Button;
|
public deleteButton: ViewModels.Button;
|
||||||
|
@ -54,7 +53,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
public partitionKeyPropertyHeader: string;
|
public partitionKeyPropertyHeader: string;
|
||||||
public partitionKeyProperty: string;
|
public partitionKeyProperty: string;
|
||||||
public conflictOperation: ko.Observable<string> = ko.observable<string>();
|
public conflictOperation: ko.Observable<string> = ko.observable<string>();
|
||||||
public conflictIds: ko.ObservableArray<ViewModels.ConflictId>;
|
public conflictIds: ko.ObservableArray<ConflictId>;
|
||||||
|
|
||||||
private _documentsIterator: MinimalQueryIterator;
|
private _documentsIterator: MinimalQueryIterator;
|
||||||
private _container: Explorer;
|
private _container: Explorer;
|
||||||
|
@ -70,7 +69,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
this.editorState = ko.observable<ViewModels.DocumentExplorerState>(
|
this.editorState = ko.observable<ViewModels.DocumentExplorerState>(
|
||||||
ViewModels.DocumentExplorerState.noDocumentSelected
|
ViewModels.DocumentExplorerState.noDocumentSelected
|
||||||
);
|
);
|
||||||
this.selectedConflictId = ko.observable<ViewModels.ConflictId>();
|
this.selectedConflictId = ko.observable<ConflictId>();
|
||||||
this.selectedConflictContent = editable.observable<any>("");
|
this.selectedConflictContent = editable.observable<any>("");
|
||||||
this.selectedConflictCurrent = editable.observable<any>("");
|
this.selectedConflictCurrent = editable.observable<any>("");
|
||||||
this.partitionKey = options.partitionKey || (this.collection && this.collection.partitionKey);
|
this.partitionKey = options.partitionKey || (this.collection && this.collection.partitionKey);
|
||||||
|
@ -106,14 +105,14 @@ export default class ConflictsTab extends TabsBase {
|
||||||
|
|
||||||
this.accessibleDocumentList = new AccessibleVerticalList(this.conflictIds());
|
this.accessibleDocumentList = new AccessibleVerticalList(this.conflictIds());
|
||||||
this.accessibleDocumentList.setOnSelect(
|
this.accessibleDocumentList.setOnSelect(
|
||||||
(selectedDocument: ViewModels.ConflictId) => selectedDocument && selectedDocument.click()
|
(selectedDocument: ConflictId) => selectedDocument && selectedDocument.click()
|
||||||
);
|
);
|
||||||
this.selectedConflictId.subscribe((newSelectedDocumentId: ViewModels.ConflictId) => {
|
this.selectedConflictId.subscribe((newSelectedDocumentId: ConflictId) => {
|
||||||
this.accessibleDocumentList.updateCurrentItem(newSelectedDocumentId);
|
this.accessibleDocumentList.updateCurrentItem(newSelectedDocumentId);
|
||||||
this.conflictOperation(newSelectedDocumentId && newSelectedDocumentId.operationType);
|
this.conflictOperation(newSelectedDocumentId && newSelectedDocumentId.operationType);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.conflictIds.subscribe((newDocuments: ViewModels.ConflictId[]) => {
|
this.conflictIds.subscribe((newDocuments: ConflictId[]) => {
|
||||||
this.accessibleDocumentList.updateItemList(newDocuments);
|
this.accessibleDocumentList.updateItemList(newDocuments);
|
||||||
this.dataContentsGridScrollHeight(
|
this.dataContentsGridScrollHeight(
|
||||||
newDocuments.length * DocumentsGridMetrics.IndividualRowHeight + DocumentsGridMetrics.BufferHeight + "px"
|
newDocuments.length * DocumentsGridMetrics.IndividualRowHeight + DocumentsGridMetrics.BufferHeight + "px"
|
||||||
|
@ -259,7 +258,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
public onConflictIdClick(clickedDocumentId: ViewModels.ConflictId): Q.Promise<any> {
|
public onConflictIdClick(clickedDocumentId: ConflictId): Q.Promise<any> {
|
||||||
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
|
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
@ -319,7 +318,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
.then(
|
.then(
|
||||||
() => {
|
() => {
|
||||||
return deleteConflict(this.collection, selectedConflict).then(() => {
|
return deleteConflict(this.collection, selectedConflict).then(() => {
|
||||||
this.conflictIds.remove((conflictId: ViewModels.ConflictId) => conflictId.rid === selectedConflict.rid);
|
this.conflictIds.remove((conflictId: ConflictId) => conflictId.rid === selectedConflict.rid);
|
||||||
this.selectedConflictContent("");
|
this.selectedConflictContent("");
|
||||||
this.selectedConflictCurrent("");
|
this.selectedConflictCurrent("");
|
||||||
this.selectedConflictId(null);
|
this.selectedConflictId(null);
|
||||||
|
@ -380,7 +379,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
return deleteConflict(this.collection, selectedConflict)
|
return deleteConflict(this.collection, selectedConflict)
|
||||||
.then(
|
.then(
|
||||||
() => {
|
() => {
|
||||||
this.conflictIds.remove((conflictId: ViewModels.ConflictId) => conflictId.rid === selectedConflict.rid);
|
this.conflictIds.remove((conflictId: ConflictId) => conflictId.rid === selectedConflict.rid);
|
||||||
this.selectedConflictContent("");
|
this.selectedConflictContent("");
|
||||||
this.selectedConflictCurrent("");
|
this.selectedConflictCurrent("");
|
||||||
this.selectedConflictId(null);
|
this.selectedConflictId(null);
|
||||||
|
@ -515,7 +514,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
})
|
})
|
||||||
// map raw response to view model
|
// map raw response to view model
|
||||||
.map((rawDocument: any) => {
|
.map((rawDocument: any) => {
|
||||||
return <ViewModels.ConflictId>new ConflictId(this, rawDocument);
|
return <ConflictId>new ConflictId(this, rawDocument);
|
||||||
});
|
});
|
||||||
|
|
||||||
const merged = currentConflicts.concat(nextConflictIds);
|
const merged = currentConflicts.concat(nextConflictIds);
|
||||||
|
@ -580,7 +579,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDocumentEditorForCreate(documentId: ViewModels.ConflictId, documentToInsert: any): Q.Promise<any> {
|
public initDocumentEditorForCreate(documentId: ConflictId, documentToInsert: any): Q.Promise<any> {
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
let parsedConflictContent: any = JSON.parse(documentToInsert);
|
let parsedConflictContent: any = JSON.parse(documentToInsert);
|
||||||
const renderedConflictContent: string = this.renderObjectForEditor(parsedConflictContent, null, 4);
|
const renderedConflictContent: string = this.renderObjectForEditor(parsedConflictContent, null, 4);
|
||||||
|
@ -592,7 +591,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDocumentEditorForReplace(
|
public initDocumentEditorForReplace(
|
||||||
documentId: ViewModels.ConflictId,
|
documentId: ConflictId,
|
||||||
conflictContent: any,
|
conflictContent: any,
|
||||||
currentContent: any
|
currentContent: any
|
||||||
): Q.Promise<any> {
|
): Q.Promise<any> {
|
||||||
|
@ -612,7 +611,7 @@ export default class ConflictsTab extends TabsBase {
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDocumentEditorForDelete(documentId: ViewModels.ConflictId, documentToDelete: any): Q.Promise<any> {
|
public initDocumentEditorForDelete(documentId: ConflictId, documentToDelete: any): Q.Promise<any> {
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
let parsedDocumentToDelete: any = JSON.parse(documentToDelete);
|
let parsedDocumentToDelete: any = JSON.parse(documentToDelete);
|
||||||
parsedDocumentToDelete = ConflictsTab.removeSystemProperties(parsedDocumentToDelete);
|
parsedDocumentToDelete = ConflictsTab.removeSystemProperties(parsedDocumentToDelete);
|
||||||
|
@ -624,15 +623,15 @@ export default class ConflictsTab extends TabsBase {
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDocumentEditorForNoOp(documentId: ViewModels.ConflictId): Q.Promise<any> {
|
public initDocumentEditorForNoOp(documentId: ConflictId): Q.Promise<any> {
|
||||||
this.selectedConflictContent(null);
|
this.selectedConflictContent(null);
|
||||||
this.selectedConflictCurrent(null);
|
this.selectedConflictCurrent(null);
|
||||||
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
const label = this._acceptButtonLabel();
|
const label = this._acceptButtonLabel();
|
||||||
if (this.acceptChangesButton.visible()) {
|
if (this.acceptChangesButton.visible()) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { PlatformType } from "../../PlatformType";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import { updateOfferThroughputBeyondLimit, updateOffer } from "../../Common/DocumentClientUtilityBase";
|
import { updateOfferThroughputBeyondLimit, updateOffer } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
const updateThroughputBeyondLimitWarningMessage: string = `
|
const updateThroughputBeyondLimitWarningMessage: string = `
|
||||||
You are about to request an increase in throughput beyond the pre-allocated capacity.
|
You are about to request an increase in throughput beyond the pre-allocated capacity.
|
||||||
|
@ -667,8 +668,8 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
const label = "Save";
|
const label = "Save";
|
||||||
if (this.saveSettingsButton.visible()) {
|
if (this.saveSettingsButton.visible()) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -3,13 +3,15 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import * as Constants from "../../Common/Constants";
|
import * as Constants from "../../Common/Constants";
|
||||||
import DocumentsTab from "./DocumentsTab";
|
import DocumentsTab from "./DocumentsTab";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import DocumentId from "../Tree/DocumentId";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
describe("Documents tab", () => {
|
describe("Documents tab", () => {
|
||||||
describe("buildQuery", () => {
|
describe("buildQuery", () => {
|
||||||
it("should generate the right select query for SQL API", () => {
|
it("should generate the right select query for SQL API", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -17,7 +19,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.buildQuery("")).toContain("select");
|
expect(documentsTab.buildQuery("")).toContain("select");
|
||||||
|
@ -89,7 +91,7 @@ describe("Documents tab", () => {
|
||||||
it("should be false for null or undefined collection", () => {
|
it("should be false for null or undefined collection", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -97,7 +99,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.showPartitionKey).toBe(false);
|
expect(documentsTab.showPartitionKey).toBe(false);
|
||||||
|
@ -107,7 +109,7 @@ describe("Documents tab", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
collection: collectionWithoutPartitionKey,
|
collection: collectionWithoutPartitionKey,
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -115,7 +117,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.showPartitionKey).toBe(false);
|
expect(documentsTab.showPartitionKey).toBe(false);
|
||||||
|
@ -125,7 +127,7 @@ describe("Documents tab", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
collection: collectionWithSystemPartitionKey,
|
collection: collectionWithSystemPartitionKey,
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -133,7 +135,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.showPartitionKey).toBe(true);
|
expect(documentsTab.showPartitionKey).toBe(true);
|
||||||
|
@ -143,7 +145,7 @@ describe("Documents tab", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
collection: mongoCollectionWithSystemPartitionKey,
|
collection: mongoCollectionWithSystemPartitionKey,
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -151,7 +153,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.showPartitionKey).toBe(false);
|
expect(documentsTab.showPartitionKey).toBe(false);
|
||||||
|
@ -161,7 +163,7 @@ describe("Documents tab", () => {
|
||||||
const documentsTab = new DocumentsTab({
|
const documentsTab = new DocumentsTab({
|
||||||
collection: collectionWithNonSystemPartitionKey,
|
collection: collectionWithNonSystemPartitionKey,
|
||||||
partitionKey: null,
|
partitionKey: null,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
title: "",
|
title: "",
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
|
@ -169,7 +171,7 @@ describe("Documents tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
|
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(documentsTab.showPartitionKey).toBe(true);
|
expect(documentsTab.showPartitionKey).toBe(true);
|
||||||
|
|
|
@ -15,13 +15,11 @@ import { DocumentsGridMetrics } from "../../Common/Constants";
|
||||||
import { QueryUtils } from "../../Utils/QueryUtils";
|
import { QueryUtils } from "../../Utils/QueryUtils";
|
||||||
import { Splitter, SplitterBounds, SplitterDirection } from "../../Common/Splitter";
|
import { Splitter, SplitterBounds, SplitterDirection } from "../../Common/Splitter";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Toolbar from "../Controls/Toolbar/Toolbar";
|
|
||||||
import NewDocumentIcon from "../../../images/NewDocument.svg";
|
import NewDocumentIcon from "../../../images/NewDocument.svg";
|
||||||
import SaveIcon from "../../../images/save-cosmos.svg";
|
import SaveIcon from "../../../images/save-cosmos.svg";
|
||||||
import DiscardIcon from "../../../images/discard.svg";
|
import DiscardIcon from "../../../images/discard.svg";
|
||||||
import DeleteDocumentIcon from "../../../images/DeleteDocument.svg";
|
import DeleteDocumentIcon from "../../../images/DeleteDocument.svg";
|
||||||
import UploadIcon from "../../../images/Upload_16x16.svg";
|
import UploadIcon from "../../../images/Upload_16x16.svg";
|
||||||
import SynapseIcon from "../../../images/synapse-link.svg";
|
|
||||||
import { extractPartitionKey, PartitionKeyDefinition, QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
|
import { extractPartitionKey, PartitionKeyDefinition, QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
|
||||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||||
|
@ -33,9 +31,10 @@ import {
|
||||||
updateDocument,
|
updateDocument,
|
||||||
createDocument
|
createDocument
|
||||||
} from "../../Common/DocumentClientUtilityBase";
|
} from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export default class DocumentsTab extends TabsBase implements ViewModels.DocumentsTab {
|
export default class DocumentsTab extends TabsBase {
|
||||||
public selectedDocumentId: ko.Observable<ViewModels.DocumentId>;
|
public selectedDocumentId: ko.Observable<DocumentId>;
|
||||||
public selectedDocumentContent: ViewModels.Editable<string>;
|
public selectedDocumentContent: ViewModels.Editable<string>;
|
||||||
public initialDocumentContent: ko.Observable<string>;
|
public initialDocumentContent: ko.Observable<string>;
|
||||||
public documentContentsGridId: string;
|
public documentContentsGridId: string;
|
||||||
|
@ -48,7 +47,6 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
public applyFilterButton: ViewModels.Button;
|
public applyFilterButton: ViewModels.Button;
|
||||||
public isEditorDirty: ko.Computed<boolean>;
|
public isEditorDirty: ko.Computed<boolean>;
|
||||||
public editorState: ko.Observable<ViewModels.DocumentExplorerState>;
|
public editorState: ko.Observable<ViewModels.DocumentExplorerState>;
|
||||||
public toolbarViewModel = ko.observable<Toolbar>();
|
|
||||||
public newDocumentButton: ViewModels.Button;
|
public newDocumentButton: ViewModels.Button;
|
||||||
public saveNewDocumentButton: ViewModels.Button;
|
public saveNewDocumentButton: ViewModels.Button;
|
||||||
public saveExisitingDocumentButton: ViewModels.Button;
|
public saveExisitingDocumentButton: ViewModels.Button;
|
||||||
|
@ -68,7 +66,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
public partitionKey: DataModels.PartitionKey;
|
public partitionKey: DataModels.PartitionKey;
|
||||||
public partitionKeyPropertyHeader: string;
|
public partitionKeyPropertyHeader: string;
|
||||||
public partitionKeyProperty: string;
|
public partitionKeyProperty: string;
|
||||||
public documentIds: ko.ObservableArray<ViewModels.DocumentId>;
|
public documentIds: ko.ObservableArray<DocumentId>;
|
||||||
|
|
||||||
private _documentsIterator: QueryIterator<ItemDefinition & Resource>;
|
private _documentsIterator: QueryIterator<ItemDefinition & Resource>;
|
||||||
private _resourceTokenPartitionKey: string;
|
private _resourceTokenPartitionKey: string;
|
||||||
|
@ -87,7 +85,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
this.editorState = ko.observable<ViewModels.DocumentExplorerState>(
|
this.editorState = ko.observable<ViewModels.DocumentExplorerState>(
|
||||||
ViewModels.DocumentExplorerState.noDocumentSelected
|
ViewModels.DocumentExplorerState.noDocumentSelected
|
||||||
);
|
);
|
||||||
this.selectedDocumentId = ko.observable<ViewModels.DocumentId>();
|
this.selectedDocumentId = ko.observable<DocumentId>();
|
||||||
this.selectedDocumentContent = editable.observable<string>("");
|
this.selectedDocumentContent = editable.observable<string>("");
|
||||||
this.initialDocumentContent = ko.observable<string>("");
|
this.initialDocumentContent = ko.observable<string>("");
|
||||||
this.partitionKey = options.partitionKey || (this.collection && this.collection.partitionKey);
|
this.partitionKey = options.partitionKey || (this.collection && this.collection.partitionKey);
|
||||||
|
@ -415,7 +413,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
public onDocumentIdClick(clickedDocumentId: ViewModels.DocumentId): Q.Promise<any> {
|
public onDocumentIdClick(clickedDocumentId: DocumentId): Q.Promise<any> {
|
||||||
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
|
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
@ -528,7 +526,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
const value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
const value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
||||||
this.selectedDocumentContent.setBaseline(value);
|
this.selectedDocumentContent.setBaseline(value);
|
||||||
this.initialDocumentContent(value);
|
this.initialDocumentContent(value);
|
||||||
this.documentIds().forEach((documentId: ViewModels.DocumentId) => {
|
this.documentIds().forEach((documentId: DocumentId) => {
|
||||||
if (documentId.rid === updatedDocument._rid) {
|
if (documentId.rid === updatedDocument._rid) {
|
||||||
documentId.id(updatedDocument.id);
|
documentId.id(updatedDocument.id);
|
||||||
}
|
}
|
||||||
|
@ -669,11 +667,11 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
return window.confirm(msg);
|
return window.confirm(msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected __deleteDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
|
protected __deleteDocument(documentId: DocumentId): Q.Promise<any> {
|
||||||
return deleteDocument(this.collection, documentId);
|
return deleteDocument(this.collection, documentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _deleteDocument(selectedDocumentId: ViewModels.DocumentId): Q.Promise<any> {
|
private _deleteDocument(selectedDocumentId: DocumentId): Q.Promise<any> {
|
||||||
this.isExecutionError(false);
|
this.isExecutionError(false);
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocument, {
|
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocument, {
|
||||||
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
|
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
|
||||||
|
@ -685,7 +683,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
return this.__deleteDocument(selectedDocumentId)
|
return this.__deleteDocument(selectedDocumentId)
|
||||||
.then(
|
.then(
|
||||||
(result: any) => {
|
(result: any) => {
|
||||||
this.documentIds.remove((documentId: ViewModels.DocumentId) => documentId.rid === selectedDocumentId.rid);
|
this.documentIds.remove((documentId: DocumentId) => documentId.rid === selectedDocumentId.rid);
|
||||||
this.selectedDocumentContent("");
|
this.selectedDocumentContent("");
|
||||||
this.selectedDocumentId(null);
|
this.selectedDocumentId(null);
|
||||||
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||||
|
@ -732,7 +730,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
return queryDocuments(this.collection.databaseId, this.collection.id(), query, options);
|
return queryDocuments(this.collection.databaseId, this.collection.id(), query, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
|
public selectDocument(documentId: DocumentId): Q.Promise<any> {
|
||||||
this.selectedDocumentId(documentId);
|
this.selectedDocumentId(documentId);
|
||||||
return readDocument(this.collection, documentId).then((content: any) => {
|
return readDocument(this.collection, documentId).then((content: any) => {
|
||||||
this.initDocumentEditor(documentId, content);
|
this.initDocumentEditor(documentId, content);
|
||||||
|
@ -755,7 +753,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
// map raw response to view model
|
// map raw response to view model
|
||||||
.map((rawDocument: any) => {
|
.map((rawDocument: any) => {
|
||||||
const partitionKeyValue = rawDocument._partitionKeyValue;
|
const partitionKeyValue = rawDocument._partitionKeyValue;
|
||||||
return <ViewModels.DocumentId>new DocumentId(this, rawDocument, partitionKeyValue);
|
return new DocumentId(this, rawDocument, partitionKeyValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
const merged = currentDocuments.concat(nextDocumentIds);
|
const merged = currentDocuments.concat(nextDocumentIds);
|
||||||
|
@ -826,7 +824,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDocumentEditor(documentId: ViewModels.DocumentId, documentContent: any): Q.Promise<any> {
|
public initDocumentEditor(documentId: DocumentId, documentContent: any): Q.Promise<any> {
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
const content: string = this.renderObjectForEditor(documentContent, null, 4);
|
const content: string = this.renderObjectForEditor(documentContent, null, 4);
|
||||||
this.selectedDocumentContent.setBaseline(content);
|
this.selectedDocumentContent.setBaseline(content);
|
||||||
|
@ -844,8 +842,8 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
return QueryUtils.buildDocumentsQuery(filter, this.partitionKeyProperty, this.partitionKey);
|
return QueryUtils.buildDocumentsQuery(filter, this.partitionKeyProperty, this.partitionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
const label = !this.isPreferredApiMongoDB ? "New Item" : "New Document";
|
const label = !this.isPreferredApiMongoDB ? "New Item" : "New Document";
|
||||||
if (this.newDocumentButton.visible()) {
|
if (this.newDocumentButton.visible()) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
@ -963,7 +961,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static _createUploadButton(container: Explorer): ViewModels.NavbarButtonConfig {
|
public static _createUploadButton(container: Explorer): CommandButtonComponentProps {
|
||||||
const label = "Upload Item";
|
const label = "Upload Item";
|
||||||
return {
|
return {
|
||||||
iconSrc: UploadIcon,
|
iconSrc: UploadIcon,
|
||||||
|
|
|
@ -4,15 +4,26 @@ import { GalleryAndNotebookViewerComponentAdapter } from "../Controls/NotebookGa
|
||||||
import { GalleryTab as GalleryViewerTab, SortBy } from "../Controls/NotebookGallery/GalleryViewerComponent";
|
import { GalleryTab as GalleryViewerTab, SortBy } from "../Controls/NotebookGallery/GalleryViewerComponent";
|
||||||
import TabsBase from "./TabsBase";
|
import TabsBase from "./TabsBase";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
|
import { JunoClient, IGalleryItem } from "../../Juno/JunoClient";
|
||||||
|
|
||||||
|
interface GalleryTabOptions extends ViewModels.TabOptions {
|
||||||
|
account: DatabaseAccount;
|
||||||
|
container: Explorer;
|
||||||
|
junoClient: JunoClient;
|
||||||
|
notebookUrl?: string;
|
||||||
|
galleryItem?: IGalleryItem;
|
||||||
|
isFavorite?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notebook gallery tab
|
* Notebook gallery tab
|
||||||
*/
|
*/
|
||||||
export default class GalleryTab extends TabsBase implements ViewModels.Tab {
|
export default class GalleryTab extends TabsBase {
|
||||||
private container: Explorer;
|
private container: Explorer;
|
||||||
public galleryAndNotebookViewerComponentAdapter: GalleryAndNotebookViewerComponentAdapter;
|
public galleryAndNotebookViewerComponentAdapter: GalleryAndNotebookViewerComponentAdapter;
|
||||||
|
|
||||||
constructor(options: ViewModels.GalleryTabOptions) {
|
constructor(options: GalleryTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
|
|
|
@ -2,13 +2,14 @@ import * as ko from "knockout";
|
||||||
import * as Q from "q";
|
import * as Q from "q";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import TabsBase from "./TabsBase";
|
import TabsBase from "./TabsBase";
|
||||||
import Toolbar from "../Controls/Toolbar/Toolbar";
|
|
||||||
import { GraphExplorerAdapter } from "../Graph/GraphExplorerComponent/GraphExplorerAdapter";
|
import { GraphExplorerAdapter } from "../Graph/GraphExplorerComponent/GraphExplorerAdapter";
|
||||||
import { GraphAccessor, GraphExplorerError } from "../Graph/GraphExplorerComponent/GraphExplorer";
|
import { GraphAccessor, GraphExplorerError } from "../Graph/GraphExplorerComponent/GraphExplorer";
|
||||||
import NewVertexIcon from "../../../images/NewVertex.svg";
|
import NewVertexIcon from "../../../images/NewVertex.svg";
|
||||||
import StyleIcon from "../../../images/Style.svg";
|
import StyleIcon from "../../../images/Style.svg";
|
||||||
import GraphStylingPane from "../Panes/GraphStylingPane";
|
import GraphStylingPane from "../Panes/GraphStylingPane";
|
||||||
import NewVertexPane from "../Panes/NewVertexPane";
|
import NewVertexPane from "../Panes/NewVertexPane";
|
||||||
|
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export interface GraphIconMap {
|
export interface GraphIconMap {
|
||||||
[key: string]: { data: string; format: string };
|
[key: string]: { data: string; format: string };
|
||||||
|
@ -26,7 +27,15 @@ export interface GraphConfig {
|
||||||
iconsMap: ko.Observable<GraphIconMap>;
|
iconsMap: ko.Observable<GraphIconMap>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GraphTab extends TabsBase implements ViewModels.Tab {
|
interface GraphTabOptions extends ViewModels.TabOptions {
|
||||||
|
account: DatabaseAccount;
|
||||||
|
masterKey: string;
|
||||||
|
collectionId: string;
|
||||||
|
databaseId: string;
|
||||||
|
collectionPartitionKeyProperty: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class GraphTab extends TabsBase {
|
||||||
// Graph default configuration
|
// Graph default configuration
|
||||||
public static readonly DEFAULT_NODE_CAPTION = "id";
|
public static readonly DEFAULT_NODE_CAPTION = "id";
|
||||||
private static readonly LINK_COLOR = "#aaa";
|
private static readonly LINK_COLOR = "#aaa";
|
||||||
|
@ -38,7 +47,6 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
|
||||||
private isPropertyEditing: ko.Observable<boolean>;
|
private isPropertyEditing: ko.Observable<boolean>;
|
||||||
private isGraphDisplayed: ko.Observable<boolean>;
|
private isGraphDisplayed: ko.Observable<boolean>;
|
||||||
private graphAccessor: GraphAccessor;
|
private graphAccessor: GraphAccessor;
|
||||||
public toolbarViewModel: ko.Observable<Toolbar>;
|
|
||||||
private graphConfig: GraphConfig;
|
private graphConfig: GraphConfig;
|
||||||
private graphConfigUiData: ViewModels.GraphConfigUiData;
|
private graphConfigUiData: ViewModels.GraphConfigUiData;
|
||||||
private isFilterQueryLoading: ko.Observable<boolean>;
|
private isFilterQueryLoading: ko.Observable<boolean>;
|
||||||
|
@ -47,7 +55,7 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
|
||||||
private graphStylingPane: GraphStylingPane;
|
private graphStylingPane: GraphStylingPane;
|
||||||
private collectionPartitionKeyProperty: string;
|
private collectionPartitionKeyProperty: string;
|
||||||
|
|
||||||
constructor(options: ViewModels.GraphTabOptions) {
|
constructor(options: GraphTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.newVertexPane = options.collection && options.collection.container.newVertexPane;
|
this.newVertexPane = options.collection && options.collection.container.newVertexPane;
|
||||||
|
@ -100,10 +108,9 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
|
||||||
|
|
||||||
this.isFilterQueryLoading = ko.observable(false);
|
this.isFilterQueryLoading = ko.observable(false);
|
||||||
this.isValidQuery = ko.observable(true);
|
this.isValidQuery = ko.observable(true);
|
||||||
this.toolbarViewModel = ko.observable<Toolbar>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getGremlinEndpoint(account: ViewModels.DatabaseAccount): string {
|
public static getGremlinEndpoint(account: DatabaseAccount): string {
|
||||||
return account.properties.gremlinEndpoint
|
return account.properties.gremlinEndpoint
|
||||||
? GraphTab.sanitizeHost(account.properties.gremlinEndpoint)
|
? GraphTab.sanitizeHost(account.properties.gremlinEndpoint)
|
||||||
: `${account.name}.graphs.azure.com:443/`;
|
: `${account.name}.graphs.azure.com:443/`;
|
||||||
|
@ -202,9 +209,9 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
|
||||||
this.graphConfigUiData.nodeIconChoice(this.graphConfigUiData.nodePropertiesWithNone()[0]);
|
this.graphConfigUiData.nodeIconChoice(this.graphConfigUiData.nodePropertiesWithNone()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const label = "New Vertex";
|
const label = "New Vertex";
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [
|
const buttons: CommandButtonComponentProps[] = [
|
||||||
{
|
{
|
||||||
iconSrc: NewVertexIcon,
|
iconSrc: NewVertexIcon,
|
||||||
iconAlt: label,
|
iconAlt: label,
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { extractPartitionKey } from "@azure/cosmos";
|
||||||
import * as Logger from "../../Common/Logger";
|
import * as Logger from "../../Common/Logger";
|
||||||
import { PartitionKeyDefinition } from "@azure/cosmos";
|
import { PartitionKeyDefinition } from "@azure/cosmos";
|
||||||
|
|
||||||
export default class MongoDocumentsTab extends DocumentsTab implements ViewModels.DocumentsTab {
|
export default class MongoDocumentsTab extends DocumentsTab {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
private continuationToken: string;
|
private continuationToken: string;
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ export default class MongoDocumentsTab extends DocumentsTab implements ViewModel
|
||||||
let value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
let value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
||||||
this.selectedDocumentContent.setBaseline(value);
|
this.selectedDocumentContent.setBaseline(value);
|
||||||
|
|
||||||
this.documentIds().forEach((documentId: ViewModels.DocumentId) => {
|
this.documentIds().forEach((documentId: DocumentId) => {
|
||||||
if (documentId.rid === updatedDocument._rid) {
|
if (documentId.rid === updatedDocument._rid) {
|
||||||
const partitionKeyArray = extractPartitionKey(
|
const partitionKeyArray = extractPartitionKey(
|
||||||
updatedDocument,
|
updatedDocument,
|
||||||
|
@ -199,7 +199,7 @@ export default class MongoDocumentsTab extends DocumentsTab implements ViewModel
|
||||||
return filter || "{}";
|
return filter || "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
|
public selectDocument(documentId: DocumentId): Q.Promise<any> {
|
||||||
this.selectedDocumentId(documentId);
|
this.selectedDocumentId(documentId);
|
||||||
return Q(
|
return Q(
|
||||||
readDocument(this.collection.databaseId, this.collection, documentId).then((content: any) => {
|
readDocument(this.collection.databaseId, this.collection, documentId).then((content: any) => {
|
||||||
|
@ -226,7 +226,7 @@ export default class MongoDocumentsTab extends DocumentsTab implements ViewModel
|
||||||
})
|
})
|
||||||
.map((rawDocument: any) => {
|
.map((rawDocument: any) => {
|
||||||
const partitionKeyValue = rawDocument._partitionKeyValue;
|
const partitionKeyValue = rawDocument._partitionKeyValue;
|
||||||
return <ViewModels.DocumentId>new DocumentId(this, rawDocument, partitionKeyValue);
|
return new DocumentId(this, rawDocument, partitionKeyValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
const merged = currentDocuments.concat(nextDocumentIds);
|
const merged = currentDocuments.concat(nextDocumentIds);
|
||||||
|
@ -324,7 +324,7 @@ export default class MongoDocumentsTab extends DocumentsTab implements ViewModel
|
||||||
return partitionKey;
|
return partitionKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __deleteDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
|
protected __deleteDocument(documentId: DocumentId): Q.Promise<any> {
|
||||||
return Q(deleteDocument(this.collection.databaseId, this.collection, documentId));
|
return Q(deleteDocument(this.collection.databaseId, this.collection, documentId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as HeadersUtility from "../../Common/HeadersUtility";
|
||||||
import { queryIterator } from "../../Common/MongoProxyClient";
|
import { queryIterator } from "../../Common/MongoProxyClient";
|
||||||
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
||||||
|
|
||||||
export default class MongoQueryTab extends QueryTab implements ViewModels.QueryTab {
|
export default class MongoQueryTab extends QueryTab {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
|
|
||||||
constructor(options: ViewModels.QueryTabOptions) {
|
constructor(options: ViewModels.QueryTabOptions) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
|
||||||
import { PlatformType } from "../../PlatformType";
|
import { PlatformType } from "../../PlatformType";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
|
||||||
export default class MongoShellTab extends TabsBase implements ViewModels.MongoShellTab {
|
export default class MongoShellTab extends TabsBase {
|
||||||
public url: ko.Computed<string>;
|
public url: ko.Computed<string>;
|
||||||
private _container: Explorer;
|
private _container: Explorer;
|
||||||
private _runtimeEndpoint: string;
|
private _runtimeEndpoint: string;
|
||||||
|
@ -26,7 +26,7 @@ export default class MongoShellTab extends TabsBase implements ViewModels.MongoS
|
||||||
this._logTraces = new HashMap<number>();
|
this._logTraces = new HashMap<number>();
|
||||||
this._container = options.collection.container;
|
this._container = options.collection.container;
|
||||||
this.url = ko.computed<string>(() => {
|
this.url = ko.computed<string>(() => {
|
||||||
const account: ViewModels.DatabaseAccount = CosmosClient.databaseAccount();
|
const account = CosmosClient.databaseAccount();
|
||||||
const resourceId: string = account && account.id;
|
const resourceId: string = account && account.id;
|
||||||
const accountName = account && account.name;
|
const accountName = account && account.name;
|
||||||
const mongoEndpoint = account && (account.properties.mongoEndpoint || account.properties.documentEndpoint);
|
const mongoEndpoint = account && (account.properties.mongoEndpoint || account.properties.documentEndpoint);
|
||||||
|
|
|
@ -28,15 +28,24 @@ import { NotebookConfigurationUtils } from "../../Utils/NotebookConfigurationUti
|
||||||
import { KernelSpecsDisplay, NotebookClientV2 } from "../Notebook/NotebookClientV2";
|
import { KernelSpecsDisplay, NotebookClientV2 } from "../Notebook/NotebookClientV2";
|
||||||
import { config } from "../../Config";
|
import { config } from "../../Config";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { NotebookContentItem } from "../Notebook/NotebookContentItem";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export default class NotebookTabV2 extends TabsBase implements ViewModels.Tab {
|
export interface NotebookTabOptions extends ViewModels.TabOptions {
|
||||||
|
account: DataModels.DatabaseAccount;
|
||||||
|
masterKey: string;
|
||||||
|
container: Explorer;
|
||||||
|
notebookContentItem: NotebookContentItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class NotebookTabV2 extends TabsBase {
|
||||||
private static clientManager: NotebookClientV2;
|
private static clientManager: NotebookClientV2;
|
||||||
private container: Explorer;
|
private container: Explorer;
|
||||||
public notebookPath: ko.Observable<string>;
|
public notebookPath: ko.Observable<string>;
|
||||||
private selectedSparkPool: ko.Observable<string>;
|
private selectedSparkPool: ko.Observable<string>;
|
||||||
private notebookComponentAdapter: NotebookComponentAdapter;
|
private notebookComponentAdapter: NotebookComponentAdapter;
|
||||||
|
|
||||||
constructor(options: ViewModels.NotebookTabOptions) {
|
constructor(options: NotebookTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
|
@ -109,7 +118,7 @@ export default class NotebookTabV2 extends TabsBase implements ViewModels.Tab {
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const availableKernels = NotebookTabV2.clientManager.getAvailableKernelSpecs();
|
const availableKernels = NotebookTabV2.clientManager.getAvailableKernelSpecs();
|
||||||
|
|
||||||
const saveLabel = "Save";
|
const saveLabel = "Save";
|
||||||
|
@ -136,7 +145,7 @@ export default class NotebookTabV2 extends TabsBase implements ViewModels.Tab {
|
||||||
const cellCodeType = "code";
|
const cellCodeType = "code";
|
||||||
const cellMarkdownType = "markdown";
|
const cellMarkdownType = "markdown";
|
||||||
const cellRawType = "raw";
|
const cellRawType = "raw";
|
||||||
let buttons: ViewModels.NavbarButtonConfig[] = [
|
let buttons: CommandButtonComponentProps[] = [
|
||||||
{
|
{
|
||||||
iconSrc: SaveIcon,
|
iconSrc: SaveIcon,
|
||||||
iconAlt: saveLabel,
|
iconAlt: saveLabel,
|
||||||
|
@ -188,7 +197,7 @@ export default class NotebookTabV2 extends TabsBase implements ViewModels.Tab {
|
||||||
hasPopup: false,
|
hasPopup: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
ariaLabel: kernel.displayName
|
ariaLabel: kernel.displayName
|
||||||
} as ViewModels.NavbarButtonConfig)
|
} as CommandButtonComponentProps)
|
||||||
),
|
),
|
||||||
ariaLabel: kernelLabel
|
ariaLabel: kernelLabel
|
||||||
},
|
},
|
||||||
|
@ -363,7 +372,7 @@ export default class NotebookTabV2 extends TabsBase implements ViewModels.Tab {
|
||||||
];
|
];
|
||||||
|
|
||||||
if (this.container.hasStorageAnalyticsAfecFeature()) {
|
if (this.container.hasStorageAnalyticsAfecFeature()) {
|
||||||
const arcadiaWorkspaceDropdown: ViewModels.NavbarButtonConfig = {
|
const arcadiaWorkspaceDropdown: CommandButtonComponentProps = {
|
||||||
iconSrc: null,
|
iconSrc: null,
|
||||||
iconAlt: workspaceLabel,
|
iconAlt: workspaceLabel,
|
||||||
ariaLabel: workspaceLabel,
|
ariaLabel: workspaceLabel,
|
||||||
|
|
|
@ -8,6 +8,14 @@ import {
|
||||||
} from "../Controls/NotebookViewer/NotebookViewerComponent";
|
} from "../Controls/NotebookViewer/NotebookViewerComponent";
|
||||||
import TabsBase from "./TabsBase";
|
import TabsBase from "./TabsBase";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { DatabaseAccount } from "../../Contracts/DataModels";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
|
interface NotebookViewerTabOptions extends ViewModels.TabOptions {
|
||||||
|
account: DatabaseAccount;
|
||||||
|
container: Explorer;
|
||||||
|
notebookUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notebook Viewer tab
|
* Notebook Viewer tab
|
||||||
|
@ -29,13 +37,13 @@ class NotebookViewerComponentAdapter implements ReactAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class NotebookViewerTab extends TabsBase implements ViewModels.Tab {
|
export default class NotebookViewerTab extends TabsBase {
|
||||||
private container: Explorer;
|
private container: Explorer;
|
||||||
public notebookUrl: string;
|
public notebookUrl: string;
|
||||||
|
|
||||||
public notebookViewerComponentAdapter: NotebookViewerComponentAdapter;
|
public notebookViewerComponentAdapter: NotebookViewerComponentAdapter;
|
||||||
|
|
||||||
constructor(options: ViewModels.NotebookViewerTabOptions) {
|
constructor(options: NotebookViewerTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
this.notebookUrl = options.notebookUrl;
|
this.notebookUrl = options.notebookUrl;
|
||||||
|
@ -54,7 +62,7 @@ export default class NotebookViewerTab extends TabsBase implements ViewModels.Ta
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,10 @@ import * as Constants from "../../Common/Constants";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import QueryTab from "./QueryTab";
|
import QueryTab from "./QueryTab";
|
||||||
import { View } from "@nteract/data-explorer/lib/utilities/types";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { PartitionKey } from "../../Contracts/DataModels";
|
|
||||||
|
|
||||||
describe("Query Tab", () => {
|
describe("Query Tab", () => {
|
||||||
function getNewQueryTabForContainer(container: Explorer): ViewModels.QueryTab {
|
function getNewQueryTabForContainer(container: Explorer): QueryTab {
|
||||||
const database = {
|
const database = {
|
||||||
container: container,
|
container: container,
|
||||||
id: ko.observable<string>("test"),
|
id: ko.observable<string>("test"),
|
||||||
|
@ -28,7 +27,7 @@ describe("Query Tab", () => {
|
||||||
selfLink: "",
|
selfLink: "",
|
||||||
isActive: ko.observable<boolean>(false),
|
isActive: ko.observable<boolean>(false),
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,13 +54,13 @@ describe("Query Tab", () => {
|
||||||
|
|
||||||
it("should be true for accounts using SQL API", () => {
|
it("should be true for accounts using SQL API", () => {
|
||||||
explorer.defaultExperience(Constants.DefaultAccountExperience.DocumentDB.toLowerCase());
|
explorer.defaultExperience(Constants.DefaultAccountExperience.DocumentDB.toLowerCase());
|
||||||
const queryTab: ViewModels.QueryTab = getNewQueryTabForContainer(explorer);
|
const queryTab = getNewQueryTabForContainer(explorer);
|
||||||
expect(queryTab.isQueryMetricsEnabled()).toBe(true);
|
expect(queryTab.isQueryMetricsEnabled()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be false for accounts using other APIs", () => {
|
it("should be false for accounts using other APIs", () => {
|
||||||
explorer.defaultExperience(Constants.DefaultAccountExperience.Graph.toLowerCase());
|
explorer.defaultExperience(Constants.DefaultAccountExperience.Graph.toLowerCase());
|
||||||
const queryTab: ViewModels.QueryTab = getNewQueryTabForContainer(explorer);
|
const queryTab = getNewQueryTabForContainer(explorer);
|
||||||
expect(queryTab.isQueryMetricsEnabled()).toBe(false);
|
expect(queryTab.isQueryMetricsEnabled()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -75,13 +74,13 @@ describe("Query Tab", () => {
|
||||||
|
|
||||||
it("should be visible when using a supported API", () => {
|
it("should be visible when using a supported API", () => {
|
||||||
explorer.defaultExperience(Constants.DefaultAccountExperience.DocumentDB);
|
explorer.defaultExperience(Constants.DefaultAccountExperience.DocumentDB);
|
||||||
const queryTab: ViewModels.QueryTab = getNewQueryTabForContainer(explorer);
|
const queryTab = getNewQueryTabForContainer(explorer);
|
||||||
expect(queryTab.saveQueryButton.visible()).toBe(true);
|
expect(queryTab.saveQueryButton.visible()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not be visible when using an unsupported API", () => {
|
it("should not be visible when using an unsupported API", () => {
|
||||||
explorer.defaultExperience(Constants.DefaultAccountExperience.MongoDB);
|
explorer.defaultExperience(Constants.DefaultAccountExperience.MongoDB);
|
||||||
const queryTab: ViewModels.QueryTab = getNewQueryTabForContainer(explorer);
|
const queryTab = getNewQueryTabForContainer(explorer);
|
||||||
expect(queryTab.saveQueryButton.visible()).toBe(false);
|
expect(queryTab.saveQueryButton.visible()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,13 +17,14 @@ import SaveQueryIcon from "../../../images/save-cosmos.svg";
|
||||||
|
|
||||||
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
||||||
import { queryDocuments, queryDocumentsPage } from "../../Common/DocumentClientUtilityBase";
|
import { queryDocuments, queryDocumentsPage } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
enum ToggleState {
|
enum ToggleState {
|
||||||
Result,
|
Result,
|
||||||
QueryMetrics
|
QueryMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class QueryTab extends TabsBase implements ViewModels.QueryTab, ViewModels.WaitsForTemplate {
|
export default class QueryTab extends TabsBase implements ViewModels.WaitsForTemplate {
|
||||||
public queryEditorId: string;
|
public queryEditorId: string;
|
||||||
public executeQueryButton: ViewModels.Button;
|
public executeQueryButton: ViewModels.Button;
|
||||||
public fetchNextPageButton: ViewModels.Button;
|
public fetchNextPageButton: ViewModels.Button;
|
||||||
|
@ -586,8 +587,8 @@ export default class QueryTab extends TabsBase implements ViewModels.QueryTab, V
|
||||||
return csvData;
|
return csvData;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
if (this.executeQueryButton.visible()) {
|
if (this.executeQueryButton.visible()) {
|
||||||
const label = this._executeQueryButtonTitle();
|
const label = this._executeQueryButtonTitle();
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -14,6 +14,7 @@ import AddEntityIcon from "../../../images/AddEntity.svg";
|
||||||
import EditEntityIcon from "../../../images/Edit-entity.svg";
|
import EditEntityIcon from "../../../images/Edit-entity.svg";
|
||||||
import DeleteEntitiesIcon from "../../../images/DeleteEntities.svg";
|
import DeleteEntitiesIcon from "../../../images/DeleteEntities.svg";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
// Will act as table explorer class
|
// Will act as table explorer class
|
||||||
export default class QueryTablesTab extends TabsBase {
|
export default class QueryTablesTab extends TabsBase {
|
||||||
|
@ -173,8 +174,8 @@ export default class QueryTablesTab extends TabsBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
if (this.queryBuilderButton.visible()) {
|
if (this.queryBuilderButton.visible()) {
|
||||||
const label = this.container.isPreferredApiCassandra() ? "CQL Query Builder" : "Query Builder";
|
const label = this.container.isPreferredApiCassandra() ? "CQL Query Builder" : "Query Builder";
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -9,9 +9,9 @@ import editable from "../../Common/EditableUtility";
|
||||||
import * as monaco from "monaco-editor";
|
import * as monaco from "monaco-editor";
|
||||||
import SaveIcon from "../../../images/save-cosmos.svg";
|
import SaveIcon from "../../../images/save-cosmos.svg";
|
||||||
import DiscardIcon from "../../../images/discard.svg";
|
import DiscardIcon from "../../../images/discard.svg";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
export default abstract class ScriptTabBase extends TabsBase
|
export default abstract class ScriptTabBase extends TabsBase implements ViewModels.WaitsForTemplate {
|
||||||
implements ViewModels.ScriptTab, ViewModels.WaitsForTemplate {
|
|
||||||
public ariaLabel: ko.Observable<string>;
|
public ariaLabel: ko.Observable<string>;
|
||||||
public editorState: ko.Observable<ViewModels.ScriptEditorState>;
|
public editorState: ko.Observable<ViewModels.ScriptEditorState>;
|
||||||
public id: ViewModels.Editable<string>;
|
public id: ViewModels.Editable<string>;
|
||||||
|
@ -216,8 +216,8 @@ export default abstract class ScriptTabBase extends TabsBase
|
||||||
return Q();
|
return Q();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
const label = "Save";
|
const label = "Save";
|
||||||
if (this.saveButton.visible()) {
|
if (this.saveButton.visible()) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Collection from "../Tree/Collection";
|
||||||
import Database from "../Tree/Database";
|
import Database from "../Tree/Database";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import SettingsTab from "../Tabs/SettingsTab";
|
import SettingsTab from "../Tabs/SettingsTab";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
describe("Settings tab", () => {
|
describe("Settings tab", () => {
|
||||||
const baseCollection: DataModels.Collection = {
|
const baseCollection: DataModels.Collection = {
|
||||||
|
@ -189,7 +190,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
||||||
|
@ -212,7 +213,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
||||||
|
@ -230,7 +231,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
expect(settingsTab.shouldUpdateCollection()).toBe(false);
|
||||||
|
@ -268,7 +269,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
||||||
|
@ -284,7 +285,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
||||||
|
@ -309,7 +310,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
|
||||||
|
@ -388,7 +389,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: getCollection(defaultApi, partitionKeyOption),
|
collection: getCollection(defaultApi, partitionKeyOption),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +533,7 @@ describe("Settings tab", () => {
|
||||||
hashLocation: "",
|
hashLocation: "",
|
||||||
isActive: ko.observable(false),
|
isActive: ko.observable(false),
|
||||||
collection: getCollection(autoPilotTier),
|
collection: getCollection(autoPilotTier),
|
||||||
onUpdateTabsButtons: (buttons: ViewModels.NavbarButtonConfig[]): void => {}
|
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
describe("Visible", () => {
|
describe("Visible", () => {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
updateOffer,
|
updateOffer,
|
||||||
updateCollection
|
updateCollection
|
||||||
} from "../../Common/DocumentClientUtilityBase";
|
} from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
const ttlWarning: string = `
|
const ttlWarning: string = `
|
||||||
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
|
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
|
||||||
|
@ -412,14 +413,14 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
||||||
});
|
});
|
||||||
|
|
||||||
this.isAutoScaleEnabled = ko.pureComputed<boolean>(() => {
|
this.isAutoScaleEnabled = ko.pureComputed<boolean>(() => {
|
||||||
const accountCapabilities: ViewModels.Capability[] =
|
const accountCapabilities: DataModels.Capability[] =
|
||||||
this.container &&
|
this.container &&
|
||||||
this.container.databaseAccount() &&
|
this.container.databaseAccount() &&
|
||||||
this.container.databaseAccount().properties &&
|
this.container.databaseAccount().properties &&
|
||||||
this.container.databaseAccount().properties.capabilities;
|
this.container.databaseAccount().properties.capabilities;
|
||||||
const enableAutoScaleCapability: ViewModels.Capability =
|
const enableAutoScaleCapability =
|
||||||
accountCapabilities &&
|
accountCapabilities &&
|
||||||
_.find(accountCapabilities, (capability: ViewModels.Capability) => {
|
_.find(accountCapabilities, capability => {
|
||||||
return (
|
return (
|
||||||
capability &&
|
capability &&
|
||||||
capability.name &&
|
capability.name &&
|
||||||
|
@ -1692,8 +1693,8 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
||||||
return document.getElementById(this.indexingPolicyEditorId);
|
return document.getElementById(this.indexingPolicyEditorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
if (this.saveSettingsButton.visible()) {
|
if (this.saveSettingsButton.visible()) {
|
||||||
const label = "Save";
|
const label = "Save";
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|
|
@ -4,13 +4,18 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import TabsBase from "./TabsBase";
|
import TabsBase from "./TabsBase";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
|
||||||
|
interface SparkMasterTabOptions extends ViewModels.TabOptions {
|
||||||
|
clusterConnectionInfo: DataModels.SparkClusterConnectionInfo;
|
||||||
|
container: Explorer;
|
||||||
|
}
|
||||||
|
|
||||||
export default class SparkMasterTab extends TabsBase {
|
export default class SparkMasterTab extends TabsBase {
|
||||||
public sparkMasterSrc: ko.Observable<string>;
|
public sparkMasterSrc: ko.Observable<string>;
|
||||||
|
|
||||||
private _clusterConnectionInfo: DataModels.SparkClusterConnectionInfo;
|
private _clusterConnectionInfo: DataModels.SparkClusterConnectionInfo;
|
||||||
private _container: Explorer;
|
private _container: Explorer;
|
||||||
|
|
||||||
constructor(options: ViewModels.SparkMasterTabOptions) {
|
constructor(options: SparkMasterTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
super.onActivate.bind(this);
|
super.onActivate.bind(this);
|
||||||
this._container = options.container;
|
this._container = options.container;
|
||||||
|
|
|
@ -11,13 +11,14 @@ import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
|
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
|
||||||
import StoredProcedure from "../Tree/StoredProcedure";
|
import StoredProcedure from "../Tree/StoredProcedure";
|
||||||
import { createStoredProcedure, updateStoredProcedure } from "../../Common/DocumentClientUtilityBase";
|
import { createStoredProcedure, updateStoredProcedure } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
enum ToggleState {
|
enum ToggleState {
|
||||||
Result = "result",
|
Result = "result",
|
||||||
Logs = "logs"
|
Logs = "logs"
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class StoredProcedureTab extends ScriptTabBase implements ViewModels.StoredProcedureTab {
|
export default class StoredProcedureTab extends ScriptTabBase {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
public node: StoredProcedure;
|
public node: StoredProcedure;
|
||||||
public executeResultsEditorId: string;
|
public executeResultsEditorId: string;
|
||||||
|
@ -204,7 +205,7 @@ export default class StoredProcedureTab extends ScriptTabBase implements ViewMod
|
||||||
super.buildCommandBarOptions();
|
super.buildCommandBarOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const label = "Execute";
|
const label = "Execute";
|
||||||
return super.getTabsButtons().concat({
|
return super.getTabsButtons().concat({
|
||||||
iconSrc: ExecuteQueryIcon,
|
iconSrc: ExecuteQueryIcon,
|
||||||
|
|
|
@ -8,9 +8,10 @@ import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import ThemeUtility from "../../Common/ThemeUtility";
|
import ThemeUtility from "../../Common/ThemeUtility";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
// TODO: Use specific actions for logging telemetry data
|
// TODO: Use specific actions for logging telemetry data
|
||||||
export default class TabsBase extends WaitsForTemplateViewModel implements ViewModels.Tab {
|
export default class TabsBase extends WaitsForTemplateViewModel {
|
||||||
public closeTabButton: ViewModels.Button;
|
public closeTabButton: ViewModels.Button;
|
||||||
public node: ViewModels.TreeNode;
|
public node: ViewModels.TreeNode;
|
||||||
public collection: ViewModels.CollectionBase;
|
public collection: ViewModels.CollectionBase;
|
||||||
|
@ -187,7 +188,7 @@ export default class TabsBase extends WaitsForTemplateViewModel implements ViewM
|
||||||
/**
|
/**
|
||||||
* @return buttons that are displayed in the navbar
|
* @return buttons that are displayed in the navbar
|
||||||
*/
|
*/
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import { TabsManager } from "./TabsManager";
|
import { TabsManager } from "./TabsManager";
|
||||||
import DocumentsTab from "./DocumentsTab";
|
import DocumentsTab from "./DocumentsTab";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import QueryTab from "./QueryTab";
|
import QueryTab from "./QueryTab";
|
||||||
|
import DocumentId from "../Tree/DocumentId";
|
||||||
|
|
||||||
describe("Tabs manager tests", () => {
|
describe("Tabs manager tests", () => {
|
||||||
let tabsManager: TabsManager;
|
let tabsManager: TabsManager;
|
||||||
|
@ -15,7 +17,7 @@ describe("Tabs manager tests", () => {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
explorer = new Explorer({ notificationsClient: undefined, isEmulator: false });
|
explorer = new Explorer({ notificationsClient: undefined, isEmulator: false });
|
||||||
explorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
|
explorer.databaseAccount = ko.observable<DataModels.DatabaseAccount>({
|
||||||
id: "test",
|
id: "test",
|
||||||
name: "test",
|
name: "test",
|
||||||
location: "",
|
location: "",
|
||||||
|
@ -56,7 +58,7 @@ describe("Tabs manager tests", () => {
|
||||||
|
|
||||||
documentsTab = new DocumentsTab({
|
documentsTab = new DocumentsTab({
|
||||||
partitionKey: undefined,
|
partitionKey: undefined,
|
||||||
documentIds: ko.observableArray<ViewModels.DocumentId>(),
|
documentIds: ko.observableArray<DocumentId>(),
|
||||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||||
collection,
|
collection,
|
||||||
title: "",
|
title: "",
|
||||||
|
@ -102,13 +104,13 @@ describe("Tabs manager tests", () => {
|
||||||
tabsManager.activateNewTab(queryTab);
|
tabsManager.activateNewTab(queryTab);
|
||||||
tabsManager.activateNewTab(documentsTab);
|
tabsManager.activateNewTab(documentsTab);
|
||||||
|
|
||||||
const queryTabs: ViewModels.Tab[] = tabsManager.getTabs(ViewModels.CollectionTabKind.Query);
|
const queryTabs = tabsManager.getTabs(ViewModels.CollectionTabKind.Query);
|
||||||
expect(queryTabs.length).toBe(1);
|
expect(queryTabs.length).toBe(1);
|
||||||
expect(queryTabs[0]).toEqual(queryTab);
|
expect(queryTabs[0]).toEqual(queryTab);
|
||||||
|
|
||||||
const documentsTabs: ViewModels.Tab[] = tabsManager.getTabs(
|
const documentsTabs = tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Documents,
|
ViewModels.CollectionTabKind.Documents,
|
||||||
(tab: ViewModels.Tab) => tab.tabId === documentsTab.tabId
|
tab => tab.tabId === documentsTab.tabId
|
||||||
);
|
);
|
||||||
expect(documentsTabs.length).toBe(1);
|
expect(documentsTabs.length).toBe(1);
|
||||||
expect(documentsTabs[0]).toEqual(documentsTab);
|
expect(documentsTabs[0]).toEqual(documentsTab);
|
||||||
|
@ -125,7 +127,7 @@ describe("Tabs manager tests", () => {
|
||||||
expect(queryTab.isActive()).toBe(true);
|
expect(queryTab.isActive()).toBe(true);
|
||||||
expect(documentsTab.isActive()).toBe(false);
|
expect(documentsTab.isActive()).toBe(false);
|
||||||
|
|
||||||
tabsManager.closeTabsByComparator((tab: ViewModels.Tab) => tab.tabId === queryTab.tabId);
|
tabsManager.closeTabsByComparator(tab => tab.tabId === queryTab.tabId);
|
||||||
expect(tabsManager.openedTabs().length).toBe(0);
|
expect(tabsManager.openedTabs().length).toBe(0);
|
||||||
expect(tabsManager.activeTab()).toEqual(undefined);
|
expect(tabsManager.activeTab()).toEqual(undefined);
|
||||||
expect(queryTab.isActive()).toBe(false);
|
expect(queryTab.isActive()).toBe(false);
|
||||||
|
|
|
@ -2,39 +2,37 @@ import * as ko from "knockout";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import TabsManagerTemplate from "./TabsManager.html";
|
import TabsManagerTemplate from "./TabsManager.html";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import TabsBase from "./TabsBase";
|
||||||
|
|
||||||
export class TabsManager {
|
export class TabsManager {
|
||||||
public openedTabs: ko.ObservableArray<ViewModels.Tab>;
|
public openedTabs: ko.ObservableArray<TabsBase>;
|
||||||
public activeTab: ko.Observable<ViewModels.Tab>;
|
public activeTab: ko.Observable<TabsBase>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.openedTabs = ko.observableArray<ViewModels.Tab>([]);
|
this.openedTabs = ko.observableArray<TabsBase>([]);
|
||||||
this.activeTab = ko.observable<ViewModels.Tab>();
|
this.activeTab = ko.observable<TabsBase>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public activateNewTab(tab: ViewModels.Tab): void {
|
public activateNewTab(tab: TabsBase): void {
|
||||||
this.openedTabs.push(tab);
|
this.openedTabs.push(tab);
|
||||||
this.activateTab(tab);
|
this.activateTab(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
public activateTab(tab: ViewModels.Tab): void {
|
public activateTab(tab: TabsBase): void {
|
||||||
this.activeTab() && this.activeTab().isActive(false);
|
this.activeTab() && this.activeTab().isActive(false);
|
||||||
tab.isActive(true);
|
tab.isActive(true);
|
||||||
this.activeTab(tab);
|
this.activeTab(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTabs(
|
public getTabs(tabKind: ViewModels.CollectionTabKind, comparator?: (tab: TabsBase) => boolean): TabsBase[] {
|
||||||
tabKind: ViewModels.CollectionTabKind,
|
return this.openedTabs().filter((openedTab: TabsBase) => {
|
||||||
comparator?: (tab: ViewModels.Tab) => boolean
|
|
||||||
): ViewModels.Tab[] {
|
|
||||||
return this.openedTabs().filter((openedTab: ViewModels.Tab) => {
|
|
||||||
return openedTab.tabKind === tabKind && (!comparator || comparator(openedTab));
|
return openedTab.tabKind === tabKind && (!comparator || comparator(openedTab));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public refreshActiveTab(comparator: (tab: ViewModels.Tab) => boolean): void {
|
public refreshActiveTab(comparator: (tab: TabsBase) => boolean): void {
|
||||||
// ensures that the tab selects/highlights the right node based on resource tree expand/collapse state
|
// ensures that the tab selects/highlights the right node based on resource tree expand/collapse state
|
||||||
this.openedTabs().forEach((tab: ViewModels.Tab) => {
|
this.openedTabs().forEach((tab: TabsBase) => {
|
||||||
if (comparator(tab) && tab.isActive()) {
|
if (comparator(tab) && tab.isActive()) {
|
||||||
tab.onActivate();
|
tab.onActivate();
|
||||||
}
|
}
|
||||||
|
@ -42,17 +40,17 @@ export class TabsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeTabById(tabId: string): void {
|
public removeTabById(tabId: string): void {
|
||||||
this.openedTabs.remove((tab: ViewModels.Tab) => tab.tabId === tabId);
|
this.openedTabs.remove((tab: TabsBase) => tab.tabId === tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeTabByComparator(comparator: (tab: ViewModels.Tab) => boolean): void {
|
public removeTabByComparator(comparator: (tab: TabsBase) => boolean): void {
|
||||||
this.openedTabs.remove((tab: ViewModels.Tab) => comparator(tab));
|
this.openedTabs.remove((tab: TabsBase) => comparator(tab));
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeTabsByComparator(comparator: (tab: ViewModels.Tab) => boolean): void {
|
public closeTabsByComparator(comparator: (tab: TabsBase) => boolean): void {
|
||||||
this.activeTab() && this.activeTab().isActive(false);
|
this.activeTab() && this.activeTab().isActive(false);
|
||||||
this.activeTab(undefined);
|
this.activeTab(undefined);
|
||||||
this.openedTabs().forEach((tab: ViewModels.Tab) => {
|
this.openedTabs().forEach((tab: TabsBase) => {
|
||||||
if (comparator(tab)) {
|
if (comparator(tab)) {
|
||||||
tab.onCloseTabButtonClick();
|
tab.onCloseTabButtonClick();
|
||||||
}
|
}
|
||||||
|
@ -64,9 +62,9 @@ export class TabsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeTab(tabId: string, explorer: Explorer): void {
|
public closeTab(tabId: string, explorer: Explorer): void {
|
||||||
const tabIndex: number = this.openedTabs().findIndex((tab: ViewModels.Tab) => tab.tabId === tabId);
|
const tabIndex: number = this.openedTabs().findIndex((tab: TabsBase) => tab.tabId === tabId);
|
||||||
if (tabIndex !== -1) {
|
if (tabIndex !== -1) {
|
||||||
const tabToActive: ViewModels.Tab = this.openedTabs()[tabIndex + 1] || this.openedTabs()[tabIndex - 1];
|
const tabToActive: TabsBase = this.openedTabs()[tabIndex + 1] || this.openedTabs()[tabIndex - 1];
|
||||||
this.openedTabs()[tabIndex].isActive(false);
|
this.openedTabs()[tabIndex].isActive(false);
|
||||||
this.removeTabById(tabId);
|
this.removeTabById(tabId);
|
||||||
if (tabToActive) {
|
if (tabToActive) {
|
||||||
|
|
|
@ -6,6 +6,13 @@ import * as React from "react";
|
||||||
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
|
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
|
||||||
import { NotebookTerminalComponent } from "../Controls/Notebook/NotebookTerminalComponent";
|
import { NotebookTerminalComponent } from "../Controls/Notebook/NotebookTerminalComponent";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
|
export interface TerminalTabOptions extends ViewModels.TabOptions {
|
||||||
|
account: DataModels.DatabaseAccount;
|
||||||
|
container: Explorer;
|
||||||
|
kind: ViewModels.TerminalKind;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notebook terminal tab
|
* Notebook terminal tab
|
||||||
|
@ -30,11 +37,11 @@ class NotebookTerminalComponentAdapter implements ReactAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TerminalTab extends TabsBase implements ViewModels.Tab {
|
export default class TerminalTab extends TabsBase {
|
||||||
private container: Explorer;
|
private container: Explorer;
|
||||||
private notebookTerminalComponentAdapter: NotebookTerminalComponentAdapter;
|
private notebookTerminalComponentAdapter: NotebookTerminalComponentAdapter;
|
||||||
|
|
||||||
constructor(options: ViewModels.TerminalTabOptions) {
|
constructor(options: TerminalTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
this.notebookTerminalComponentAdapter = new NotebookTerminalComponentAdapter(
|
this.notebookTerminalComponentAdapter = new NotebookTerminalComponentAdapter(
|
||||||
|
@ -53,15 +60,15 @@ export default class TerminalTab extends TabsBase implements ViewModels.Tab {
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTabsButtons(): ViewModels.NavbarButtonConfig[] {
|
protected getTabsButtons(): CommandButtonComponentProps[] {
|
||||||
const buttons: ViewModels.NavbarButtonConfig[] = [];
|
const buttons: CommandButtonComponentProps[] = [];
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
protected buildCommandBarOptions(): void {
|
protected buildCommandBarOptions(): void {
|
||||||
this.updateNavbarWithTabsButtons();
|
this.updateNavbarWithTabsButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNotebookServerInfo(options: ViewModels.TerminalTabOptions): DataModels.NotebookWorkspaceConnectionInfo {
|
private getNotebookServerInfo(options: TerminalTabOptions): DataModels.NotebookWorkspaceConnectionInfo {
|
||||||
let endpointSuffix: string;
|
let endpointSuffix: string;
|
||||||
|
|
||||||
switch (options.kind) {
|
switch (options.kind) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Trigger from "../Tree/Trigger";
|
import Trigger from "../Tree/Trigger";
|
||||||
import { createTrigger, updateTrigger } from "../../Common/DocumentClientUtilityBase";
|
import { createTrigger, updateTrigger } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
|
||||||
export default class TriggerTab extends ScriptTabBase implements ViewModels.TriggerTab {
|
export default class TriggerTab extends ScriptTabBase {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
public node: Trigger;
|
public node: Trigger;
|
||||||
public triggerType: ViewModels.Editable<string>;
|
public triggerType: ViewModels.Editable<string>;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import UserDefinedFunction from "../Tree/UserDefinedFunction";
|
import UserDefinedFunction from "../Tree/UserDefinedFunction";
|
||||||
import { createUserDefinedFunction, updateUserDefinedFunction } from "../../Common/DocumentClientUtilityBase";
|
import { createUserDefinedFunction, updateUserDefinedFunction } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
|
||||||
export default class UserDefinedFunctionTab extends ScriptTabBase implements ViewModels.UserDefinedFunctionTab {
|
export default class UserDefinedFunctionTab extends ScriptTabBase {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
public node: UserDefinedFunction;
|
public node: UserDefinedFunction;
|
||||||
constructor(options: ViewModels.ScriptTabOption) {
|
constructor(options: ViewModels.ScriptTabOption) {
|
||||||
|
|
|
@ -240,9 +240,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
this.expandCollection();
|
this.expandCollection();
|
||||||
}
|
}
|
||||||
this.container.onUpdateTabsButtons([]);
|
this.container.onUpdateTabsButtons([]);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public collapseCollection() {
|
public collapseCollection() {
|
||||||
|
@ -293,7 +291,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const documentsTabs: DocumentsTab[] = this.container.tabsManager.getTabs(
|
const documentsTabs: DocumentsTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Documents,
|
ViewModels.CollectionTabKind.Documents,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as DocumentsTab[];
|
) as DocumentsTab[];
|
||||||
let documentsTab: DocumentsTab = documentsTabs && documentsTabs[0];
|
let documentsTab: DocumentsTab = documentsTabs && documentsTabs[0];
|
||||||
|
|
||||||
|
@ -344,7 +342,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const conflictsTabs: ConflictsTab[] = this.container.tabsManager.getTabs(
|
const conflictsTabs: ConflictsTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Conflicts,
|
ViewModels.CollectionTabKind.Conflicts,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as ConflictsTab[];
|
) as ConflictsTab[];
|
||||||
let conflictsTab: ConflictsTab = conflictsTabs && conflictsTabs[0];
|
let conflictsTab: ConflictsTab = conflictsTabs && conflictsTabs[0];
|
||||||
|
|
||||||
|
@ -401,7 +399,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const queryTablesTabs: QueryTablesTab[] = this.container.tabsManager.getTabs(
|
const queryTablesTabs: QueryTablesTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.QueryTables,
|
ViewModels.CollectionTabKind.QueryTables,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as QueryTablesTab[];
|
) as QueryTablesTab[];
|
||||||
let queryTablesTab: QueryTablesTab = queryTablesTabs && queryTablesTabs[0];
|
let queryTablesTab: QueryTablesTab = queryTablesTabs && queryTablesTabs[0];
|
||||||
|
|
||||||
|
@ -455,7 +453,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const graphTabs: GraphTab[] = this.container.tabsManager.getTabs(
|
const graphTabs: GraphTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Graph,
|
ViewModels.CollectionTabKind.Graph,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as GraphTab[];
|
) as GraphTab[];
|
||||||
let graphTab: GraphTab = graphTabs && graphTabs[0];
|
let graphTab: GraphTab = graphTabs && graphTabs[0];
|
||||||
|
|
||||||
|
@ -511,7 +509,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const mongoDocumentsTabs: MongoDocumentsTab[] = this.container.tabsManager.getTabs(
|
const mongoDocumentsTabs: MongoDocumentsTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Documents,
|
ViewModels.CollectionTabKind.Documents,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as MongoDocumentsTab[];
|
) as MongoDocumentsTab[];
|
||||||
let mongoDocumentsTab: MongoDocumentsTab = mongoDocumentsTabs && mongoDocumentsTabs[0];
|
let mongoDocumentsTab: MongoDocumentsTab = mongoDocumentsTabs && mongoDocumentsTabs[0];
|
||||||
|
|
||||||
|
@ -562,12 +560,9 @@ export default class Collection implements ViewModels.Collection {
|
||||||
|
|
||||||
const tabTitle = !this.offer() ? "Settings" : "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 = this.container.tabsManager.getTabs(ViewModels.CollectionTabKind.Settings, tab => {
|
||||||
ViewModels.CollectionTabKind.Settings,
|
return tab.collection && tab.collection.rid === this.rid;
|
||||||
(tab: ViewModels.Tab) => {
|
});
|
||||||
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) {
|
||||||
|
@ -902,9 +897,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
} else {
|
} else {
|
||||||
this.expandStoredProcedures();
|
this.expandStoredProcedures();
|
||||||
}
|
}
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public expandStoredProcedures() {
|
public expandStoredProcedures() {
|
||||||
|
@ -961,9 +954,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
} else {
|
} else {
|
||||||
this.expandUserDefinedFunctions();
|
this.expandUserDefinedFunctions();
|
||||||
}
|
}
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public expandUserDefinedFunctions() {
|
public expandUserDefinedFunctions() {
|
||||||
|
@ -1020,9 +1011,7 @@ export default class Collection implements ViewModels.Collection {
|
||||||
} else {
|
} else {
|
||||||
this.expandTriggers();
|
this.expandTriggers();
|
||||||
}
|
}
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public expandTriggers() {
|
public expandTriggers() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { extractPartitionKey } from "@azure/cosmos";
|
||||||
import ConflictsTab from "../Tabs/ConflictsTab";
|
import ConflictsTab from "../Tabs/ConflictsTab";
|
||||||
import { readDocument } from "../../Common/DocumentClientUtilityBase";
|
import { readDocument } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
|
||||||
export default class ConflictId implements ViewModels.ConflictId {
|
export default class ConflictId {
|
||||||
public container: ConflictsTab;
|
public container: ConflictsTab;
|
||||||
public rid: string;
|
public rid: string;
|
||||||
public self: string;
|
public self: string;
|
||||||
|
@ -115,7 +115,7 @@ export default class ConflictId implements ViewModels.ConflictId {
|
||||||
return JSON.stringify(partitionKeyValue);
|
return JSON.stringify(partitionKeyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildDocumentIdFromConflict(partitionKeyValue: any): ViewModels.DocumentId {
|
public buildDocumentIdFromConflict(partitionKeyValue: any): DocumentId {
|
||||||
const conflictDocumentRid = Constants.HashRoutePrefixes.docsWithIds(
|
const conflictDocumentRid = Constants.HashRoutePrefixes.docsWithIds(
|
||||||
this.container.collection.getDatabase().rid,
|
this.container.collection.getDatabase().rid,
|
||||||
this.container.collection.rid,
|
this.container.collection.rid,
|
||||||
|
|
|
@ -52,9 +52,9 @@ export default class Database implements ViewModels.Database {
|
||||||
});
|
});
|
||||||
|
|
||||||
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 = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.DatabaseSettings,
|
ViewModels.CollectionTabKind.DatabaseSettings,
|
||||||
(tab: ViewModels.Tab) => tab.rid === this.rid
|
tab => tab.rid === this.rid
|
||||||
);
|
);
|
||||||
let settingsTab: DatabaseSettingsTab = matchingTabs && (matchingTabs[0] as DatabaseSettingsTab);
|
let settingsTab: DatabaseSettingsTab = matchingTabs && (matchingTabs[0] as DatabaseSettingsTab);
|
||||||
if (!settingsTab) {
|
if (!settingsTab) {
|
||||||
|
@ -223,9 +223,7 @@ export default class Database implements ViewModels.Database {
|
||||||
this.expandDatabase();
|
this.expandDatabase();
|
||||||
}
|
}
|
||||||
this.container.onUpdateTabsButtons([]);
|
this.container.onUpdateTabsButtons([]);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.getDatabase().rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.getDatabase().rid === this.rid
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public expandDatabase() {
|
public expandDatabase() {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import DocumentsTab from "../Tabs/DocumentsTab";
|
||||||
|
|
||||||
export default class DocumentId implements ViewModels.DocumentId {
|
export default class DocumentId {
|
||||||
public container: ViewModels.DocumentsTab;
|
public container: DocumentsTab;
|
||||||
public rid: string;
|
public rid: string;
|
||||||
public self: string;
|
public self: string;
|
||||||
public ts: string;
|
public ts: string;
|
||||||
|
@ -14,7 +14,7 @@ export default class DocumentId implements ViewModels.DocumentId {
|
||||||
public stringPartitionKeyValue: string;
|
public stringPartitionKeyValue: string;
|
||||||
public isDirty: ko.Observable<boolean>;
|
public isDirty: ko.Observable<boolean>;
|
||||||
|
|
||||||
constructor(container: ViewModels.DocumentsTab, data: any, partitionKeyValue: any) {
|
constructor(container: DocumentsTab, data: any, partitionKeyValue: any) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.self = data._self;
|
this.self = data._self;
|
||||||
this.rid = data._rid;
|
this.rid = data._rid;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import DocumentId from "./DocumentId";
|
import DocumentId from "./DocumentId";
|
||||||
|
import DocumentsTab from "../Tabs/DocumentsTab";
|
||||||
|
|
||||||
export default class ObjectId extends DocumentId implements ViewModels.DocumentId {
|
export default class ObjectId extends DocumentId {
|
||||||
constructor(container: ViewModels.DocumentsTab, data: any, partitionKeyValue: any) {
|
constructor(container: DocumentsTab, data: any, partitionKeyValue: any) {
|
||||||
super(container, data, partitionKeyValue);
|
super(container, data, partitionKeyValue);
|
||||||
if (typeof data._id === "object") {
|
if (typeof data._id === "object") {
|
||||||
this.id = ko.observable(data._id[Object.keys(data._id)[0]]);
|
this.id = ko.observable(data._id[Object.keys(data._id)[0]]);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Q from "q";
|
||||||
import QueryTab from "../Tabs/QueryTab";
|
import QueryTab from "../Tabs/QueryTab";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
|
import TabsBase from "../Tabs/TabsBase";
|
||||||
|
|
||||||
export default class ResourceTokenCollection implements ViewModels.CollectionBase {
|
export default class ResourceTokenCollection implements ViewModels.CollectionBase {
|
||||||
public nodeKind: string;
|
public nodeKind: string;
|
||||||
|
@ -120,7 +121,7 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas
|
||||||
|
|
||||||
const documentsTabs: DocumentsTab[] = this.container.tabsManager.getTabs(
|
const documentsTabs: DocumentsTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Documents,
|
ViewModels.CollectionTabKind.Documents,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
(tab: TabsBase) => tab.collection && tab.collection.rid === this.rid
|
||||||
) as DocumentsTab[];
|
) as DocumentsTab[];
|
||||||
let documentsTab: DocumentsTab = documentsTabs && documentsTabs[0];
|
let documentsTab: DocumentsTab = documentsTabs && documentsTabs[0];
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ import Explorer from "../Explorer";
|
||||||
import UserDefinedFunction from "./UserDefinedFunction";
|
import UserDefinedFunction from "./UserDefinedFunction";
|
||||||
import StoredProcedure from "./StoredProcedure";
|
import StoredProcedure from "./StoredProcedure";
|
||||||
import Trigger from "./Trigger";
|
import Trigger from "./Trigger";
|
||||||
|
import TabsBase from "../Tabs/TabsBase";
|
||||||
|
|
||||||
export class ResourceTreeAdapter implements ReactAdapter {
|
export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
private static readonly DataTitle = "DATA";
|
private static readonly DataTitle = "DATA";
|
||||||
|
@ -50,7 +51,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
this.parameters = ko.observable(Date.now());
|
this.parameters = ko.observable(Date.now());
|
||||||
|
|
||||||
this.container.selectedNode.subscribe((newValue: any) => this.triggerRender());
|
this.container.selectedNode.subscribe((newValue: any) => this.triggerRender());
|
||||||
this.container.tabsManager.activeTab.subscribe((newValue: ViewModels.Tab) => this.triggerRender());
|
this.container.tabsManager.activeTab.subscribe((newValue: TabsBase) => this.triggerRender());
|
||||||
this.container.isNotebookEnabled.subscribe(newValue => this.triggerRender());
|
this.container.isNotebookEnabled.subscribe(newValue => this.triggerRender());
|
||||||
|
|
||||||
this.koSubsDatabaseIdMap = new ArrayHashMap();
|
this.koSubsDatabaseIdMap = new ArrayHashMap();
|
||||||
|
@ -176,7 +177,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
database.selectDatabase();
|
database.selectDatabase();
|
||||||
this.container.onUpdateTabsButtons([]);
|
this.container.onUpdateTabsButtons([]);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.getDatabase().rid === database.rid
|
(tab: TabsBase) => tab.collection && tab.collection.getDatabase().rid === database.rid
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onContextMenuOpen: () => this.container.selectedNode(database)
|
onContextMenuOpen: () => this.container.selectedNode(database)
|
||||||
|
@ -275,7 +276,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
this.container.selectedNode(collection);
|
this.container.selectedNode(collection);
|
||||||
this.container.onUpdateTabsButtons([]);
|
this.container.onUpdateTabsButtons([]);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === collection.rid
|
(tab: TabsBase) => tab.collection && tab.collection.rid === collection.rid
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onExpanded: () => {
|
onExpanded: () => {
|
||||||
|
@ -303,7 +304,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.StoredProcedures);
|
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.StoredProcedures);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === collection.rid
|
(tab: TabsBase) => tab.collection && tab.collection.rid === collection.rid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -322,7 +323,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.UserDefinedFunctions);
|
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.UserDefinedFunctions);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === collection.rid
|
(tab: TabsBase) => tab.collection && tab.collection.rid === collection.rid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -340,7 +341,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Triggers);
|
collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Triggers);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === collection.rid
|
(tab: TabsBase) => tab.collection && tab.collection.rid === collection.rid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,10 +16,9 @@ export class ResourceTreeAdapterForResourceToken implements ReactAdapter {
|
||||||
public constructor(private container: Explorer) {
|
public constructor(private container: Explorer) {
|
||||||
this.parameters = ko.observable(Date.now());
|
this.parameters = ko.observable(Date.now());
|
||||||
|
|
||||||
this.container.resourceTokenCollection.subscribe((collection: ViewModels.CollectionBase) => this.triggerRender());
|
this.container.resourceTokenCollection.subscribe(() => this.triggerRender());
|
||||||
this.container.selectedNode.subscribe((newValue: any) => this.triggerRender());
|
this.container.selectedNode.subscribe((newValue: any) => this.triggerRender());
|
||||||
this.container.tabsManager &&
|
this.container.tabsManager && this.container.tabsManager.activeTab.subscribe(() => this.triggerRender());
|
||||||
this.container.tabsManager.activeTab.subscribe((newValue: ViewModels.Tab) => this.triggerRender());
|
|
||||||
|
|
||||||
this.triggerRender();
|
this.triggerRender();
|
||||||
}
|
}
|
||||||
|
@ -65,9 +64,7 @@ export class ResourceTreeAdapterForResourceToken implements ReactAdapter {
|
||||||
// Rewritten version of expandCollapseCollection
|
// Rewritten version of expandCollapseCollection
|
||||||
this.container.selectedNode(collection);
|
this.container.selectedNode(collection);
|
||||||
this.container.onUpdateTabsButtons([]);
|
this.container.onUpdateTabsButtons([]);
|
||||||
this.container.tabsManager.refreshActiveTab(
|
this.container.tabsManager.refreshActiveTab(tab => tab.collection && tab.collection.rid === collection.rid);
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === collection.rid
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
isSelected: () => this.isDataNodeSelected(collection.rid, "Collection", undefined)
|
isSelected: () => this.isDataNodeSelected(collection.rid, "Collection", undefined)
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ import StoredProcedureTab from "../Tabs/StoredProcedureTab";
|
||||||
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import { deleteStoredProcedure, executeStoredProcedure } from "../../Common/DocumentClientUtilityBase";
|
import { deleteStoredProcedure, executeStoredProcedure } from "../../Common/DocumentClientUtilityBase";
|
||||||
|
import TabsBase from "../Tabs/TabsBase";
|
||||||
|
|
||||||
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
|
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
|
||||||
function sample(prefix) {
|
function sample(prefix) {
|
||||||
|
@ -96,7 +97,7 @@ export default class StoredProcedure {
|
||||||
|
|
||||||
const storedProcedureTabs: StoredProcedureTab[] = this.container.tabsManager.getTabs(
|
const storedProcedureTabs: StoredProcedureTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.StoredProcedures,
|
ViewModels.CollectionTabKind.StoredProcedures,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
(tab: TabsBase) => tab.node && tab.node.rid === this.rid
|
||||||
) as StoredProcedureTab[];
|
) as StoredProcedureTab[];
|
||||||
let storedProcedureTab: StoredProcedureTab = storedProcedureTabs && storedProcedureTabs[0];
|
let storedProcedureTab: StoredProcedureTab = storedProcedureTabs && storedProcedureTabs[0];
|
||||||
|
|
||||||
|
@ -145,9 +146,7 @@ export default class StoredProcedure {
|
||||||
|
|
||||||
deleteStoredProcedure(this.collection, storedProcedureData).then(
|
deleteStoredProcedure(this.collection, storedProcedureData).then(
|
||||||
() => {
|
() => {
|
||||||
this.container.tabsManager.removeTabByComparator(
|
this.container.tabsManager.removeTabByComparator((tab: TabsBase) => tab.node && tab.node.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
|
||||||
);
|
|
||||||
this.collection.children.remove(this);
|
this.collection.children.remove(this);
|
||||||
},
|
},
|
||||||
reason => {}
|
reason => {}
|
||||||
|
@ -155,11 +154,11 @@ export default class StoredProcedure {
|
||||||
}
|
}
|
||||||
|
|
||||||
public execute(params: string[], partitionKeyValue?: string): void {
|
public execute(params: string[], partitionKeyValue?: string): void {
|
||||||
const sprocTabs: ViewModels.StoredProcedureTab[] = this.container.tabsManager.getTabs(
|
const sprocTabs = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.StoredProcedures,
|
ViewModels.CollectionTabKind.StoredProcedures,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
(tab: TabsBase) => tab.node && tab.node.rid === this.rid
|
||||||
) as ViewModels.StoredProcedureTab[];
|
) as StoredProcedureTab[];
|
||||||
const sprocTab: ViewModels.StoredProcedureTab = sprocTabs && sprocTabs.length > 0 && sprocTabs[0];
|
const sprocTab = sprocTabs && sprocTabs.length > 0 && sprocTabs[0];
|
||||||
sprocTab.isExecuting(true);
|
sprocTab.isExecuting(true);
|
||||||
this.container &&
|
this.container &&
|
||||||
executeStoredProcedure(this.collection, this, partitionKeyValue, params)
|
executeStoredProcedure(this.collection, this, partitionKeyValue, params)
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default class Trigger {
|
||||||
|
|
||||||
const triggerTabs: TriggerTab[] = this.container.tabsManager.getTabs(
|
const triggerTabs: TriggerTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Triggers,
|
ViewModels.CollectionTabKind.Triggers,
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
tab => tab.node && tab.node.rid === this.rid
|
||||||
) as TriggerTab[];
|
) as TriggerTab[];
|
||||||
let triggerTab: TriggerTab = triggerTabs && triggerTabs[0];
|
let triggerTab: TriggerTab = triggerTabs && triggerTabs[0];
|
||||||
|
|
||||||
|
@ -125,9 +125,7 @@ export default class Trigger {
|
||||||
|
|
||||||
deleteTrigger(this.collection, triggerData).then(
|
deleteTrigger(this.collection, triggerData).then(
|
||||||
() => {
|
() => {
|
||||||
this.container.tabsManager.removeTabByComparator(
|
this.container.tabsManager.removeTabByComparator(tab => tab.node && tab.node.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
|
||||||
);
|
|
||||||
this.collection.children.remove(this);
|
this.collection.children.remove(this);
|
||||||
},
|
},
|
||||||
reason => {}
|
reason => {}
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default class UserDefinedFunction {
|
||||||
|
|
||||||
const userDefinedFunctionTabs: UserDefinedFunctionTab[] = this.container.tabsManager.getTabs(
|
const userDefinedFunctionTabs: UserDefinedFunctionTab[] = this.container.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
||||||
(tab: ViewModels.Tab) => tab.collection && tab.collection.rid === this.rid
|
tab => tab.collection && tab.collection.rid === this.rid
|
||||||
) as UserDefinedFunctionTab[];
|
) as UserDefinedFunctionTab[];
|
||||||
let userDefinedFunctionTab: UserDefinedFunctionTab = userDefinedFunctionTabs && userDefinedFunctionTabs[0];
|
let userDefinedFunctionTab: UserDefinedFunctionTab = userDefinedFunctionTabs && userDefinedFunctionTabs[0];
|
||||||
|
|
||||||
|
@ -115,9 +115,7 @@ export default class UserDefinedFunction {
|
||||||
};
|
};
|
||||||
deleteUserDefinedFunction(this.collection, userDefinedFunctionData).then(
|
deleteUserDefinedFunction(this.collection, userDefinedFunctionData).then(
|
||||||
() => {
|
() => {
|
||||||
this.container.tabsManager.removeTabByComparator(
|
this.container.tabsManager.removeTabByComparator(tab => tab.node && tab.node.rid === this.rid);
|
||||||
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
|
|
||||||
);
|
|
||||||
this.collection.children.remove(this);
|
this.collection.children.remove(this);
|
||||||
},
|
},
|
||||||
reason => {}
|
reason => {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import { HttpStatusCodes } from "../Common/Constants";
|
import { HttpStatusCodes } from "../Common/Constants";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import { JunoClient } from "../Juno/JunoClient";
|
import { JunoClient } from "../Juno/JunoClient";
|
||||||
import { GitHubConnector, IGitHubConnectorParams } from "./GitHubConnector";
|
import { GitHubConnector, IGitHubConnectorParams } from "./GitHubConnector";
|
||||||
import { GitHubOAuthService } from "./GitHubOAuthService";
|
import { GitHubOAuthService } from "./GitHubOAuthService";
|
||||||
|
@ -8,7 +8,7 @@ import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/Notificat
|
||||||
import NotebookManager from "../Explorer/Notebook/NotebookManager";
|
import NotebookManager from "../Explorer/Notebook/NotebookManager";
|
||||||
import Explorer from "../Explorer/Explorer";
|
import Explorer from "../Explorer/Explorer";
|
||||||
|
|
||||||
const sampleDatabaseAccount: ViewModels.DatabaseAccount = {
|
const sampleDatabaseAccount: DataModels.DatabaseAccount = {
|
||||||
id: "id",
|
id: "id",
|
||||||
name: "name",
|
name: "name",
|
||||||
location: "location",
|
location: "location",
|
||||||
|
@ -29,7 +29,7 @@ describe("GitHubOAuthService", () => {
|
||||||
let originalDataExplorer: Explorer;
|
let originalDataExplorer: Explorer;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
junoClient = new JunoClient(ko.observable<ViewModels.DatabaseAccount>(sampleDatabaseAccount));
|
junoClient = new JunoClient(ko.observable<DataModels.DatabaseAccount>(sampleDatabaseAccount));
|
||||||
gitHubOAuthService = new GitHubOAuthService(junoClient);
|
gitHubOAuthService = new GitHubOAuthService(junoClient);
|
||||||
originalDataExplorer = window.dataExplorer;
|
originalDataExplorer = window.dataExplorer;
|
||||||
window.dataExplorer = {
|
window.dataExplorer = {
|
||||||
|
|
|
@ -27,7 +27,6 @@ import * as Logger from "./Common/Logger";
|
||||||
import { MeControlComponentProps } from "./Explorer/Menus/NavBar/MeControlComponent";
|
import { MeControlComponentProps } from "./Explorer/Menus/NavBar/MeControlComponent";
|
||||||
import { MeControlComponentAdapter } from "./Explorer/Menus/NavBar/MeControlComponentAdapter";
|
import { MeControlComponentAdapter } from "./Explorer/Menus/NavBar/MeControlComponentAdapter";
|
||||||
import { MessageTypes } from "./Contracts/ExplorerContracts";
|
import { MessageTypes } from "./Contracts/ExplorerContracts";
|
||||||
import { NavbarButtonConfig } from "./Contracts/ViewModels";
|
|
||||||
import * as ReactBindingHandler from "./Bindings/ReactBindingHandler";
|
import * as ReactBindingHandler from "./Bindings/ReactBindingHandler";
|
||||||
import { SwitchDirectoryPane, SwitchDirectoryPaneComponent } from "./Explorer/Panes/SwitchDirectoryPane";
|
import { SwitchDirectoryPane, SwitchDirectoryPaneComponent } from "./Explorer/Panes/SwitchDirectoryPane";
|
||||||
import TelemetryProcessor from "./Shared/Telemetry/TelemetryProcessor";
|
import TelemetryProcessor from "./Shared/Telemetry/TelemetryProcessor";
|
||||||
|
@ -38,6 +37,7 @@ import ConnectIcon from "../images/HostedConnectwhite.svg";
|
||||||
import SettingsIcon from "../images/HostedSettings.svg";
|
import SettingsIcon from "../images/HostedSettings.svg";
|
||||||
import FeedbackIcon from "../images/Feedback.svg";
|
import FeedbackIcon from "../images/Feedback.svg";
|
||||||
import SwitchDirectoryIcon from "../images/DirectorySwitch.svg";
|
import SwitchDirectoryIcon from "../images/DirectorySwitch.svg";
|
||||||
|
import { CommandButtonComponentProps } from "./Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||||
|
|
||||||
ReactBindingHandler.Registerer.register();
|
ReactBindingHandler.Registerer.register();
|
||||||
ko.components.register("switch-directory-pane", new SwitchDirectoryPaneComponent());
|
ko.components.register("switch-directory-pane", new SwitchDirectoryPaneComponent());
|
||||||
|
@ -56,7 +56,7 @@ class HostedExplorer {
|
||||||
private _dialogProps: ko.Observable<DialogProps>;
|
private _dialogProps: ko.Observable<DialogProps>;
|
||||||
private _meControlProps: ko.Observable<MeControlComponentProps>;
|
private _meControlProps: ko.Observable<MeControlComponentProps>;
|
||||||
private _accountSwitchProps: ko.Observable<AccountSwitchComponentProps>;
|
private _accountSwitchProps: ko.Observable<AccountSwitchComponentProps>;
|
||||||
private _controlbarCommands: ko.ObservableArray<NavbarButtonConfig>;
|
private _controlbarCommands: ko.ObservableArray<CommandButtonComponentProps>;
|
||||||
private _directoryDropdownProps: ko.Observable<DefaultDirectoryDropdownProps>;
|
private _directoryDropdownProps: ko.Observable<DefaultDirectoryDropdownProps>;
|
||||||
private _directoryListProps: ko.Observable<DirectoryListProps>;
|
private _directoryListProps: ko.Observable<DirectoryListProps>;
|
||||||
|
|
||||||
|
@ -1086,7 +1086,7 @@ class HostedExplorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setAadControlBar() {
|
private _setAadControlBar() {
|
||||||
const switchDirectoryCommand: NavbarButtonConfig = {
|
const switchDirectoryCommand: CommandButtonComponentProps = {
|
||||||
iconSrc: SwitchDirectoryIcon,
|
iconSrc: SwitchDirectoryIcon,
|
||||||
iconAlt: "switch directory button",
|
iconAlt: "switch directory button",
|
||||||
onCommandClick: () => this.openDirectoryPane(),
|
onCommandClick: () => this.openDirectoryPane(),
|
||||||
|
|
|
@ -4,8 +4,9 @@ import * as ViewModels from "../Contracts/ViewModels";
|
||||||
import { IPinnedRepo, JunoClient, IGalleryItem } from "./JunoClient";
|
import { IPinnedRepo, JunoClient, IGalleryItem } from "./JunoClient";
|
||||||
import { config } from "../Config";
|
import { config } from "../Config";
|
||||||
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||||
|
import { DatabaseAccount } from "../Contracts/DataModels";
|
||||||
|
|
||||||
const sampleDatabaseAccount: ViewModels.DatabaseAccount = {
|
const sampleDatabaseAccount: DatabaseAccount = {
|
||||||
id: "id",
|
id: "id",
|
||||||
name: "name",
|
name: "name",
|
||||||
location: "location",
|
location: "location",
|
||||||
|
@ -51,7 +52,7 @@ const sampleGalleryItems: IGalleryItem[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
describe("Pinned repos", () => {
|
describe("Pinned repos", () => {
|
||||||
const junoClient = new JunoClient(ko.observable<ViewModels.DatabaseAccount>(sampleDatabaseAccount));
|
const junoClient = new JunoClient(ko.observable<DatabaseAccount>(sampleDatabaseAccount));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
window.fetch = jest.fn().mockImplementation(() => {
|
window.fetch = jest.fn().mockImplementation(() => {
|
||||||
|
@ -88,7 +89,7 @@ describe("Pinned repos", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("GitHub", () => {
|
describe("GitHub", () => {
|
||||||
const junoClient = new JunoClient(ko.observable<ViewModels.DatabaseAccount>(sampleDatabaseAccount));
|
const junoClient = new JunoClient(ko.observable<DatabaseAccount>(sampleDatabaseAccount));
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
@ -147,7 +148,7 @@ describe("GitHub", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Gallery", () => {
|
describe("Gallery", () => {
|
||||||
const junoClient = new JunoClient(ko.observable<ViewModels.DatabaseAccount>(sampleDatabaseAccount));
|
const junoClient = new JunoClient(ko.observable<DatabaseAccount>(sampleDatabaseAccount));
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import { HttpStatusCodes } from "../Common/Constants";
|
import { HttpStatusCodes } from "../Common/Constants";
|
||||||
import { config } from "../Config";
|
import { config } from "../Config";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
|
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
|
||||||
import { IGitHubResponse } from "../GitHub/GitHubClient";
|
import { IGitHubResponse } from "../GitHub/GitHubClient";
|
||||||
import { IGitHubOAuthToken } from "../GitHub/GitHubOAuthService";
|
import { IGitHubOAuthToken } from "../GitHub/GitHubOAuthService";
|
||||||
|
@ -55,7 +55,7 @@ interface IPublishNotebookRequest {
|
||||||
export class JunoClient {
|
export class JunoClient {
|
||||||
private cachedPinnedRepos: ko.Observable<IPinnedRepo[]>;
|
private cachedPinnedRepos: ko.Observable<IPinnedRepo[]>;
|
||||||
|
|
||||||
constructor(private databaseAccount?: ko.Observable<ViewModels.DatabaseAccount>) {
|
constructor(private databaseAccount?: ko.Observable<DataModels.DatabaseAccount>) {
|
||||||
this.cachedPinnedRepos = ko.observable<IPinnedRepo[]>([]);
|
this.cachedPinnedRepos = ko.observable<IPinnedRepo[]>([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ export default class AuthHeadersUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _generateResourceUrl(): string {
|
private static _generateResourceUrl(): string {
|
||||||
const databaseAccount: ViewModels.DatabaseAccount = CosmosClient.databaseAccount();
|
const databaseAccount = CosmosClient.databaseAccount();
|
||||||
const subscriptionId: string = CosmosClient.subscriptionId();
|
const subscriptionId: string = CosmosClient.subscriptionId();
|
||||||
const resourceGroup: string = CosmosClient.resourceGroup();
|
const resourceGroup: string = CosmosClient.resourceGroup();
|
||||||
const defaultExperience: string = DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount);
|
const defaultExperience: string = DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount);
|
||||||
|
|
|
@ -4,6 +4,8 @@ import * as ViewModels from "../Contracts/ViewModels";
|
||||||
|
|
||||||
import crossroads from "crossroads";
|
import crossroads from "crossroads";
|
||||||
import hasher from "hasher";
|
import hasher from "hasher";
|
||||||
|
import ScriptTabBase from "../Explorer/Tabs/ScriptTabBase";
|
||||||
|
import TabsBase from "../Explorer/Tabs/TabsBase";
|
||||||
|
|
||||||
export class TabRouteHandler {
|
export class TabRouteHandler {
|
||||||
private _tabRouter: any;
|
private _tabRouter: any;
|
||||||
|
@ -187,7 +189,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.Query
|
ViewModels.CollectionTabKind.Query
|
||||||
|
@ -206,7 +208,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.Query
|
ViewModels.CollectionTabKind.Query
|
||||||
|
@ -228,7 +230,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.MongoShell
|
ViewModels.CollectionTabKind.MongoShell
|
||||||
|
@ -271,7 +273,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.StoredProcedures,
|
ViewModels.CollectionTabKind.StoredProcedures,
|
||||||
|
@ -302,7 +304,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.Triggers,
|
ViewModels.CollectionTabKind.Triggers,
|
||||||
|
@ -333,7 +335,7 @@ export class TabRouteHandler {
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId
|
collectionId
|
||||||
);
|
);
|
||||||
const matchingTab: ViewModels.Tab = this._findMatchingTabByTabKind(
|
const matchingTab: TabsBase = this._findMatchingTabByTabKind(
|
||||||
databaseId,
|
databaseId,
|
||||||
collectionId,
|
collectionId,
|
||||||
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
ViewModels.CollectionTabKind.UserDefinedFunctions,
|
||||||
|
@ -380,15 +382,15 @@ export class TabRouteHandler {
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
tabKind: ViewModels.CollectionTabKind,
|
tabKind: ViewModels.CollectionTabKind,
|
||||||
isNewScriptTab?: boolean
|
isNewScriptTab?: boolean
|
||||||
): ViewModels.Tab {
|
): TabsBase {
|
||||||
const explorer = window.dataExplorer;
|
const explorer = window.dataExplorer;
|
||||||
const matchingTabs: ViewModels.Tab[] = explorer.tabsManager.getTabs(
|
const matchingTabs: TabsBase[] = explorer.tabsManager.getTabs(
|
||||||
tabKind,
|
tabKind,
|
||||||
(tab: ViewModels.Tab) =>
|
(tab: TabsBase) =>
|
||||||
tab.collection &&
|
tab.collection &&
|
||||||
tab.collection.databaseId === databaseId &&
|
tab.collection.databaseId === databaseId &&
|
||||||
tab.collection.id() === collectionId &&
|
tab.collection.id() === collectionId &&
|
||||||
(!isNewScriptTab || (tab as ViewModels.ScriptTab).isNew())
|
(!isNewScriptTab || (tab as ScriptTabBase).isNew())
|
||||||
);
|
);
|
||||||
return matchingTabs && matchingTabs[0];
|
return matchingTabs && matchingTabs[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,12 +71,12 @@ describe("Default Experience Utility", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getDefaultExperienceFromDatabaseAccount()", () => {
|
describe("getDefaultExperienceFromDatabaseAccount()", () => {
|
||||||
function runScenario(databaseAccount: ViewModels.DatabaseAccount, expectedDefaultExperience: string): void {
|
function runScenario(databaseAccount: DataModels.DatabaseAccount, expectedDefaultExperience: string): void {
|
||||||
const resolvedExperience = DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount);
|
const resolvedExperience = DefaultExperienceUtility.getDefaultExperienceFromDatabaseAccount(databaseAccount);
|
||||||
expect(resolvedExperience).toEqual(expectedDefaultExperience);
|
expect(resolvedExperience).toEqual(expectedDefaultExperience);
|
||||||
}
|
}
|
||||||
|
|
||||||
const databaseAccountWithWrongTagsAndCapabilities: ViewModels.DatabaseAccount = {
|
const databaseAccountWithWrongTagsAndCapabilities: DataModels.DatabaseAccount = {
|
||||||
id: "test",
|
id: "test",
|
||||||
kind: "GlobalDocumentDB",
|
kind: "GlobalDocumentDB",
|
||||||
name: "test",
|
name: "test",
|
||||||
|
@ -99,7 +99,7 @@ describe("Default Experience Utility", () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const databaseAccountWithApiKind: ViewModels.DatabaseAccount = {
|
const databaseAccountWithApiKind: DataModels.DatabaseAccount = {
|
||||||
id: "test",
|
id: "test",
|
||||||
kind: Constants.AccountKind.MongoDB,
|
kind: Constants.AccountKind.MongoDB,
|
||||||
name: "test",
|
name: "test",
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import * as _ from "underscore";
|
import * as _ from "underscore";
|
||||||
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 * as ViewModels from "../Contracts/ViewModels";
|
|
||||||
|
|
||||||
export class DefaultExperienceUtility {
|
export class DefaultExperienceUtility {
|
||||||
public static getDefaultExperienceFromDatabaseAccount(databaseAccount: ViewModels.DatabaseAccount): string {
|
public static getDefaultExperienceFromDatabaseAccount(databaseAccount: DataModels.DatabaseAccount): string {
|
||||||
if (!databaseAccount) {
|
if (!databaseAccount) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const kind: string =
|
const kind: string =
|
||||||
databaseAccount && databaseAccount.kind && databaseAccount.kind && databaseAccount.kind.toLowerCase();
|
databaseAccount && databaseAccount.kind && databaseAccount.kind && databaseAccount.kind.toLowerCase();
|
||||||
const capabilities: ViewModels.Capability[] =
|
const capabilities = (databaseAccount.properties && databaseAccount.properties.capabilities) || [];
|
||||||
(databaseAccount.properties && databaseAccount.properties.capabilities) || [];
|
|
||||||
|
|
||||||
return DefaultExperienceUtility._getDefaultExperience(kind, capabilities);
|
return DefaultExperienceUtility._getDefaultExperience(kind, capabilities);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +59,7 @@ export class DefaultExperienceUtility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _getDefaultExperience(kind: string, capabilities: ViewModels.Capability[]): string {
|
private static _getDefaultExperience(kind: string, capabilities: DataModels.Capability[]): string {
|
||||||
const defaultDefaultExperience: string = Constants.DefaultAccountExperience.DocumentDB;
|
const defaultDefaultExperience: string = Constants.DefaultAccountExperience.DocumentDB;
|
||||||
const defaultExperienceFromKind: string = DefaultExperienceUtility._getDefaultExperienceFromAccountKind(kind);
|
const defaultExperienceFromKind: string = DefaultExperienceUtility._getDefaultExperienceFromAccountKind(kind);
|
||||||
const defaultExperienceFromCapabilities: string = DefaultExperienceUtility._getDefaultExperienceFromAccountCapabilities(
|
const defaultExperienceFromCapabilities: string = DefaultExperienceUtility._getDefaultExperienceFromAccountCapabilities(
|
||||||
|
@ -95,7 +93,7 @@ export class DefaultExperienceUtility {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _getDefaultExperienceFromAccountCapabilities(capabilities: ViewModels.Capability[]): string {
|
private static _getDefaultExperienceFromAccountCapabilities(capabilities: DataModels.Capability[]): string {
|
||||||
if (!capabilities) {
|
if (!capabilities) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -104,15 +102,12 @@ export class DefaultExperienceUtility {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const enableTable: ViewModels.Capability = DefaultExperienceUtility._findCapability(
|
const enableTable = DefaultExperienceUtility._findCapability(capabilities, Constants.CapabilityNames.EnableTable);
|
||||||
capabilities,
|
|
||||||
Constants.CapabilityNames.EnableTable
|
|
||||||
);
|
|
||||||
if (enableTable) {
|
if (enableTable) {
|
||||||
return Constants.DefaultAccountExperience.Table;
|
return Constants.DefaultAccountExperience.Table;
|
||||||
}
|
}
|
||||||
|
|
||||||
const enableGremlin: ViewModels.Capability = DefaultExperienceUtility._findCapability(
|
const enableGremlin = DefaultExperienceUtility._findCapability(
|
||||||
capabilities,
|
capabilities,
|
||||||
Constants.CapabilityNames.EnableGremlin
|
Constants.CapabilityNames.EnableGremlin
|
||||||
);
|
);
|
||||||
|
@ -120,7 +115,7 @@ export class DefaultExperienceUtility {
|
||||||
return Constants.DefaultAccountExperience.Graph;
|
return Constants.DefaultAccountExperience.Graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
const enableCassandra: ViewModels.Capability = DefaultExperienceUtility._findCapability(
|
const enableCassandra = DefaultExperienceUtility._findCapability(
|
||||||
capabilities,
|
capabilities,
|
||||||
Constants.CapabilityNames.EnableCassandra
|
Constants.CapabilityNames.EnableCassandra
|
||||||
);
|
);
|
||||||
|
@ -131,8 +126,8 @@ export class DefaultExperienceUtility {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _findCapability(capabilities: ViewModels.Capability[], capabilityName: string): ViewModels.Capability {
|
private static _findCapability(capabilities: DataModels.Capability[], capabilityName: string): DataModels.Capability {
|
||||||
return _.find(capabilities, (capability: ViewModels.Capability) => {
|
return _.find(capabilities, capability => {
|
||||||
return capability && capability.name && capability.name.toLowerCase() === capabilityName.toLowerCase();
|
return capability && capability.name && capability.name.toLowerCase() === capabilityName.toLowerCase();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
|
||||||
import { DatabaseAccountUtils } from "./DatabaseAccountUtils";
|
|
||||||
|
|
||||||
describe("DatabaseAccountUtils Tests", () => {
|
|
||||||
describe("mergeDatabaseAccountWithGateway", () => {
|
|
||||||
const databaseAccountWithProperties: ViewModels.DatabaseAccount = {
|
|
||||||
id: "test",
|
|
||||||
kind: "GlobalDocumentDB",
|
|
||||||
name: "test",
|
|
||||||
location: "somewhere",
|
|
||||||
type: "DocumentDB",
|
|
||||||
tags: [],
|
|
||||||
properties: {
|
|
||||||
documentEndpoint: "",
|
|
||||||
cassandraEndpoint: "",
|
|
||||||
gremlinEndpoint: "",
|
|
||||||
tableEndpoint: ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const databaseAccountWithLocations: ViewModels.DatabaseAccount = {
|
|
||||||
id: "test",
|
|
||||||
kind: "GlobalDocumentDB",
|
|
||||||
name: "test",
|
|
||||||
location: "somewhere",
|
|
||||||
type: "DocumentDB",
|
|
||||||
tags: [],
|
|
||||||
properties: {
|
|
||||||
documentEndpoint: "",
|
|
||||||
cassandraEndpoint: "",
|
|
||||||
gremlinEndpoint: "",
|
|
||||||
tableEndpoint: "",
|
|
||||||
enableMultipleWriteLocations: false,
|
|
||||||
readLocations: [
|
|
||||||
{
|
|
||||||
documentEndpoint: "https://centralus",
|
|
||||||
failoverPriority: 0,
|
|
||||||
id: "",
|
|
||||||
locationId: "",
|
|
||||||
locationName: "Central US",
|
|
||||||
provisioningState: "Succeeded"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
writeLocations: [
|
|
||||||
{
|
|
||||||
documentEndpoint: "https://centralus",
|
|
||||||
failoverPriority: 0,
|
|
||||||
id: "",
|
|
||||||
locationId: "",
|
|
||||||
locationName: "Central US",
|
|
||||||
provisioningState: "Succeeded"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const databaseAccountWithoutProperties: ViewModels.DatabaseAccount = {
|
|
||||||
id: "test",
|
|
||||||
kind: "GlobalDocumentDB",
|
|
||||||
name: "test",
|
|
||||||
location: "somewhere",
|
|
||||||
type: "DocumentDB",
|
|
||||||
tags: [],
|
|
||||||
properties: null
|
|
||||||
};
|
|
||||||
|
|
||||||
const gatewayDatabaseAccount: DataModels.GatewayDatabaseAccount = {
|
|
||||||
EnableMultipleWriteLocations: true,
|
|
||||||
CurrentMediaStorageUsageInMB: 0,
|
|
||||||
DatabasesLink: "",
|
|
||||||
MaxMediaStorageUsageInMB: 0,
|
|
||||||
MediaLink: "",
|
|
||||||
ReadableLocations: [
|
|
||||||
{
|
|
||||||
name: "Central US",
|
|
||||||
documentAccountEndpoint: "https://centralus"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "North Central US",
|
|
||||||
documentAccountEndpoint: "https://northcentralus"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
WritableLocations: [
|
|
||||||
{
|
|
||||||
name: "Central US",
|
|
||||||
documentAccountEndpoint: "https://centralus"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
it("should return databaseAccount when gatewayDatabaseAccount is not defined", () => {
|
|
||||||
expect(DatabaseAccountUtils.mergeDatabaseAccountWithGateway(databaseAccountWithoutProperties, null)).toBe(
|
|
||||||
databaseAccountWithoutProperties
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return null when databaseAccount is not defined", () => {
|
|
||||||
expect(DatabaseAccountUtils.mergeDatabaseAccountWithGateway(null, null)).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return merged with no properties when databaseAccount has no properties", () => {
|
|
||||||
const merged = DatabaseAccountUtils.mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccountWithoutProperties,
|
|
||||||
gatewayDatabaseAccount
|
|
||||||
);
|
|
||||||
expect(merged).toBeDefined();
|
|
||||||
expect(merged.properties).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return merged writableLocations", () => {
|
|
||||||
const merged = DatabaseAccountUtils.mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccountWithProperties,
|
|
||||||
gatewayDatabaseAccount
|
|
||||||
);
|
|
||||||
expect(merged.properties).toBeDefined();
|
|
||||||
expect(merged.properties.writeLocations).toBeDefined();
|
|
||||||
expect(merged.properties.writeLocations.length).toBe(gatewayDatabaseAccount.WritableLocations.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return merged readableLocations", () => {
|
|
||||||
const merged = DatabaseAccountUtils.mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccountWithProperties,
|
|
||||||
gatewayDatabaseAccount
|
|
||||||
);
|
|
||||||
expect(merged.properties).toBeDefined();
|
|
||||||
expect(merged.properties.readLocations).toBeDefined();
|
|
||||||
expect(merged.properties.readLocations.length).toBe(gatewayDatabaseAccount.ReadableLocations.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return merged enableMultipleWriteLocations", () => {
|
|
||||||
const merged = DatabaseAccountUtils.mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccountWithProperties,
|
|
||||||
gatewayDatabaseAccount
|
|
||||||
);
|
|
||||||
expect(merged.properties).toBeDefined();
|
|
||||||
expect(merged.properties.enableMultipleWriteLocations).toBe(gatewayDatabaseAccount.EnableMultipleWriteLocations);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not overwrite existing values", () => {
|
|
||||||
const merged = DatabaseAccountUtils.mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccountWithLocations,
|
|
||||||
gatewayDatabaseAccount
|
|
||||||
);
|
|
||||||
expect(merged.properties.enableMultipleWriteLocations).toBe(
|
|
||||||
databaseAccountWithLocations.properties.enableMultipleWriteLocations
|
|
||||||
);
|
|
||||||
expect(merged.properties.readLocations.length).toBe(databaseAccountWithLocations.properties.readLocations.length);
|
|
||||||
expect(merged.properties.writeLocations.length).toBe(
|
|
||||||
databaseAccountWithLocations.properties.writeLocations.length
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,53 +0,0 @@
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
|
||||||
import { StringUtils } from "./StringUtils";
|
|
||||||
|
|
||||||
export class DatabaseAccountUtils {
|
|
||||||
public static mergeDatabaseAccountWithGateway(
|
|
||||||
databaseAccount: ViewModels.DatabaseAccount,
|
|
||||||
gatewayDatabaseAccount: DataModels.GatewayDatabaseAccount
|
|
||||||
): ViewModels.DatabaseAccount {
|
|
||||||
if (!databaseAccount || !gatewayDatabaseAccount) {
|
|
||||||
return databaseAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (databaseAccount.properties && gatewayDatabaseAccount.EnableMultipleWriteLocations) {
|
|
||||||
databaseAccount.properties.enableMultipleWriteLocations = gatewayDatabaseAccount.EnableMultipleWriteLocations;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (databaseAccount.properties && !databaseAccount.properties.readLocations) {
|
|
||||||
databaseAccount.properties.readLocations = DatabaseAccountUtils._convertToDatabaseAccountResponseLocation(
|
|
||||||
gatewayDatabaseAccount.ReadableLocations
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (databaseAccount.properties && !databaseAccount.properties.writeLocations) {
|
|
||||||
databaseAccount.properties.writeLocations = DatabaseAccountUtils._convertToDatabaseAccountResponseLocation(
|
|
||||||
gatewayDatabaseAccount.WritableLocations
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return databaseAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _convertToDatabaseAccountResponseLocation(
|
|
||||||
gatewayLocations: DataModels.RegionEndpoint[]
|
|
||||||
): DataModels.DatabaseAccountResponseLocation[] {
|
|
||||||
if (!gatewayLocations) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gatewayLocations.map((gatewayLocation: DataModels.RegionEndpoint, index: number) => {
|
|
||||||
const responseLocation: DataModels.DatabaseAccountResponseLocation = {
|
|
||||||
documentEndpoint: gatewayLocation.documentAccountEndpoint,
|
|
||||||
locationName: gatewayLocation.name,
|
|
||||||
failoverPriority: index,
|
|
||||||
locationId: StringUtils.stripSpacesFromString(gatewayLocation.name).toLowerCase(),
|
|
||||||
provisioningState: "Succeeded",
|
|
||||||
id: gatewayLocation.name
|
|
||||||
};
|
|
||||||
|
|
||||||
return responseLocation;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,12 @@
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import { KernelConnectionMetadata } from "../Contracts/ViewModels";
|
|
||||||
import * as Logger from "../Common/Logger";
|
import * as Logger from "../Common/Logger";
|
||||||
|
|
||||||
|
interface KernelConnectionMetadata {
|
||||||
|
name: string;
|
||||||
|
configurationEndpoints: DataModels.NotebookConfigurationEndpoints;
|
||||||
|
notebookConnectionInfo: DataModels.NotebookWorkspaceConnectionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
export class NotebookConfigurationUtils {
|
export class NotebookConfigurationUtils {
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,6 @@
|
||||||
"./src/Explorer/Controls/ErrorDisplayComponent/ErrorDisplayComponent.ts",
|
"./src/Explorer/Controls/ErrorDisplayComponent/ErrorDisplayComponent.ts",
|
||||||
"./src/Explorer/Controls/GitHub/GitHubStyleConstants.ts",
|
"./src/Explorer/Controls/GitHub/GitHubStyleConstants.ts",
|
||||||
"./src/Explorer/Controls/SmartUi/InputUtils.ts",
|
"./src/Explorer/Controls/SmartUi/InputUtils.ts",
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarAction.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarDisplayable.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarDropDown.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarItem.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarSeperator.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/IToolbarToggle.ts",
|
|
||||||
"./src/Explorer/Controls/Toolbar/KeyCodes.ts",
|
|
||||||
"./src/Explorer/Notebook/FileSystemUtil.ts",
|
"./src/Explorer/Notebook/FileSystemUtil.ts",
|
||||||
"./src/Explorer/Notebook/NTeractUtil.ts",
|
"./src/Explorer/Notebook/NTeractUtil.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/actions.ts",
|
"./src/Explorer/Notebook/NotebookComponent/actions.ts",
|
||||||
|
|
Loading…
Reference in New Issue