Skip to content

Commit

Permalink
Hook up deletion for MIAA (microsoft#10991)
Browse files Browse the repository at this point in the history
* Hook up deletion for MIAA

* fix button disabling

* cannot
  • Loading branch information
Charles-Gagnon authored Jun 18, 2020
1 parent 95107f1 commit dc751db
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 15 deletions.
49 changes: 49 additions & 0 deletions extensions/arc/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,52 @@ export function getConnectionModeDisplayText(connectionMode: string | undefined)
}
return connectionMode;
}

/**
* Opens an input box prompting the user to enter in the name of a resource to delete
* @param namespace The namespace of the resource to delete
* @param name The name of the resource to delete
* @returns Promise resolving to true if the user confirmed the name, false if the input box was closed for any other reason
*/
export async function promptForResourceDeletion(namespace: string, name: string): Promise<boolean> {
const inputBox = vscode.window.createInputBox();
inputBox.title = loc.resourceDeletionWarning(namespace, name);
inputBox.placeholder = name;
return new Promise(resolve => {
let valueAccepted = false;
inputBox.show();
inputBox.onDidAccept(() => {
if (inputBox.value === name) {
valueAccepted = true;
inputBox.hide();
inputBox.dispose();
resolve(true);
} else {
inputBox.validationMessage = loc.invalidResourceDeletionName(inputBox.value);
}
});
inputBox.onDidHide(() => {
if (!valueAccepted) {
resolve(false);
}
});
inputBox.onDidChangeValue(() => {
inputBox.validationMessage = '';
});
});
}

