Q removal: the easy parts

This commit is contained in:
Jordi Bunster 2020-11-16 03:26:08 -08:00
parent 94ff6b3e81
commit 6adfea03ab
40 changed files with 396 additions and 582 deletions

View File

@ -7,7 +7,6 @@ import {
Resource
} from "@azure/cosmos";
import { RequestOptions } from "@azure/cosmos/dist-esm";
import Q from "q";
import { configContext, Platform } from "../ConfigContext";
import * as DataModels from "../Contracts/DataModels";
import { MessageTypes } from "../Contracts/ExplorerContracts";
@ -39,18 +38,17 @@ export function getCommonQueryOptions(options: FeedOptions): any {
return options;
}
export function queryDocuments(
export async function queryDocuments(
databaseId: string,
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
): Promise<QueryIterator<ItemDefinition & Resource>> {
options = getCommonQueryOptions(options);
const documentsIterator = client()
return client()
.database(databaseId)
.container(containerId)
.items.query(query, options);
return Q(documentsIterator);
}
export function getPartitionKeyHeaderForConflict(conflictId: ConflictId): Object {
@ -76,17 +74,15 @@ export function updateDocument(
collection: ViewModels.CollectionBase,
documentId: DocumentId,
newDocument: any
): Q.Promise<any> {
): Promise<any> {
const partitionKey = documentId.partitionKeyValue;
return Q(
client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.replace(newDocument)
.then(response => response.resource)
);
return client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.replace(newDocument)
.then(response => response.resource);
}
export function executeStoredProcedure(
@ -94,105 +90,89 @@ export function executeStoredProcedure(
storedProcedure: StoredProcedure,
partitionKeyValue: any,
params: any[]
): Q.Promise<any> {
// TODO remove this deferred. Kept it because of timeout code at bottom of function
const deferred = Q.defer<any>();
client()
.database(collection.databaseId)
.container(collection.id())
.scripts.storedProcedure(storedProcedure.id())
.execute(partitionKeyValue, params, { enableScriptLogging: true })
.then(response =>
deferred.resolve({
): Promise<any> {
return Promise.race([
client()
.database(collection.databaseId)
.container(collection.id())
.scripts.storedProcedure(storedProcedure.id())
.execute(partitionKeyValue, params, { enableScriptLogging: true })
.then(response => ({
result: response.resource,
scriptLogs: response.headers[Constants.HttpHeaders.scriptLogResults]
})
})),
new Promise((_, reject) =>
setTimeout(
() => reject(`Request timed out while executing stored procedure ${storedProcedure.id()}`),
Constants.ClientDefaults.requestTimeoutMs
)
)
.catch(error => deferred.reject(error));
return deferred.promise.timeout(
Constants.ClientDefaults.requestTimeoutMs,
`Request timed out while executing stored procedure ${storedProcedure.id()}`
);
]);
}
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
return Q(
client()
.database(collection.databaseId)
.container(collection.id())
.items.create(newDocument)
.then(response => response.resource)
);
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Promise<any> {
return client()
.database(collection.databaseId)
.container(collection.id())
.items.create(newDocument)
.then(response => response.resource);
}
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Promise<any> {
const partitionKey = documentId.partitionKeyValue;
return Q(
client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.read()
.then(response => response.resource)
);
return client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.read()
.then(response => response.resource);
}
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Promise<any> {
const partitionKey = documentId.partitionKeyValue;
return Q(
client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.delete()
);
return client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), partitionKey)
.delete();
}
export function deleteConflict(
collection: ViewModels.CollectionBase,
conflictId: ConflictId,
options: any = {}
): Q.Promise<any> {
): Promise<any> {
options.partitionKey = options.partitionKey || getPartitionKeyHeaderForConflict(conflictId);
return Q(
client()
.database(collection.databaseId)
.container(collection.id())
.conflict(conflictId.id())
.delete(options)
);
return client()
.database(collection.databaseId)
.container(collection.id())
.conflict(conflictId.id())
.delete(options);
}
export function refreshCachedOffers(): Q.Promise<void> {
export async function refreshCachedOffers(): Promise<void> {
if (configContext.platform === Platform.Portal) {
return sendCachedDataMessage(MessageTypes.RefreshOffers, []);
} else {
return Q();
sendCachedDataMessage(MessageTypes.RefreshOffers, []);
}
}
export function refreshCachedResources(options?: any): Q.Promise<void> {
export async function refreshCachedResources(options?: any): Promise<void> {
if (configContext.platform === Platform.Portal) {
return sendCachedDataMessage(MessageTypes.RefreshResources, []);
} else {
return Q();
sendCachedDataMessage(MessageTypes.RefreshResources, []);
}
}
export function queryConflicts(
export async function queryConflicts(
databaseId: string,
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
const documentsIterator = client()
): Promise<QueryIterator<ConflictDefinition & Resource>> {
return client()
.database(databaseId)
.container(containerId)
.conflicts.query(query, options);
return Q(documentsIterator);
}

View File

@ -1,5 +1,4 @@
import { ConflictDefinition, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
import Q from "q";
import * as ViewModels from "../Contracts/ViewModels";
import ConflictId from "../Explorer/Tree/ConflictId";
import DocumentId from "../Explorer/Tree/DocumentId";
@ -16,7 +15,7 @@ export function queryDocuments(
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
): Promise<QueryIterator<ItemDefinition & Resource>> {
return DataAccessUtilityBase.queryDocuments(databaseId, containerId, query, options);
}
@ -25,7 +24,7 @@ export function queryConflicts(
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
): Promise<QueryIterator<ConflictDefinition & Resource>> {
return DataAccessUtilityBase.queryConflicts(databaseId, containerId, query, options);
}
@ -43,17 +42,15 @@ export function executeStoredProcedure(
storedProcedure: StoredProcedure,
partitionKeyValue: any,
params: any[]
): Q.Promise<any> {
var deferred = Q.defer<any>();
): Promise<any> {
const clearMessage = logConsoleProgress(`Executing stored procedure ${storedProcedure.id()}`);
DataAccessUtilityBase.executeStoredProcedure(collection, storedProcedure, partitionKeyValue, params)
return DataAccessUtilityBase.executeStoredProcedure(collection, storedProcedure, partitionKeyValue, params)
.then(
(response: any) => {
deferred.resolve(response);
logConsoleInfo(
`Finished executing stored procedure ${storedProcedure.id()} for container ${storedProcedure.collection.id()}`
);
return response;
},
(error: any) => {
handleError(
@ -61,14 +58,10 @@ export function executeStoredProcedure(
`Failed to execute stored procedure ${storedProcedure.id()} for container ${storedProcedure.collection.id()}`,
"ExecuteStoredProcedure"
);
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function queryDocumentsPage(
@ -76,150 +69,114 @@ export function queryDocumentsPage(
documentsIterator: MinimalQueryIterator,
firstItemIndex: number,
options: any
): Q.Promise<ViewModels.QueryResults> {
var deferred = Q.defer<ViewModels.QueryResults>();
): Promise<ViewModels.QueryResults> {
const entityName = getEntityName();
const clearMessage = logConsoleProgress(`Querying ${entityName} for container ${resourceName}`);
Q(nextPage(documentsIterator, firstItemIndex))
return nextPage(documentsIterator, firstItemIndex)
.then(
(result: ViewModels.QueryResults) => {
const itemCount = (result.documents && result.documents.length) || 0;
logConsoleInfo(`Successfully fetched ${itemCount} ${entityName} for container ${resourceName}`);
deferred.resolve(result);
return result;
},
(error: any) => {
handleError(error, `Failed to query ${entityName} for container ${resourceName}`, "QueryDocumentsPage");
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
var deferred = Q.defer<any>();
export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Promise<any> {
const entityName = getEntityName();
const clearMessage = logConsoleProgress(`Reading ${entityName} ${documentId.id()}`);
DataAccessUtilityBase.readDocument(collection, documentId)
.then(
(document: any) => {
deferred.resolve(document);
},
(error: any) => {
handleError(error, `Failed to read ${entityName} ${documentId.id()}`, "ReadDocument");
deferred.reject(error);
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
return DataAccessUtilityBase.readDocument(collection, documentId)
.catch((error: any) => {
handleError(error, `Failed to read ${entityName} ${documentId.id()}`, "ReadDocument");
throw error;
})
.finally(clearMessage);
}
export function updateDocument(
collection: ViewModels.CollectionBase,
documentId: DocumentId,
newDocument: any
): Q.Promise<any> {
var deferred = Q.defer<any>();
): Promise<any> {
const entityName = getEntityName();
const clearMessage = logConsoleProgress(`Updating ${entityName} ${documentId.id()}`);
DataAccessUtilityBase.updateDocument(collection, documentId, newDocument)
return DataAccessUtilityBase.updateDocument(collection, documentId, newDocument)
.then(
(updatedDocument: any) => {
logConsoleInfo(`Successfully updated ${entityName} ${documentId.id()}`);
deferred.resolve(updatedDocument);
return updatedDocument;
},
(error: any) => {
handleError(error, `Failed to update ${entityName} ${documentId.id()}`, "UpdateDocument");
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
var deferred = Q.defer<any>();
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Promise<any> {
const entityName = getEntityName();
const clearMessage = logConsoleProgress(`Creating new ${entityName} for container ${collection.id()}`);
DataAccessUtilityBase.createDocument(collection, newDocument)
return DataAccessUtilityBase.createDocument(collection, newDocument)
.then(
(savedDocument: any) => {
logConsoleInfo(`Successfully created new ${entityName} for container ${collection.id()}`);
deferred.resolve(savedDocument);
return savedDocument;
},
(error: any) => {
handleError(error, `Error while creating new ${entityName} for container ${collection.id()}`, "CreateDocument");
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise<any> {
var deferred = Q.defer<any>();
export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Promise<any> {
const entityName = getEntityName();
const clearMessage = logConsoleProgress(`Deleting ${entityName} ${documentId.id()}`);
DataAccessUtilityBase.deleteDocument(collection, documentId)
return DataAccessUtilityBase.deleteDocument(collection, documentId)
.then(
(response: any) => {
logConsoleInfo(`Successfully deleted ${entityName} ${documentId.id()}`);
deferred.resolve(response);
return response;
},
(error: any) => {
handleError(error, `Error while deleting ${entityName} ${documentId.id()}`, "DeleteDocument");
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function deleteConflict(
collection: ViewModels.CollectionBase,
conflictId: ConflictId,
options?: any
): Q.Promise<any> {
var deferred = Q.defer<any>();
): Promise<any> {
const clearMessage = logConsoleProgress(`Deleting conflict ${conflictId.id()}`);
DataAccessUtilityBase.deleteConflict(collection, conflictId, options)
return DataAccessUtilityBase.deleteConflict(collection, conflictId, options)
.then(
(response: any) => {
logConsoleInfo(`Successfully deleted conflict ${conflictId.id()}`);
deferred.resolve(response);
return response;
},
(error: any) => {
handleError(error, `Error while deleting conflict ${conflictId.id()}`, "DeleteConflict");
deferred.reject(error);
throw error;
}
)
.finally(() => {
clearMessage();
});
return deferred.promise;
.finally(clearMessage);
}
export function refreshCachedResources(options: any = {}): Q.Promise<void> {
export function refreshCachedResources(options: any = {}): Promise<void> {
return DataAccessUtilityBase.refreshCachedResources(options);
}
export function refreshCachedOffers(): Q.Promise<void> {
export function refreshCachedOffers(): Promise<void> {
return DataAccessUtilityBase.refreshCachedOffers();
}

View File

@ -136,7 +136,7 @@ export class QueriesClient {
return queryDocuments(SavedQueries.DatabaseName, SavedQueries.CollectionName, this.fetchQueriesQuery(), options)
.then(
(queryIterator: QueryIterator<ItemDefinition & Resource>) => {
const fetchQueries = (firstItemIndex: number): Q.Promise<ViewModels.QueryResults> =>
const fetchQueries = (firstItemIndex: number): Promise<ViewModels.QueryResults> =>
queryDocumentsPage(queriesCollection.id(), queryIterator, firstItemIndex, options);
return QueryUtils.queryAllPages(fetchQueries).then(
(results: ViewModels.QueryResults) => {

View File

@ -5,7 +5,6 @@ import {
TriggerDefinition,
UserDefinedFunctionDefinition
} from "@azure/cosmos";
import Q from "q";
import { CommandButtonComponentProps } from "../Explorer/Controls/CommandButton/CommandButtonComponent";
import Explorer from "../Explorer/Explorer";
import { ConsoleData } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
@ -107,7 +106,7 @@ export interface CollectionBase extends TreeNode {
onDocumentDBDocumentsClick(): void;
onNewQueryClick(source: any, event: MouseEvent, queryText?: string): void;
expandCollection(): Q.Promise<any>;
expandCollection(): Promise<any>;
collapseCollection(): void;
getDatabase(): Database;
}
@ -172,7 +171,7 @@ export interface Collection extends CollectionBase {
onDragOver(source: Collection, event: { originalEvent: DragEvent }): void;
onDrop(source: Collection, event: { originalEvent: DragEvent }): void;
uploadFiles(fileList: FileList): Q.Promise<UploadDetails>;
uploadFiles(fileList: FileList): Promise<UploadDetails>;
getLabel(): string;
}
@ -290,7 +289,7 @@ export interface DocumentsTabOptions extends TabOptions {
}
export interface SettingsTabV2Options extends TabOptions {
getPendingNotification: Q.Promise<DataModels.Notification>;
getPendingNotification: Promise<DataModels.Notification>;
}
export interface ConflictsTabOptions extends TabOptions {

View File

@ -57,7 +57,7 @@ class EditorViewModel extends JsonEditorViewModel {
}
}
protected getErrorMarkers(input: string): Q.Promise<monaco.editor.IMarkerData[]> {
protected async getErrorMarkers(input: string): Promise<monaco.editor.IMarkerData[]> {
return ErrorMarkProvider.getErrorMark(input);
}
}

View File

@ -1,4 +1,3 @@
import Q from "q";
import * as monaco from "monaco-editor";
import * as ViewModels from "../../../Contracts/ViewModels";
import { WaitsForTemplateViewModel } from "../../WaitsForTemplateViewModel";
@ -107,8 +106,8 @@ export class JsonEditorViewModel extends WaitsForTemplateViewModel {
protected registerCompletionItemProvider() {}
// Interface. Will be implemented in children editor view model such as EditorViewModel.
protected getErrorMarkers(input: string): Q.Promise<monaco.editor.IMarkerData[]> {
return Q.Promise(() => {});
protected getErrorMarkers(input: string): Promise<monaco.editor.IMarkerData[]> {
return new Promise(() => {});
}
protected getEditorLanguage(): string {

View File

@ -31,7 +31,6 @@ jest.mock("../../../Common/dataAccess/updateCollection", () => ({
}));
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
import { MongoDBCollectionResource } from "../../../Utils/arm/generatedClients/2020-04-01/types";
import Q from "q";
jest.mock("../../../Common/dataAccess/updateOffer", () => ({
updateOffer: jest.fn().mockReturnValue({} as DataModels.Offer)
}));
@ -47,9 +46,7 @@ describe("SettingsComponent", () => {
hashLocation: "settings",
isActive: ko.observable(false),
onUpdateTabsButtons: undefined,
getPendingNotification: Q.Promise<DataModels.Notification>(() => {
return;
})
getPendingNotification: Promise.resolve(undefined)
})
};

View File

@ -3,7 +3,6 @@ jest.mock("../Graph/GraphExplorerComponent/GremlinClient");
jest.mock("../../Common/dataAccess/createCollection");
import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import Q from "q";
import { ContainerSampleGenerator } from "./ContainerSampleGenerator";
import { createDocument } from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
@ -21,7 +20,7 @@ describe("ContainerSampleGenerator", () => {
explorerStub.canExceedMaximumValue = ko.computed<boolean>(() => false);
explorerStub.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
explorerStub.findDatabaseWithId = () => database;
explorerStub.refreshAllDatabases = () => Q.resolve();
explorerStub.refreshAllDatabases = () => Promise.resolve();
return explorerStub;
};

View File

@ -70,7 +70,7 @@ export class ContainerSampleGenerator {
if (!collection) {
throw new Error("No container to populate");
}
const promises: Q.Promise<any>[] = [];
const promises: Promise<any>[] = [];
if (this.container.isPreferredApiGraph()) {
// For Gremlin, all queries are executed sequentially, because some queries might be dependent on other queries

View File

@ -217,7 +217,7 @@ export default class Explorer {
public shouldShowShareDialogContents: ko.Observable<boolean>;
public shareAccessData: ko.Observable<AdHocAccessData>;
public renewExplorerShareAccess: (explorer: Explorer, token: string) => Q.Promise<void>;
public renewExplorerShareAccess: (explorer: Explorer, token: string) => Promise<void>;
public renewTokenError: ko.Observable<string>;
public tokenForRenewal: ko.Observable<string>;
public shareAccessToggleState: ko.Observable<ShareAccessToggleState>;
@ -1120,7 +1120,7 @@ export default class Explorer {
"Initiating connection to account"
);
this.renewExplorerShareAccess(this, this.tokenForRenewal())
.fail((error: any) => {
.catch((error: any) => {
const stringifiedError: string = error.message;
this.renewTokenError("Invalid connection string specified");
NotificationConsoleUtils.logConsoleMessage(
@ -1157,33 +1157,27 @@ export default class Explorer {
);
}
public renewShareAccess(token: string): Q.Promise<void> {
public async renewShareAccess(token: string): Promise<void> {
if (!this.renewExplorerShareAccess) {
return Q.reject("Not implemented");
throw "Not implemented";
}
const deferred: Q.Deferred<void> = Q.defer<void>();
const id: string = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
"Initiating connection to account"
);
this.renewExplorerShareAccess(this, token)
return this.renewExplorerShareAccess(this, token)
.then(
() => {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, "Connection successful");
this.renewAdHocAccessPane && this.renewAdHocAccessPane.close();
deferred.resolve();
},
(error: any) => {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${error.message}`);
deferred.reject(error);
throw error;
}
)
.finally(() => {
NotificationConsoleUtils.clearInProgressMessageWithId(id);
});
return deferred.promise;
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
}
public displayGuestAccessTokenRenewalPrompt(): void {
@ -1378,24 +1372,19 @@ export default class Explorer {
}
}
public refreshDatabaseForResourceToken(): Q.Promise<any> {
public async refreshDatabaseForResourceToken(): Promise<any> {
const databaseId = this.resourceTokenDatabaseId();
const collectionId = this.resourceTokenCollectionId();
if (!databaseId || !collectionId) {
return Q.reject();
throw new Error();
}
const deferred: Q.Deferred<void> = Q.defer();
readCollection(databaseId, collectionId).then((collection: DataModels.Collection) => {
this.resourceTokenCollection(new ResourceTokenCollection(this, databaseId, collection));
this.selectedNode(this.resourceTokenCollection());
deferred.resolve();
});
return deferred.promise;
const collection = await readCollection(databaseId, collectionId);
this.resourceTokenCollection(new ResourceTokenCollection(this, databaseId, collection));
this.selectedNode(this.resourceTokenCollection());
}
public refreshAllDatabases(isInitialLoad?: boolean): Q.Promise<any> {
public refreshAllDatabases(isInitialLoad?: boolean): Promise<any> {
this.isRefreshingExplorer(true);
const startKey: number = TelemetryProcessor.traceStart(Action.LoadDatabases, {
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
@ -1412,89 +1401,85 @@ export default class Explorer {
}
// TODO: Refactor
const deferred: Q.Deferred<any> = Q.defer();
this._setLoadingStatusText("Fetching databases...");
readDatabases().then(
(databases: DataModels.Database[]) => {
this._setLoadingStatusText("Successfully fetched databases.");
TelemetryProcessor.traceSuccess(
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree
},
startKey
);
const currentlySelectedNode: ViewModels.TreeNode = this.selectedNode();
const deltaDatabases = this.getDeltaDatabases(databases);
this.addDatabasesToList(deltaDatabases.toAdd);
this.deleteDatabasesFromList(deltaDatabases.toDelete);
this.selectedNode(currentlySelectedNode);
this._setLoadingStatusText("Fetching containers...");
this.refreshAndExpandNewDatabases(deltaDatabases.toAdd)
.then(
() => {
this._setLoadingStatusText("Successfully fetched containers.");
deferred.resolve();
},
reason => {
this._setLoadingStatusText("Failed to fetch containers.");
deferred.reject(reason);
}
)
.finally(() => this.isRefreshingExplorer(false));
},
error => {
this._setLoadingStatusText("Failed to fetch databases.");
this.isRefreshingExplorer(false);
deferred.reject(error);
TelemetryProcessor.traceFailure(
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree,
error: error.message
},
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while refreshing databases: ${error.message}`
);
}
);
return deferred.promise.then(
() => {
if (resourceTreeStartKey != null) {
return readDatabases()
.then(
(databases: DataModels.Database[]) => {
this._setLoadingStatusText("Successfully fetched databases.");
TelemetryProcessor.traceSuccess(
Action.LoadResourceTree,
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
defaultExperience: this.defaultExperience && this.defaultExperience(),
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree
},
resourceTreeStartKey
startKey
);
}
},
reason => {
if (resourceTreeStartKey != null) {
const currentlySelectedNode: ViewModels.TreeNode = this.selectedNode();
const deltaDatabases = this.getDeltaDatabases(databases);
this.addDatabasesToList(deltaDatabases.toAdd);
this.deleteDatabasesFromList(deltaDatabases.toDelete);
this.selectedNode(currentlySelectedNode);
this._setLoadingStatusText("Fetching containers...");
this.refreshAndExpandNewDatabases(deltaDatabases.toAdd)
.then(
() => this._setLoadingStatusText("Successfully fetched containers."),
reason => {
this._setLoadingStatusText("Failed to fetch containers.");
throw reason;
}
)
.finally(() => this.isRefreshingExplorer(false));
},
error => {
this._setLoadingStatusText("Failed to fetch databases.");
this.isRefreshingExplorer(false);
TelemetryProcessor.traceFailure(
Action.LoadResourceTree,
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
defaultExperience: this.defaultExperience && this.defaultExperience(),
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree,
error: reason
error: error.message
},
resourceTreeStartKey
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while refreshing databases: ${error.message}`
);
throw error;
}
}
);
)
.then(
() => {
if (resourceTreeStartKey != null) {
TelemetryProcessor.traceSuccess(
Action.LoadResourceTree,
{
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
defaultExperience: this.defaultExperience && this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree
},
resourceTreeStartKey
);
}
},
reason => {
if (resourceTreeStartKey != null) {
TelemetryProcessor.traceFailure(
Action.LoadResourceTree,
{
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
defaultExperience: this.defaultExperience && this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree,
error: reason
},
resourceTreeStartKey
);
}
}
);
}
public onRefreshDatabasesKeyPress = (source: any, event: KeyboardEvent): boolean => {
@ -1794,7 +1779,7 @@ export default class Explorer {
inputs.extensionEndpoint = configContext.PROXY_PATH;
}
const initPromise: Q.Promise<void> = inputs ? this.initDataExplorerWithFrameInputs(inputs) : Q();
const initPromise: Promise<void> = inputs ? this.initDataExplorerWithFrameInputs(inputs) : Promise.resolve();
initPromise.then(() => {
const openAction: ActionContracts.DataExplorerAction = message.openAction;
@ -1888,7 +1873,7 @@ export default class Explorer {
return false;
}
public initDataExplorerWithFrameInputs(inputs: ViewModels.DataExplorerInputsFrame): Q.Promise<void> {
public async initDataExplorerWithFrameInputs(inputs: ViewModels.DataExplorerInputsFrame): Promise<void> {
if (inputs != null) {
const authorizationToken = inputs.authorizationToken || "";
const masterKey = inputs.masterKey || "";
@ -1938,7 +1923,6 @@ export default class Explorer {
this.isAccountReady(true);
}
return Q();
}
public setFeatureFlagsFromFlights(flights: readonly string[]): void {
@ -2056,7 +2040,7 @@ export default class Explorer {
// we reload collections for all databases so the resource tree reflects any collection-level changes
// i.e addition of stored procedures, etc.
const deferred: Q.Deferred<void> = Q.defer<void>();
let loadCollectionPromises: Q.Promise<void>[] = [];
let loadCollectionPromises: Promise<void>[] = [];
// If the user has a lot of databases, only load expanded databases.
const databasesToLoad =
@ -2440,7 +2424,7 @@ export default class Explorer {
return true;
}
public renameNotebook(notebookFile: NotebookContentItem): Q.Promise<NotebookContentItem> {
public async renameNotebook(notebookFile: NotebookContentItem): Promise<NotebookContentItem> {
if (!this.isNotebookEnabled() || !this.notebookManager?.notebookContentClient) {
const error = "Attempt to rename notebook, but notebook is not enabled";
Logger.logError(error, "Explorer/renameNotebook");
@ -2457,39 +2441,35 @@ export default class Explorer {
);
if (openedNotebookTabs.length > 0) {
this.showOkModalDialog("Unable to rename file", "This file is being edited. Please close the tab and try again.");
return Q.reject();
throw new Error();
}
const originalPath = notebookFile.path;
const result = this.stringInputPane
.openWithOptions<NotebookContentItem>({
errorMessage: "Could not rename notebook",
inProgressMessage: "Renaming notebook to",
successMessage: "Renamed notebook to",
inputLabel: "Enter new notebook name",
paneTitle: "Rename Notebook",
submitButtonLabel: "Rename",
defaultInput: FileSystemUtil.stripExtension(notebookFile.name, "ipynb"),
onSubmit: (input: string) => this.notebookManager?.notebookContentClient.renameNotebook(notebookFile, input)
})
.then(newNotebookFile => {
const notebookTabs = this.tabsManager.getTabs(
ViewModels.CollectionTabKind.NotebookV2,
(tab: NotebookV2Tab) => tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), originalPath)
);
notebookTabs.forEach(tab => {
tab.tabTitle(newNotebookFile.name);
tab.tabPath(newNotebookFile.path);
(tab as NotebookV2Tab).notebookPath(newNotebookFile.path);
});
const newNotebookFile = await this.stringInputPane.openWithOptions<NotebookContentItem>({
errorMessage: "Could not rename notebook",
inProgressMessage: "Renaming notebook to",
successMessage: "Renamed notebook to",
inputLabel: "Enter new notebook name",
paneTitle: "Rename Notebook",
submitButtonLabel: "Rename",
defaultInput: FileSystemUtil.stripExtension(notebookFile.name, "ipynb"),
onSubmit: (input: string) => this.notebookManager?.notebookContentClient.renameNotebook(notebookFile, input)
});
const notebookTabs = this.tabsManager.getTabs(
ViewModels.CollectionTabKind.NotebookV2,
(tab: NotebookV2Tab) => tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), originalPath)
);
notebookTabs.forEach(tab => {
tab.tabTitle(newNotebookFile.name);
tab.tabPath(newNotebookFile.path);
(tab as NotebookV2Tab).notebookPath(newNotebookFile.path);
});
return newNotebookFile;
});
result.then(() => this.resourceTree.triggerRender());
return result;
this.resourceTree.triggerRender();
return newNotebookFile;
}
public onCreateDirectory(parent: NotebookContentItem): Q.Promise<NotebookContentItem> {
public async onCreateDirectory(parent: NotebookContentItem): Promise<NotebookContentItem> {
if (!this.isNotebookEnabled() || !this.notebookManager?.notebookContentClient) {
const error = "Attempt to create notebook directory, but notebook is not enabled";
Logger.logError(error, "Explorer/onCreateDirectory");
@ -2497,7 +2477,7 @@ export default class Explorer {
throw new Error(error);
}
const result = this.stringInputPane.openWithOptions<NotebookContentItem>({
const result = await this.stringInputPane.openWithOptions<NotebookContentItem>({
errorMessage: "Could not create directory ",
inProgressMessage: "Creating directory ",
successMessage: "Created directory ",
@ -2507,7 +2487,7 @@ export default class Explorer {
defaultInput: "",
onSubmit: (input: string) => this.notebookManager?.notebookContentClient.createDirectory(parent, input)
});
result.then(() => this.resourceTree.triggerRender());
this.resourceTree.triggerRender();
return result;
}

View File

@ -378,8 +378,7 @@ export class D3ForceGraph implements GraphRenderer {
* @param targetPosition
* @return promise with shift offset
*/
private shiftGraph(targetPosition: Point2D): Q.Promise<Point2D> {
const deferred: Q.Deferred<Point2D> = Q.defer<Point2D>();
private async shiftGraph(targetPosition: Point2D): Promise<Point2D> {
const offset = { x: this.width / 2 - targetPosition.x, y: this.height / 2 - targetPosition.y };
this.viewCenter = targetPosition;
@ -391,18 +390,15 @@ export class D3ForceGraph implements GraphRenderer {
.translate(-targetPosition.x, -targetPosition.y);
};
this.zoomBackground
const transition = this.zoomBackground
.transition()
.duration(D3ForceGraph.TRANSITION_STEP1_MS)
.call(this.zoom.transform, transform)
.on("end", () => {
deferred.resolve(offset);
});
} else {
deferred.resolve(null);
}
.call(this.zoom.transform, transform);
return deferred.promise;
await new Promise(resolve => transition.on("end", resolve));
return offset;
}
return null;
}
private onGraphDataUpdate(graph: GraphData<D3Node, D3Link>) {
@ -435,7 +431,7 @@ export class D3ForceGraph implements GraphRenderer {
}
}
private animateRemoveExitSelections(): Q.Promise<void> {
private animateRemoveExitSelections(): Promise<void> {
const deferred1 = Q.defer<void>();
const deferred2 = Q.defer<void>();
const linkExitSelection = this.linkSelection.exit();
@ -508,7 +504,7 @@ export class D3ForceGraph implements GraphRenderer {
deferred2.resolve();
}
return Q.allSettled([deferred1.promise, deferred2.promise]).then(undefined);
return Promise.all([deferred1.promise, deferred2.promise]).then(undefined);
}
/**

View File

@ -1,6 +1,5 @@
import React from "react";
import { mount, ReactWrapper } from "enzyme";
import * as Q from "q";
import { NodePropertiesComponent, NodePropertiesComponentProps, Mode } from "./NodePropertiesComponent";
import { GraphHighlightedNodeData, EditedProperties, EditedEdges, PossibleVertex } from "./GraphExplorer";
@ -41,11 +40,11 @@ describe("Property pane", () => {
node: highlightedNode,
getPkIdFromNodeData: (v: GraphHighlightedNodeData): string => null,
collectionPartitionKeyProperty: null,
updateVertexProperties: (editedProperties: EditedProperties): Q.Promise<void> => Q.resolve(),
updateVertexProperties: (editedProperties: EditedProperties): Promise<void> => Promise.resolve(),
selectNode: (id: string): void => {},
updatePossibleVertices: (): Q.Promise<PossibleVertex[]> => Q.resolve(null),
updatePossibleVertices: async (): Promise<PossibleVertex[]> => null,
possibleEdgeLabels: null,
editGraphEdges: (editedEdges: EditedEdges): Q.Promise<any> => Q.resolve(),
editGraphEdges: async (editedEdges: EditedEdges): Promise<any> => undefined,
deleteHighlightedNode: (): void => {},
onModeChanged: (newMode: Mode): void => {},
viewMode: Mode.READONLY_PROP

View File

@ -36,11 +36,11 @@ export interface NodePropertiesComponentProps {
node: GraphHighlightedNodeData;
getPkIdFromNodeData: (v: GraphHighlightedNodeData) => string;
collectionPartitionKeyProperty: string;
updateVertexProperties: (editedProperties: EditedProperties) => Q.Promise<void>;
updateVertexProperties: (editedProperties: EditedProperties) => Promise<void>;
selectNode: (id: string) => void;
updatePossibleVertices: () => Q.Promise<PossibleVertex[]>;
updatePossibleVertices: () => Promise<PossibleVertex[]>;
possibleEdgeLabels: Item[];
editGraphEdges: (editedEdges: EditedEdges) => Q.Promise<any>;
editGraphEdges: (editedEdges: EditedEdges) => Promise<any>;
deleteHighlightedNode: () => void;
onModeChanged: (newMode: Mode) => void;
viewMode: Mode; // If viewMode is specified in parent, keep state in sync with it

View File

@ -350,7 +350,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase {
}
this.isExecuting(true);
const autoPilotCommand = `cosmosdb_autoscale_max_throughput`;
let createTableAndKeyspacePromise: Q.Promise<any>;
let createTableAndKeyspacePromise: Promise<any>;
const toCreateKeyspace: boolean = this.keyspaceCreateNew();
const useAutoPilotForKeyspace: boolean =
(!this.hasAutoPilotV2FeatureFlag() && this.isSharedAutoPilotSelected() && !!this.sharedAutoPilotThroughput()) ||

View File

@ -1,7 +1,6 @@
jest.mock("../../Common/dataAccess/deleteCollection");
import * as ko from "knockout";
import * as sinon from "sinon";
import Q from "q";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
@ -58,7 +57,7 @@ describe("Delete Collection Confirmation Pane", () => {
it("should return true if last collection and database does not have shared throughput else false", () => {
let fakeExplorer = new Explorer();
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
fakeExplorer.refreshAllDatabases = () => Q.resolve();
fakeExplorer.refreshAllDatabases = () => Promise.resolve();
let pane = new DeleteCollectionConfirmationPane({
id: "deletecollectionconfirmationpane",
@ -119,7 +118,7 @@ describe("Delete Collection Confirmation Pane", () => {
fakeExplorer.selectedNode = ko.observable<TreeNode>();
fakeExplorer.isLastCollection = () => true;
fakeExplorer.isSelectedDatabaseShared = () => false;
fakeExplorer.refreshAllDatabases = () => Q.resolve();
fakeExplorer.refreshAllDatabases = () => Promise.resolve();
let pane = new DeleteCollectionConfirmationPane({
id: "deletecollectionconfirmationpane",

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as ViewModels from "../../Contracts/ViewModels";
import * as Constants from "../../Common/Constants";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";

View File

@ -1,7 +1,6 @@
jest.mock("../../Common/dataAccess/deleteDatabase");
jest.mock("../../Shared/Telemetry/TelemetryProcessor");
import * as ko from "knockout";
import Q from "q";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
@ -91,7 +90,7 @@ describe("Delete Database Confirmation Pane", () => {
collections: ko.observableArray<ViewModels.Collection>()
} as ViewModels.Database;
};
fakeExplorer.refreshAllDatabases = () => Q.resolve();
fakeExplorer.refreshAllDatabases = () => Promise.resolve();
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
fakeExplorer.selectedDatabaseId = ko.computed<string>(() => selectedDatabaseId);
fakeExplorer.isSelectedDatabaseShared = () => false;

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as Constants from "../../Common/Constants";
import * as ViewModels from "../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
@ -31,7 +30,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
this.resetData();
}
public submit(): Q.Promise<any> {
public async submit(): Promise<any> {
if (!this._isValid()) {
const selectedDatabase: ViewModels.Database = this.container.findSelectedDatabase();
this.formErrors("Input database name does not match the selected database");
@ -39,7 +38,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
ConsoleDataType.Error,
`Error while deleting collection ${selectedDatabase && selectedDatabase.id()}: ${this.formErrors()}`
);
return Q.resolve();
return;
}
this.formErrors("");
@ -53,7 +52,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
paneTitle: this.title()
});
// TODO: Should not be a Q promise anymore, but the Cassandra code requires it
let promise: Q.Promise<any>;
let promise: Promise<any>;
if (this.container.isPreferredApiCassandra()) {
promise = (<CassandraAPIDataClient>this.container.tableDataClient).deleteTableOrKeyspace(
this.container.databaseAccount().properties.cassandraEndpoint,
@ -62,7 +61,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
this.container
);
} else {
promise = Q(deleteDatabase(selectedDatabase.id()));
promise = deleteDatabase(selectedDatabase.id());
}
return promise.then(
() => {

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import * as Q from "q";
import * as Constants from "../../Common/Constants";
import * as ViewModels from "../../Contracts/ViewModels";
import { ContextualPaneBase } from "./ContextualPaneBase";
@ -97,33 +96,30 @@ export class LoadQueryPane extends ContextualPaneBase {
return true;
};
public loadQueryFromFile(file: File): Q.Promise<void> {
public async loadQueryFromFile(file: File): Promise<void> {
const selectedCollection: ViewModels.Collection = this.container && this.container.findSelectedCollection();
if (!selectedCollection) {
// should never get into this state
Logger.logError("No collection was selected", "LoadQueryPane.loadQueryFromFile");
return Q.reject("No collection was selected");
throw new Error("No collection was selected");
} else if (this.container.isPreferredApiMongoDB()) {
selectedCollection.onNewMongoQueryClick(selectedCollection, null);
} else {
selectedCollection.onNewQueryClick(selectedCollection, null);
}
const deferred: Q.Deferred<void> = Q.defer<void>();
const reader = new FileReader();
reader.onload = (evt: any): void => {
const fileData: string = evt.target.result;
const queryTab = this.container.tabsManager.activeTab() as QueryTab;
queryTab.initialEditorContent(fileData);
queryTab.sqlQueryEditorContent(fileData);
deferred.resolve();
};
reader.onerror = (evt: ProgressEvent): void => {
deferred.reject((evt as any).error.message);
throw new Error((evt as any).error.message);
};
reader.readAsText(file);
return deferred.promise;
}
private updateSelectedFilesTitle(fileList: FileList) {

View File

@ -1,5 +1,4 @@
import _ from "underscore";
import Q from "q";
import * as Entities from "../Entities";
import * as QueryBuilderConstants from "../Constants";
@ -84,11 +83,11 @@ export function filterColumns(table: DataTables.DataTable, settings: boolean[]):
* Reorder columns based on current order.
* If no current order is specified, reorder the columns based on intial order.
*/
export function reorderColumns(
export async function reorderColumns(
table: DataTables.DataTable,
targetOrder: number[],
currentOrder?: number[]
): Q.Promise<any> {
): Promise<any> {
var columnsCount: number = targetOrder.length;
var isCurrentOrderPassedIn: boolean = !!currentOrder;
if (!isCurrentOrderPassedIn) {
@ -107,13 +106,9 @@ export function reorderColumns(
var transformationOrder: number[] = isCurrentOrderPassedIn
? calculateTransformationOrder(currentOrder, targetOrder)
: targetOrder;
try {
$.fn.dataTable.ColReorder(table).fnOrder(transformationOrder);
} catch (err) {
return Q.reject(err);
}
$.fn.dataTable.ColReorder(table).fnOrder(transformationOrder);
}
return Q.resolve(null);
return null;
}
export function resetColumns(table: DataTables.DataTable): void {

View File

@ -1,5 +1,4 @@
import _ from "underscore";
import Q from "q";
import * as DataTableUtilities from "./DataTableUtilities";
import * as DataTableOperations from "./DataTableOperations";
import TableEntityListViewModel from "./TableEntityListViewModel";
@ -49,7 +48,7 @@ export default class TableCommands {
/**
* Edit entity
*/
public editEntityCommand(viewModel: TableEntityListViewModel): Q.Promise<any> {
public editEntityCommand(viewModel: TableEntityListViewModel): Promise<any> {
if (!viewModel) {
return null; // Error
}
@ -68,7 +67,7 @@ export default class TableCommands {
return null;
}
public deleteEntitiesCommand(viewModel: TableEntityListViewModel): Q.Promise<any> {
public deleteEntitiesCommand(viewModel: TableEntityListViewModel): Promise<any> {
if (!viewModel) {
return null; // Error
}
@ -92,7 +91,7 @@ export default class TableCommands {
return null;
}
public customizeColumnsCommand(viewModel: TableEntityListViewModel): Q.Promise<any> {
public customizeColumnsCommand(viewModel: TableEntityListViewModel): Promise<any> {
var table: DataTables.DataTable = viewModel.table;
var displayedColumnNames: string[] = DataTableOperations.getDataTableHeaders(table);
var columnsCount: number = displayedColumnNames.length;
@ -120,7 +119,7 @@ export default class TableCommands {
return null;
}
public reorderColumnsBasedOnSelectedEntities(viewModel: TableEntityListViewModel): Q.Promise<boolean> {
public reorderColumnsBasedOnSelectedEntities(viewModel: TableEntityListViewModel): Promise<boolean> {
var selected = viewModel.selected();
if (!selected || !selected.length) {
return null;

View File

@ -1,5 +1,4 @@
import * as _ from "underscore";
import Q from "q";
import * as Entities from "./Entities";
import { CassandraTableKey } from "./TableDataClient";
import * as Constants from "./Constants";
@ -19,8 +18,8 @@ export function guid() {
/**
* Returns a promise that resolves in the specified number of milliseconds.
*/
export function delay(milliseconds: number): Q.Promise<any> {
return Q.delay(milliseconds);
export function delay(milliseconds: number): Promise<any> {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
/**

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
@ -225,7 +224,7 @@ export default class ConflictsTab extends TabsBase {
});
}
public refreshDocumentsGrid(): Q.Promise<any> {
public refreshDocumentsGrid(): Promise<any> {
// clear documents grid
this.conflictIds([]);
return this.createIterator()
@ -256,19 +255,17 @@ export default class ConflictsTab extends TabsBase {
return true;
};
public onConflictIdClick(clickedDocumentId: ConflictId): Q.Promise<any> {
public async onConflictIdClick(clickedDocumentId: ConflictId): Promise<any> {
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
return Q();
return;
}
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
return Q();
}
public onAcceptChangesClick = (): Q.Promise<any> => {
public onAcceptChangesClick = async (): Promise<any> => {
if (this.isEditorDirty() && !this._isIgnoreDirtyEditor()) {
return Q();
return;
}
this.isExecutionError(false);
@ -286,7 +283,7 @@ export default class ConflictsTab extends TabsBase {
conflictResourceId: selectedConflict.resourceId
});
let operationPromise: Q.Promise<any> = Q();
let operationPromise: Promise<any>;
if (selectedConflict.operationType === Constants.ConflictOperationType.Replace) {
const documentContent = JSON.parse(this.selectedConflictContent());
@ -358,7 +355,7 @@ export default class ConflictsTab extends TabsBase {
.finally(() => this.isExecuting(false));
};
public onDeleteClick = (): Q.Promise<any> => {
public onDeleteClick = (): Promise<any> => {
this.isExecutionError(false);
this.isExecuting(true);
@ -418,40 +415,34 @@ export default class ConflictsTab extends TabsBase {
.finally(() => this.isExecuting(false));
};
public onDiscardClick = (): Q.Promise<any> => {
public onDiscardClick = async (): Promise<any> => {
this.selectedConflictContent(this.selectedConflictContent.getEditableOriginalValue());
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
return Q();
};
public onValidDocumentEdit(): Q.Promise<any> {
public async onValidDocumentEdit(): Promise<any> {
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid);
return Q();
}
public onInvalidDocumentEdit(): Q.Promise<any> {
public async onInvalidDocumentEdit(): Promise<any> {
if (
this.editorState() === ViewModels.DocumentExplorerState.exisitingDocumentNoEdits ||
this.editorState() === ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid
) {
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid);
return Q();
}
return Q();
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
this.collection && this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Conflicts);
});
}
public onActivate(): Q.Promise<any> {
public onActivate(): Promise<any> {
return super.onActivate().then(() => {
if (this._documentsIterator) {
return Q.resolve(this._documentsIterator);
return this._documentsIterator;
}
return this.createIterator().then(
@ -481,7 +472,7 @@ export default class ConflictsTab extends TabsBase {
});
}
public onRefreshClick(): Q.Promise<any> {
public onRefreshClick(): Promise<any> {
return this.refreshDocumentsGrid().then(() => {
this.selectedConflictContent("");
this.selectedConflictId(null);
@ -489,7 +480,7 @@ export default class ConflictsTab extends TabsBase {
});
}
public createIterator(): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
public createIterator(): Promise<QueryIterator<ConflictDefinition & Resource>> {
// TODO: Conflict Feed does not allow filtering atm
const query: string = undefined;
let options: any = {};
@ -497,7 +488,7 @@ export default class ConflictsTab extends TabsBase {
return queryConflicts(this.collection.databaseId, this.collection.id(), query, options);
}
public loadNextPage(): Q.Promise<any> {
public loadNextPage(): Promise<any> {
this.isExecuting(true);
this.isExecutionError(false);
return this._loadNextPageInternal()
@ -564,8 +555,8 @@ export default class ConflictsTab extends TabsBase {
}
};
protected _loadNextPageInternal(): Q.Promise<DataModels.ConflictId[]> {
return Q(this._documentsIterator.fetchNext().then(response => response.resources));
protected _loadNextPageInternal(): Promise<DataModels.ConflictId[]> {
return this._documentsIterator.fetchNext().then(response => response.resources);
}
protected _onEditorContentChange(newContent: string) {
@ -577,22 +568,20 @@ export default class ConflictsTab extends TabsBase {
}
}
public initDocumentEditorForCreate(documentId: ConflictId, documentToInsert: any): Q.Promise<any> {
public async initDocumentEditorForCreate(documentId: ConflictId, documentToInsert: any): Promise<any> {
if (documentId) {
let parsedConflictContent: any = JSON.parse(documentToInsert);
const renderedConflictContent: string = this.renderObjectForEditor(parsedConflictContent, null, 4);
this.selectedConflictContent.setBaseline(renderedConflictContent);
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
}
return Q();
}
public initDocumentEditorForReplace(
public async initDocumentEditorForReplace(
documentId: ConflictId,
conflictContent: any,
currentContent: any
): Q.Promise<any> {
): Promise<any> {
if (documentId) {
currentContent = ConflictsTab.removeSystemProperties(currentContent);
const renderedCurrentContent: string = this.renderObjectForEditor(currentContent, null, 4);
@ -605,11 +594,9 @@ export default class ConflictsTab extends TabsBase {
this.selectedConflictContent.setBaseline(renderedConflictContent);
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
}
return Q();
}
public initDocumentEditorForDelete(documentId: ConflictId, documentToDelete: any): Q.Promise<any> {
public async initDocumentEditorForDelete(documentId: ConflictId, documentToDelete: any): Promise<any> {
if (documentId) {
let parsedDocumentToDelete: any = JSON.parse(documentToDelete);
parsedDocumentToDelete = ConflictsTab.removeSystemProperties(parsedDocumentToDelete);
@ -617,15 +604,12 @@ export default class ConflictsTab extends TabsBase {
this.selectedConflictContent.setBaseline(renderedDocumentToDelete);
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
}
return Q();
}
public initDocumentEditorForNoOp(documentId: ConflictId): Q.Promise<any> {
public async initDocumentEditorForNoOp(documentId: ConflictId): Promise<any> {
this.selectedConflictContent(null);
this.selectedConflictCurrent(null);
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
return Q();
}
protected getTabsButtons(): CommandButtonComponentProps[] {

View File

@ -8,7 +8,6 @@ import * as SharedConstants from "../../Shared/Constants";
import * as ViewModels from "../../Contracts/ViewModels";
import DiscardIcon from "../../../images/discard.svg";
import editable from "../../Common/EditableUtility";
import Q from "q";
import SaveIcon from "../../../images/save-cosmos.svg";
import TabsBase from "./TabsBase";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
@ -22,12 +21,12 @@ import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/update
import { configContext, Platform } from "../../ConfigContext";
const updateThroughputBeyondLimitWarningMessage: string = `
You are about to request an increase in throughput beyond the pre-allocated capacity.
The service will scale out and increase throughput for the selected database.
You are about to request an increase in throughput beyond the pre-allocated capacity.
The service will scale out and increase throughput for the selected database.
This operation will take 1-3 business days to complete. You can track the status of this request in Notifications.`;
const updateThroughputDelayedApplyWarningMessage: 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.
This operation will take some time to complete.`;
const currentThroughput: (isAutoscale: boolean, throughput: number) => string = (isAutoscale, throughput) =>
@ -36,17 +35,17 @@ const currentThroughput: (isAutoscale: boolean, throughput: number) => string =
: `Current manual throughput: ${throughput} RU/s`;
const throughputApplyDelayedMessage = (isAutoscale: boolean, throughput: number, databaseName: string) =>
`The request to increase the throughput has successfully been submitted.
`The request to increase the throughput has successfully been submitted.
This operation will take 1-3 business days to complete. View the latest status in Notifications.<br />
Database: ${databaseName}, ${currentThroughput(isAutoscale, throughput)}`;
const throughputApplyShortDelayMessage = (isAutoscale: boolean, throughput: number, databaseName: string) =>
`A request to increase the throughput is currently in progress.
`A request to increase the throughput is currently in progress.
This operation will take some time to complete.<br />
Database: ${databaseName}, ${currentThroughput(isAutoscale, throughput)}`;
const throughputApplyLongDelayMessage = (isAutoscale: boolean, throughput: number, databaseName: string) =>
`A request to increase the throughput is currently in progress.
`A request to increase the throughput is currently in progress.
This operation will take 1-3 business days to complete. View the latest status in Notifications.<br />
Database: ${databaseName}, ${currentThroughput(isAutoscale, throughput)}`;
@ -544,7 +543,7 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
}
};
public onRevertClick = (): Q.Promise<any> => {
public onRevertClick = async (): Promise<any> => {
this.throughput.setBaseline(this.throughput.getEditableOriginalValue());
this.isAutoPilotSelected.setBaseline(this.isAutoPilotSelected.getEditableOriginalValue());
if (!this.hasAutoPilotV2FeatureFlag()) {
@ -552,11 +551,9 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
} else {
this.selectedAutoPilotTier.setBaseline(this.selectedAutoPilotTier.getEditableOriginalValue());
}
return Q();
};
public onActivate(): Q.Promise<any> {
public onActivate(): Promise<any> {
return super.onActivate().then(async () => {
this.database.selectedSubnodeKind(ViewModels.CollectionTabKind.DatabaseSettings);
await this.database.loadOffer();

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
@ -340,24 +339,21 @@ export default class DocumentsTab extends TabsBase {
return true;
}
public onShowFilterClick(): Q.Promise<any> {
public async onShowFilterClick(): Promise<any> {
this.isFilterCreated(true);
this.isFilterExpanded(true);
$(".filterDocExpanded").addClass("active");
$("#content").addClass("active");
$(".querydropdown").focus();
return Q();
}
public onHideFilterClick(): Q.Promise<any> {
public async onHideFilterClick(): Promise<any> {
this.isFilterExpanded(false);
$(".filterDocExpanded").removeClass("active");
$("#content").removeClass("active");
$(".queryButton").focus();
return Q();
}
public onCloseButtonKeyDown = (source: any, event: KeyboardEvent): boolean => {
@ -369,7 +365,7 @@ export default class DocumentsTab extends TabsBase {
return true;
};
public onApplyFilterClick(): Q.Promise<any> {
public onApplyFilterClick(): Promise<any> {
// clear documents grid
this.documentIds([]);
return this.createIterator()
@ -398,7 +394,7 @@ export default class DocumentsTab extends TabsBase {
});
}
public refreshDocumentsGrid(): Q.Promise<any> {
public refreshDocumentsGrid(): Promise<any> {
return this.onApplyFilterClick();
}
@ -411,19 +407,17 @@ export default class DocumentsTab extends TabsBase {
return true;
};
public onDocumentIdClick(clickedDocumentId: DocumentId): Q.Promise<any> {
public async onDocumentIdClick(clickedDocumentId: DocumentId): Promise<any> {
if (this.editorState() !== ViewModels.DocumentExplorerState.noDocumentSelected) {
return Q();
return;
}
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
return Q();
}
public onNewDocumentClick = (): Q.Promise<any> => {
public onNewDocumentClick = async (): Promise<any> => {
if (this.isEditorDirty() && !this._isIgnoreDirtyEditor()) {
return Q();
return;
}
this.selectedDocumentId(null);
@ -431,11 +425,9 @@ export default class DocumentsTab extends TabsBase {
this.initialDocumentContent(defaultDocument);
this.selectedDocumentContent.setBaseline(defaultDocument);
this.editorState(ViewModels.DocumentExplorerState.newDocumentValid);
return Q();
};
public onSaveNewDocumentClick = (): Q.Promise<any> => {
public onSaveNewDocumentClick = (): Promise<any> => {
this.isExecutionError(false);
const startKey: number = TelemetryProcessor.traceStart(Action.CreateDocument, {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
@ -493,15 +485,13 @@ export default class DocumentsTab extends TabsBase {
.finally(() => this.isExecuting(false));
};
public onRevertNewDocumentClick = (): Q.Promise<any> => {
public onRevertNewDocumentClick = async (): Promise<any> => {
this.initialDocumentContent("");
this.selectedDocumentContent("");
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
return Q();
};
public onSaveExisitingDocumentClick = (): Q.Promise<any> => {
public onSaveExisitingDocumentClick = (): Promise<any> => {
const selectedDocumentId = this.selectedDocumentId();
const documentContent = JSON.parse(this.selectedDocumentContent());
@ -560,15 +550,13 @@ export default class DocumentsTab extends TabsBase {
.finally(() => this.isExecuting(false));
};
public onRevertExisitingDocumentClick = (): Q.Promise<any> => {
public onRevertExisitingDocumentClick = async (): Promise<any> => {
this.selectedDocumentContent.setBaseline(this.initialDocumentContent());
this.initialDocumentContent.valueHasMutated();
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
return Q();
};
public onDeleteExisitingDocumentClick = (): Q.Promise<any> => {
public onDeleteExisitingDocumentClick = async (): Promise<any> => {
const selectedDocumentId = this.selectedDocumentId();
const msg = !this.isPreferredApiMongoDB
? "Are you sure you want to delete the selected item ?"
@ -577,30 +565,27 @@ export default class DocumentsTab extends TabsBase {
if (window.confirm(msg)) {
return this._deleteDocument(selectedDocumentId);
}
return Q();
};
public onValidDocumentEdit(): Q.Promise<any> {
public async onValidDocumentEdit(): Promise<any> {
if (
this.editorState() === ViewModels.DocumentExplorerState.newDocumentInvalid ||
this.editorState() === ViewModels.DocumentExplorerState.newDocumentValid
) {
this.editorState(ViewModels.DocumentExplorerState.newDocumentValid);
return Q();
return;
}
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid);
return Q();
}
public onInvalidDocumentEdit(): Q.Promise<any> {
public async onInvalidDocumentEdit(): Promise<any> {
if (
this.editorState() === ViewModels.DocumentExplorerState.newDocumentInvalid ||
this.editorState() === ViewModels.DocumentExplorerState.newDocumentValid
) {
this.editorState(ViewModels.DocumentExplorerState.newDocumentInvalid);
return Q();
return;
}
if (
@ -608,22 +593,20 @@ export default class DocumentsTab extends TabsBase {
this.editorState() === ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid
) {
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid);
return Q();
return;
}
return Q();
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
this.collection && this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Documents);
});
}
public onActivate(): Q.Promise<any> {
public onActivate(): Promise<any> {
return super.onActivate().then(() => {
if (this._documentsIterator) {
return Q.resolve(this._documentsIterator);
return this._documentsIterator;
}
return this.createIterator().then(
@ -653,7 +636,7 @@ export default class DocumentsTab extends TabsBase {
});
}
public onRefreshClick(): Q.Promise<any> {
public onRefreshClick(): Promise<any> {
return this.refreshDocumentsGrid().then(() => {
this.selectedDocumentContent("");
this.selectedDocumentId(null);
@ -665,11 +648,11 @@ export default class DocumentsTab extends TabsBase {
return window.confirm(msg);
};
protected __deleteDocument(documentId: DocumentId): Q.Promise<any> {
protected __deleteDocument(documentId: DocumentId): Promise<any> {
return deleteDocument(this.collection, documentId);
}
private _deleteDocument(selectedDocumentId: DocumentId): Q.Promise<any> {
private _deleteDocument(selectedDocumentId: DocumentId): Promise<any> {
this.isExecutionError(false);
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocument, {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
@ -714,7 +697,7 @@ export default class DocumentsTab extends TabsBase {
.finally(() => this.isExecuting(false));
}
public createIterator(): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
public createIterator(): Promise<QueryIterator<ItemDefinition & Resource>> {
let filters = this.lastFilterContents();
const filter: string = this.filterContent().trim();
const query: string = this.buildQuery(filter);
@ -728,14 +711,14 @@ export default class DocumentsTab extends TabsBase {
return queryDocuments(this.collection.databaseId, this.collection.id(), query, options);
}
public selectDocument(documentId: DocumentId): Q.Promise<any> {
public selectDocument(documentId: DocumentId): Promise<any> {
this.selectedDocumentId(documentId);
return readDocument(this.collection, documentId).then((content: any) => {
this.initDocumentEditor(documentId, content);
});
}
public loadNextPage(): Q.Promise<any> {
public loadNextPage(): Promise<any> {
this.isExecuting(true);
this.isExecutionError(false);
return this._loadNextPageInternal()
@ -809,8 +792,8 @@ export default class DocumentsTab extends TabsBase {
}
};
protected _loadNextPageInternal(): Q.Promise<DataModels.DocumentId[]> {
return Q(this._documentsIterator.fetchNext().then(response => response.resources));
protected _loadNextPageInternal(): Promise<DataModels.DocumentId[]> {
return this._documentsIterator.fetchNext().then(response => response.resources);
}
protected _onEditorContentChange(newContent: string) {
@ -822,7 +805,7 @@ export default class DocumentsTab extends TabsBase {
}
}
public initDocumentEditor(documentId: DocumentId, documentContent: any): Q.Promise<any> {
public async initDocumentEditor(documentId: DocumentId, documentContent: any): Promise<any> {
if (documentId) {
const content: string = this.renderObjectForEditor(documentContent, null, 4);
this.selectedDocumentContent.setBaseline(content);
@ -832,8 +815,6 @@ export default class DocumentsTab extends TabsBase {
: ViewModels.DocumentExplorerState.newDocumentValid;
this.editorState(newState);
}
return Q();
}
public buildQuery(filter: string): string {

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import * as Q from "q";
import * as ViewModels from "../../Contracts/ViewModels";
import TabsBase from "./TabsBase";
import { GraphExplorerAdapter } from "../Graph/GraphExplorerComponent/GraphExplorerAdapter";
@ -114,7 +113,7 @@ export default class GraphTab extends TabsBase {
: `${account.name}.graphs.azure.com:443/`;
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Graph);
});

View File

@ -1,5 +1,4 @@
import * as ViewModels from "../../Contracts/ViewModels";
import Q from "q";
import MongoUtility from "../../Common/MongoUtility";
import QueryTab from "./QueryTab";
import * as HeadersUtility from "../../Common/HeadersUtility";
@ -20,10 +19,10 @@ export default class MongoQueryTab extends QueryTab {
return MongoUtility.tojson(value, null, false);
}
protected _initIterator(): Q.Promise<MinimalQueryIterator> {
protected async _initIterator(): Promise<MinimalQueryIterator> {
let options: any = {};
options.enableCrossPartitionQuery = HeadersUtility.shouldEnableCrossPartitionKey();
this._iterator = queryIterator(this.collection.databaseId, this.collection, this.sqlStatementToExecute());
return Q(this._iterator);
return this._iterator;
}
}

View File

@ -3,7 +3,6 @@ import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import AuthHeadersUtil from "../../Platform/Hosted/Authorization";
import { isInvalidParentFrameOrigin } from "../../Utils/MessageValidation";
import Q from "q";
import TabsBase from "./TabsBase";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
@ -53,7 +52,7 @@ export default class MongoShellTab extends TabsBase {
// }
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Documents);
});

View File

@ -1,5 +1,4 @@
import * as _ from "underscore";
import * as Q from "q";
import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
@ -84,7 +83,7 @@ export default class NotebookTabV2 extends TabsBase {
});
}
public onCloseTabButtonClick(): Q.Promise<any> {
public async onCloseTabButtonClick(): Promise<any> {
const cleanup = () => {
this.notebookComponentAdapter.notebookShutdown();
this.isActive(false);
@ -100,11 +99,11 @@ export default class NotebookTabV2 extends TabsBase {
"Cancel",
undefined
);
return Q.resolve(null);
} else {
cleanup();
return Q.resolve(null);
}
return null;
}
public async reconfigureServiceEndpoints() {

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
@ -163,13 +162,13 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
this._buildCommandBarOptions();
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
this.collection && this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Query);
});
}
public onExecuteQueryClick = (): Q.Promise<any> => {
public onExecuteQueryClick = (): Promise<any> => {
const sqlStatement: string = this.selectedContent() || this.sqlQueryEditorContent();
this.sqlStatementToExecute(sqlStatement);
this.allResultsMetadata([]);
@ -191,7 +190,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
this.collection && this.collection.container && this.collection.container.browseQueriesPane.open();
};
public onFetchNextPageClick(): Q.Promise<any> {
public onFetchNextPageClick(): Promise<any> {
const allResultsMetadata = (this.allResultsMetadata && this.allResultsMetadata()) || [];
const metadata: ViewModels.QueryResultsMetadata = allResultsMetadata[allResultsMetadata.length - 1];
const firstResultIndex: number = (metadata && Number(metadata.firstItemIndex)) || 1;
@ -265,7 +264,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
return true;
};
private _executeQueryDocumentsPage(firstItemIndex: number): Q.Promise<any> {
private _executeQueryDocumentsPage(firstItemIndex: number): Promise<any> {
this.errors([]);
this.roundTrips(undefined);
if (this._iterator == null) {
@ -277,7 +276,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
}
// TODO: Position and enable spinner when request is in progress
private _queryDocumentsPage(firstItemIndex: number): Q.Promise<any> {
private _queryDocumentsPage(firstItemIndex: number): Promise<any> {
this.isExecutionError(false);
this._resetAggregateQueryMetrics();
const startKey: number = TelemetryProcessor.traceStart(Action.ExecuteQuery, {
@ -485,16 +484,14 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
}
}
protected _initIterator(): Q.Promise<MinimalQueryIterator> {
protected _initIterator(): Promise<MinimalQueryIterator> {
const options: any = QueryTab.getIteratorOptions(this.collection);
if (this._resourceTokenPartitionKey) {
options.partitionKey = this._resourceTokenPartitionKey;
}
return Q(
queryDocuments(this.collection.databaseId, this.collection.id(), this.sqlStatementToExecute(), options).then(
iterator => (this._iterator = iterator)
)
return queryDocuments(this.collection.databaseId, this.collection.id(), this.sqlStatementToExecute(), options).then(
iterator => (this._iterator = iterator)
);
}

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as ViewModels from "../../Contracts/ViewModels";
import TabsBase from "./TabsBase";
import TableEntityListViewModel from "../Tables/DataTable/TableEntityListViewModel";
@ -130,38 +129,38 @@ export default class QueryTablesTab extends TabsBase {
this.buildCommandBarOptions();
}
public onExecuteQueryClick = (): Q.Promise<any> => {
public onExecuteQueryClick = (): Promise<any> => {
this.queryViewModel().runQuery();
return null;
};
public onQueryBuilderClick = (): Q.Promise<any> => {
public onQueryBuilderClick = (): Promise<any> => {
this.queryViewModel().selectHelper();
return null;
};
public onQueryTextClick = (): Q.Promise<any> => {
public onQueryTextClick = (): Promise<any> => {
this.queryViewModel().selectEditor();
return null;
};
public onAddEntityClick = (): Q.Promise<any> => {
public onAddEntityClick = (): Promise<any> => {
this.container.addTableEntityPane.tableViewModel = this.tableEntityListViewModel();
this.container.addTableEntityPane.open();
return null;
};
public onEditEntityClick = (): Q.Promise<any> => {
public onEditEntityClick = (): Promise<any> => {
this.tableCommands.editEntityCommand(this.tableEntityListViewModel());
return null;
};
public onDeleteEntityClick = (): Q.Promise<any> => {
public onDeleteEntityClick = (): Promise<any> => {
this.tableCommands.deleteEntitiesCommand(this.tableEntityListViewModel());
return null;
};
public onActivate(): Q.Promise<any> {
public onActivate(): Promise<any> {
return super.onActivate().then(() => {
const columns =
!!this.tableEntityListViewModel() &&

View File

@ -1,6 +1,5 @@
import * as ko from "knockout";
import * as monaco from "monaco-editor";
import Q from "q";
import DiscardIcon from "../../../images/discard.svg";
import SaveIcon from "../../../images/save-cosmos.svg";
import * as Constants from "../../Common/Constants";
@ -186,7 +185,7 @@ export default abstract class ScriptTabBase extends TabsBase implements ViewMode
this._setBaselines();
}
public onTabClick(): Q.Promise<any> {
public onTabClick(): Promise<any> {
return super.onTabClick().then(() => {
if (this.isNew()) {
this.collection.selectedSubnodeKind(this.tabKind);
@ -197,13 +196,11 @@ export default abstract class ScriptTabBase extends TabsBase implements ViewMode
public abstract onSaveClick: () => Promise<any>;
public abstract onUpdateClick: () => Promise<any>;
public onDiscard = (): Q.Promise<any> => {
public onDiscard = async (): Promise<any> => {
this.setBaselines();
const original = this.editorContent.getEditableOriginalValue();
const editorModel = this.editor() && this.editor().getModel();
editorModel && editorModel.setValue(original);
return Q();
};
public onSaveOrUpdateClick(): Promise<any> {

View File

@ -9,7 +9,6 @@ import * as SharedConstants from "../../Shared/Constants";
import * as ViewModels from "../../Contracts/ViewModels";
import DiscardIcon from "../../../images/discard.svg";
import editable from "../../Common/EditableUtility";
import Q from "q";
import SaveIcon from "../../../images/save-cosmos.svg";
import TabsBase from "./TabsBase";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
@ -24,21 +23,21 @@ import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/update
import { configContext, Platform } from "../../ConfigContext";
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.
For more information see, <a target="_blank" href="https://aka.ms/cosmos-db-ttl">Time to Live (TTL) in Azure Cosmos DB</a>.`;
const indexingPolicyTTLWarningMessage: string = `
Changing the Indexing Policy impacts query results while the index transformation occurs.
When a change is made and the indexing mode is set to consistent or lazy, queries return eventual results until the operation completes.
Changing the Indexing Policy impacts query results while the index transformation occurs.
When a change is made and the indexing mode is set to consistent or lazy, queries return eventual results until the operation completes.
For more information see, <a target="_blank" href="https://aka.ms/cosmosdb/modify-index-policy">Modifying Indexing Policies</a>.`;
const updateThroughputBeyondLimitWarningMessage: string = `
You are about to request an increase in throughput beyond the pre-allocated capacity.
The service will scale out and increase throughput for the selected container.
You are about to request an increase in throughput beyond the pre-allocated capacity.
The service will scale out and increase throughput for the selected container.
This operation will take 1-3 business days to complete. You can track the status of this request in Notifications.`;
const updateThroughputDelayedApplyWarningMessage: 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.
This operation will take some time to complete.`;
// TODO: move to a utility classs and add unit tests
@ -82,7 +81,7 @@ const throughputApplyDelayedMessage = (
collectionName: string,
requestedThroughput: number
): string => `
The request to increase the throughput has successfully been submitted.
The request to increase the throughput has successfully been submitted.
This operation will take 1-3 business days to complete. View the latest status in Notifications.<br />
Database: ${databaseName}, Container: ${collectionName} ${currentThroughput(
isAutoscale,
@ -115,7 +114,7 @@ const throughputApplyLongDelayMessage = (
collectionName: string,
requestedThroughput: number
): string => `
A request to increase the throughput is currently in progress.
A request to increase the throughput is currently in progress.
This operation will take 1-3 business days to complete. View the latest status in Notifications.<br />
Database: ${databaseName}, Container: ${collectionName} ${currentThroughput(
isAutoscale,
@ -1231,7 +1230,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
this.isExecuting(false);
};
public onRevertClick = (): Q.Promise<any> => {
public onRevertClick = async (): Promise<any> => {
TelemetryProcessor.trace(Action.DiscardSettings, ActionModifiers.Mark, {
message: "Settings Discarded"
});
@ -1274,21 +1273,17 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
this.selectedAutoPilotTier(originalAutoPilotTier);
}
}
return Q();
};
public onValidIndexingPolicyEdit(): Q.Promise<any> {
public async onValidIndexingPolicyEdit(): Promise<any> {
this.indexingPolicyContent.editableIsValid(true);
return Q();
}
public onInvalidIndexingPolicyEdit(): Q.Promise<any> {
public async onInvalidIndexingPolicyEdit(): Promise<any> {
this.indexingPolicyContent.editableIsValid(false);
return Q();
}
public onActivate(): Q.Promise<any> {
public onActivate(): Promise<any> {
return super.onActivate().then(async () => {
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Settings);
const database: ViewModels.Database = this.collection.getDatabase();

View File

@ -41,7 +41,7 @@ export default class SettingsTabV2 extends TabsBase {
});
}
public onActivate(): Q.Promise<unknown> {
public onActivate(): Promise<unknown> {
this.isExecuting(true);
this.currentCollection.loadOffer().then(
() => {

View File

@ -1,6 +1,5 @@
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
import * as ko from "knockout";
import Q from "q";
import * as _ from "underscore";
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
import * as Constants from "../../Common/Constants";
@ -61,13 +60,11 @@ export default class StoredProcedureTab extends ScriptTabBase {
});
};
public onDiscard = (): Q.Promise<any> => {
public onDiscard = async (): Promise<any> => {
this.setBaselines();
const original = this.editorContent.getEditableOriginalValue();
this.originalSprocBody(original);
this.originalSprocBody.valueHasMutated(); // trigger a re-render of the editor
return Q();
};
public onUpdateClick = (): Promise<any> => {
@ -284,8 +281,7 @@ export default class StoredProcedureTab extends ScriptTabBase {
.finally(() => this.isExecuting(false));
}
public onDelete(): Q.Promise<any> {
public async onDelete(): Promise<any> {
// TODO
return Q();
}
}

View File

@ -1,5 +1,4 @@
import * as ko from "knockout";
import Q from "q";
import * as Constants from "../../Common/Constants";
import * as ViewModels from "../../Contracts/ViewModels";
import * as DataModels from "../../Contracts/DataModels";
@ -93,9 +92,8 @@ export default class TabsBase extends WaitsForTemplateViewModel {
});
}
public onTabClick(): Q.Promise<any> {
public async onTabClick(): Promise<any> {
this.getContainer().tabsManager.activateTab(this);
return Q();
}
protected updateSelectedNode(): void {
@ -127,7 +125,7 @@ export default class TabsBase extends WaitsForTemplateViewModel {
return this.onSpaceOrEnterKeyPress(event, () => this.onCloseTabButtonClick());
};
public onActivate(): Q.Promise<any> {
public async onActivate(): Promise<any> {
this.updateSelectedNode();
if (!!this.collection) {
this.collection.selectedSubnodeKind(this.tabKind);
@ -149,7 +147,6 @@ export default class TabsBase extends WaitsForTemplateViewModel {
tabTitle: this.tabTitle(),
tabId: this.tabId
});
return Q();
}
public onErrorDetailsClick = (src: any, event: MouseEvent): boolean => {
@ -172,9 +169,8 @@ export default class TabsBase extends WaitsForTemplateViewModel {
return true;
};
public refresh(): Q.Promise<any> {
public async refresh(): Promise<any> {
location.reload();
return Q();
}
protected getContainer(): Explorer {

View File

@ -1,4 +1,3 @@
import Q from "q";
import * as ko from "knockout";
import * as Constants from "../../Common/Constants";
import DocumentId from "./DocumentId";
@ -59,13 +58,13 @@ export default class ConflictId {
return;
}
public loadConflict(): Q.Promise<any> {
public async loadConflict(): Promise<any> {
const conflictsTab = this.container;
this.container.selectedConflictId(this);
if (this.operationType === Constants.ConflictOperationType.Create) {
this.container.initDocumentEditorForCreate(this, this.content);
return Q();
return;
}
this.container.loadingConflictData(true);
@ -88,10 +87,10 @@ export default class ConflictId {
this.operationType === Constants.ConflictOperationType.Delete
) {
this.container.initDocumentEditorForNoOp(this);
return Q();
return;
}
return Q.reject(reason);
throw reason;
}
);
}

View File

@ -65,7 +65,7 @@ export default class DocumentId {
return JSON.stringify(partitionKeyValue);
}
public loadDocument(): Q.Promise<any> {
public loadDocument(): Promise<any> {
return this.container.selectDocument(this);
}
}

View File

@ -5,7 +5,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import DocumentId from "./DocumentId";
import DocumentsTab from "../Tabs/DocumentsTab";
import Q from "q";
import QueryTab from "../Tabs/QueryTab";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Explorer from "../Explorer";
@ -41,9 +40,9 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas
this.isCollectionExpanded = ko.observable<boolean>(true);
}
public expandCollection(): Q.Promise<void> {
public async expandCollection(): Promise<void> {
if (this.isCollectionExpanded()) {
return Q();
return;
}
this.isCollectionExpanded(true);
@ -55,8 +54,6 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas
defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree
});
return Q.resolve();
}
public collapseCollection() {

View File

@ -1,4 +1,3 @@
import Q from "q";
import * as DataModels from "../Contracts/DataModels";
import * as ViewModels from "../Contracts/ViewModels";
@ -60,39 +59,34 @@ export class QueryUtils {
public static queryPagesUntilContentPresent(
firstItemIndex: number,
queryItems: (itemIndex: number) => Q.Promise<ViewModels.QueryResults>
): Q.Promise<ViewModels.QueryResults> {
queryItems: (itemIndex: number) => Promise<ViewModels.QueryResults>
): Promise<ViewModels.QueryResults> {
let roundTrips: number = 0;
let netRequestCharge: number = 0;
const doRequest = (itemIndex: number): Q.Promise<ViewModels.QueryResults> =>
queryItems(itemIndex).then(
(results: ViewModels.QueryResults) => {
roundTrips = roundTrips + 1;
results.roundTrips = roundTrips;
results.requestCharge = Number(results.requestCharge) + netRequestCharge;
netRequestCharge = Number(results.requestCharge);
const resultsMetadata: ViewModels.QueryResultsMetadata = {
hasMoreResults: results.hasMoreResults,
itemCount: results.itemCount,
firstItemIndex: results.firstItemIndex,
lastItemIndex: results.lastItemIndex
};
if (resultsMetadata.itemCount === 0 && resultsMetadata.hasMoreResults) {
return doRequest(resultsMetadata.lastItemIndex);
}
return Q.resolve(results);
},
(error: any) => {
return Q.reject(error);
const doRequest = async (itemIndex: number): Promise<ViewModels.QueryResults> =>
queryItems(itemIndex).then((results: ViewModels.QueryResults) => {
roundTrips = roundTrips + 1;
results.roundTrips = roundTrips;
results.requestCharge = Number(results.requestCharge) + netRequestCharge;
netRequestCharge = Number(results.requestCharge);
const resultsMetadata: ViewModels.QueryResultsMetadata = {
hasMoreResults: results.hasMoreResults,
itemCount: results.itemCount,
firstItemIndex: results.firstItemIndex,
lastItemIndex: results.lastItemIndex
};
if (resultsMetadata.itemCount === 0 && resultsMetadata.hasMoreResults) {
return doRequest(resultsMetadata.lastItemIndex);
}
);
return results;
});
return doRequest(firstItemIndex);
}
public static queryAllPages(
queryItems: (itemIndex: number) => Q.Promise<ViewModels.QueryResults>
): Q.Promise<ViewModels.QueryResults> {
queryItems: (itemIndex: number) => Promise<ViewModels.QueryResults>
): Promise<ViewModels.QueryResults> {
const queryResults: ViewModels.QueryResults = {
documents: [],
activityId: undefined,
@ -103,25 +97,20 @@ export class QueryUtils {
requestCharge: 0,
roundTrips: 0
};
const doRequest = (itemIndex: number): Q.Promise<ViewModels.QueryResults> =>
queryItems(itemIndex).then(
(results: ViewModels.QueryResults) => {
const { requestCharge, hasMoreResults, itemCount, lastItemIndex, documents } = results;
queryResults.roundTrips = queryResults.roundTrips + 1;
queryResults.requestCharge = Number(queryResults.requestCharge) + Number(requestCharge);
queryResults.hasMoreResults = hasMoreResults;
queryResults.itemCount = queryResults.itemCount + itemCount;
queryResults.lastItemIndex = lastItemIndex;
queryResults.documents = queryResults.documents.concat(documents);
if (queryResults.hasMoreResults) {
return doRequest(queryResults.lastItemIndex + 1);
}
return Q.resolve(queryResults);
},
(error: any) => {
return Q.reject(error);
const doRequest = async (itemIndex: number): Promise<ViewModels.QueryResults> =>
queryItems(itemIndex).then((results: ViewModels.QueryResults) => {
const { requestCharge, hasMoreResults, itemCount, lastItemIndex, documents } = results;
queryResults.roundTrips = queryResults.roundTrips + 1;
queryResults.requestCharge = Number(queryResults.requestCharge) + Number(requestCharge);
queryResults.hasMoreResults = hasMoreResults;
queryResults.itemCount = queryResults.itemCount + itemCount;
queryResults.lastItemIndex = lastItemIndex;
queryResults.documents = queryResults.documents.concat(documents);
if (queryResults.hasMoreResults) {
return doRequest(queryResults.lastItemIndex + 1);
}
);
return queryResults;
});
return doRequest(0);
}