/**
* Gets the message to display for a given error object that may be a variety of types.
* @param error The error object
*/
export function getErrorText(error: any): string {
if (error?.body?.reason) {
// For HTTP Errors pull out the reason message since that's usually the most helpful
return error.body.reason;
} else if (error instanceof Error) {
return error.message;
} else {
return error;
}
}
10 changes: 5 additions & 5 deletions extensions/arc/src/localizedConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ export const learnAboutPostgresClients = localize('arc.learnAboutPostgresClients
export const node = localize('arc.node', "node");
export const nodes = localize('arc.nodes', "nodes");
export const storagePerNode = localize('arc.storagePerNode', "storage per node");
export const arcResources = localize('arc.arcResources', "Azure Arc Resources");

export function databaseCreated(name: string): string { return localize('arc.databaseCreated', "Database {0} created", name); }
export function databaseCreationFailed(name: string, error: any): string { return localize('arc.databaseCreationFailed', "Failed to create database {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function passwordReset(name: string): string { return localize('arc.passwordReset', "Password reset for service {0}", name); }
export function passwordResetFailed(name: string, error: any): string { return localize('arc.passwordResetFailed', "Failed to reset password for service {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function deleteServicePrompt(name: string): string { return localize('arc.deleteServicePrompt', "Delete service {0}?", name); }
export function serviceDeleted(name: string): string { return localize('arc.serviceDeleted', "Service {0} deleted", name); }
export function serviceDeletionFailed(name: string, error: any): string { return localize('arc.serviceDeletionFailed', "Failed to delete service {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function resourceDeleted(name: string): string { return localize('arc.resourceDeleted', "Resource '{0}' deleted", name); }
export function resourceDeletionFailed(name: string, error: any): string { return localize('arc.resourceDeletionFailed', "Failed to delete resource {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function couldNotFindAzureResource(name: string): string { return localize('arc.couldNotFindAzureResource', "Could not find Azure resource for {0}", name); }
export function copiedToClipboard(name: string): string { return localize('arc.copiedToClipboard', "{0} copied to clipboard", name); }
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", (error instanceof Error ? error.message : error)); }
Expand All @@ -106,5 +106,5 @@ export function numVCores(vCores: string): string {
}
}
export function couldNotFindRegistration(namespace: string, name: string) { return localize('arc.couldNotFindRegistration', "Could not find controller registration for {0} ({1})", name, namespace); }

export const arcResources = localize('arc.arcResources', "Azure Arc Resources");
export function resourceDeletionWarning(namespace: string, name: string): string { return localize('arc.resourceDeletionWarning', "Warning! Deleting a resource is permanent and cannot be undone. To delete the resource '{0}.{1}' type the name '{1}' below to proceed.", namespace, name); }
export function invalidResourceDeletionName(name: string): string { return localize('arc.invalidResourceDeletionName', "The value '{0}' does not match the instance name. Try again or press escape to exit", name); }
4 changes: 2 additions & 2 deletions extensions/arc/src/models/controllerModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export class ControllerModel {
});
}

public miaaDelete(name: string): void {
this._sqlInstanceRouter.apiV1HybridSqlNsNameDelete(this._namespace, name);
public async miaaDelete(namespace: string, name: string): Promise<void> {
await this._sqlInstanceRouter.apiV1HybridSqlNsNameDelete(namespace, name);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as loc from '../../../localizedConstants';
import { DashboardPage } from '../../components/dashboardPage';
import { IconPathHelper, cssStyles, ResourceType } from '../../../constants';
import { ControllerModel, Registration } from '../../../models/controllerModel';
import { getAzurecoreApi } from '../../../common/utils';
import { getAzurecoreApi, promptForResourceDeletion, getErrorText } from '../../../common/utils';
import { MiaaModel, DatabaseModel } from '../../../models/miaaModel';
import { HybridSqlNsNameGetResponse } from '../../../controller/generated/v1/model/hybridSqlNsNameGetResponse';
import { EndpointModel } from '../../../controller/generated/v1/api';
Expand Down Expand Up @@ -176,6 +176,20 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
iconPath: IconPathHelper.delete
}).component();

deleteButton.onDidClick(async () => {
deleteButton.enabled = false;
try {
if (await promptForResourceDeletion(this._miaaModel.namespace, this._miaaModel.name)) {
await this._controllerModel.miaaDelete(this._miaaModel.namespace, this._miaaModel.name);
vscode.window.showInformationMessage(loc.resourceDeleted(this._miaaModel.name));
}
} catch (error) {
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._miaaModel.name, getErrorText(error)));
} finally {
deleteButton.enabled = true;
}
});

const resetPasswordButton = this.modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({
label: loc.resetPassword,
iconPath: IconPathHelper.edit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DuskyObjectModelsDatabase, DuskyObjectModelsDatabaseServiceArcPayload,
import { DashboardPage } from '../../components/dashboardPage';
import { ControllerModel } from '../../../models/controllerModel';
import { PostgresModel, PodRole } from '../../../models/postgresModel';
import { promptForResourceDeletion, getErrorText } from '../../../common/utils';

export class PostgresOverviewPage extends DashboardPage {
private propertiesLoading?: azdata.LoadingComponent;
Expand Down Expand Up @@ -220,14 +221,12 @@ export class PostgresOverviewPage extends DashboardPage {
deleteButton.onDidClick(async () => {
deleteButton.enabled = false;
try {
const response = await vscode.window.showQuickPick([loc.yes, loc.no], {
placeHolder: loc.deleteServicePrompt(this._postgresModel.fullName)
});
if (response !== loc.yes) { return; }
await this._postgresModel.delete();
vscode.window.showInformationMessage(loc.serviceDeleted(this._postgresModel.fullName));
if (await promptForResourceDeletion(this._postgresModel.namespace, this._postgresModel.name)) {
await this._postgresModel.delete();
vscode.window.showInformationMessage(loc.resourceDeleted(this._postgresModel.fullName));
}
} catch (error) {
vscode.window.showErrorMessage(loc.serviceDeletionFailed(this._postgresModel.fullName, error));
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._postgresModel.fullName, getErrorText(error)));
} finally {
deleteButton.enabled = true;
}
Expand Down

0 comments on commit dc751db

Please sign in to comment.