mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add and drop Postgres extensions (#15923)
* Works * Clean up * Aria labels added * Pr fixes, only allow one drop at a time, check for citus * Cleaning up refresh * Created separate function for creating drop button * Added with props, add comment about not able to drop citus extension * Update url link of postgres extensions to match engine version after config is availible
This commit is contained in:
@@ -37,10 +37,13 @@ export const value = localize('arc.value', "Value");
|
|||||||
|
|
||||||
export const newInstance = localize('arc.createNew', "New Instance");
|
export const newInstance = localize('arc.createNew', "New Instance");
|
||||||
export const deleteText = localize('arc.delete', "Delete");
|
export const deleteText = localize('arc.delete', "Delete");
|
||||||
|
export const learnMore = localize('arc.learnMore', "Learn More.");
|
||||||
|
export const dropText = localize('arc.drop', "Drop");
|
||||||
export const saveText = localize('arc.save', "Save");
|
export const saveText = localize('arc.save', "Save");
|
||||||
export const discardText = localize('arc.discard', "Discard");
|
export const discardText = localize('arc.discard', "Discard");
|
||||||
export const resetPassword = localize('arc.resetPassword', "Reset Password");
|
export const resetPassword = localize('arc.resetPassword', "Reset Password");
|
||||||
export const addExtensions = localize('arc.addExtensions', "Add extensions");
|
export const addExtensions = localize('arc.addExtensions', "Add extensions");
|
||||||
|
export const dropExtension = localize('arc.dropExtension', "Drop extension");
|
||||||
export const openInAzurePortal = localize('arc.openInAzurePortal', "Open in Azure Portal");
|
export const openInAzurePortal = localize('arc.openInAzurePortal', "Open in Azure Portal");
|
||||||
export const resourceGroup = localize('arc.resourceGroup', "Resource Group");
|
export const resourceGroup = localize('arc.resourceGroup', "Resource Group");
|
||||||
export const region = localize('arc.region', "Region");
|
export const region = localize('arc.region', "Region");
|
||||||
@@ -56,11 +59,13 @@ export const miaaAdmin = localize('arc.miaaAdmin', "Managed instance admin");
|
|||||||
export const controllerEndpoint = localize('arc.controllerEndpoint', "Controller endpoint");
|
export const controllerEndpoint = localize('arc.controllerEndpoint', "Controller endpoint");
|
||||||
export const extensionName = localize('arc.extensionName', "Extension name");
|
export const extensionName = localize('arc.extensionName', "Extension name");
|
||||||
export const extensionsDescription = localize('arc.extensionsDescription', "PostgreSQL provides the ability to extend the functionality of your database by using extensions. Extensions allow for bundling multiple related SQL objects together in a single package that can be loaded or removed from your database with a single command. After being loaded in the database, extensions can function like built-in features.");
|
export const extensionsDescription = localize('arc.extensionsDescription', "PostgreSQL provides the ability to extend the functionality of your database by using extensions. Extensions allow for bundling multiple related SQL objects together in a single package that can be loaded or removed from your database with a single command. After being loaded in the database, extensions can function like built-in features.");
|
||||||
export const extensionsFunction = localize('arc.extensionsFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. These preloaded extensions can be viewed below.");
|
export const extensionsFunction = localize('arc.extensionsFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. These preloaded extensions can be viewed and edited below.");
|
||||||
export const extensionsLearnMore = localize('arc.extensionsLearnMore', "Learn more about PostgreSQL extensions.");
|
export const extensionsLearnMore = localize('arc.extensionsLearnMore', "Learn more about PostgreSQL extensions.");
|
||||||
export const extensionsTableLoading = localize('arc.extensionsTableLoading', "Table of preloaded extensions are loading.");
|
export const extensionsTableLoading = localize('arc.extensionsTableLoading', "Table of preloaded extensions are loading.");
|
||||||
export const extensionsTableLabel = localize('arc.extensionsTableLabel', "Table of preloaded extensions.");
|
export const extensionsTableLabel = localize('arc.extensionsTableLabel', "Table of preloaded extensions.");
|
||||||
export const extensionsTableLoadingComplete = localize('arc.extensionsTableLoadingComplete', "Preloaded extensions can now be viewed.");
|
export const extensionsTableLoadingComplete = localize('arc.extensionsTableLoadingComplete', "Preloaded extensions can now be viewed.");
|
||||||
|
export const extensionsAddList = localize('arc.extensionsAddList', "Extensions");
|
||||||
|
export const extensionsAddDialog = localize('arc.extensionsAddDialog', "PostgreSQL provides the ability to extend the functionality of your database by using extensions.");
|
||||||
export const dataController = localize('arc.dataController', "Data controller");
|
export const dataController = localize('arc.dataController', "Data controller");
|
||||||
export const kibanaDashboard = localize('arc.kibanaDashboard', "Kibana Dashboard");
|
export const kibanaDashboard = localize('arc.kibanaDashboard', "Kibana Dashboard");
|
||||||
export const grafanaDashboard = localize('arc.grafanaDashboard', "Grafana Dashboard");
|
export const grafanaDashboard = localize('arc.grafanaDashboard', "Grafana Dashboard");
|
||||||
@@ -217,6 +222,8 @@ export function extensionInstalled(name: string): string { return localize('arc.
|
|||||||
export function updatingInstance(name: string): string { return localize('arc.updatingInstance', "Updating instance '{0}'...", name); }
|
export function updatingInstance(name: string): string { return localize('arc.updatingInstance', "Updating instance '{0}'...", name); }
|
||||||
export function instanceDeleted(name: string): string { return localize('arc.instanceDeleted', "Instance '{0}' deleted", name); }
|
export function instanceDeleted(name: string): string { return localize('arc.instanceDeleted', "Instance '{0}' deleted", name); }
|
||||||
export function instanceUpdated(name: string): string { return localize('arc.instanceUpdated', "Instance '{0}' updated", name); }
|
export function instanceUpdated(name: string): string { return localize('arc.instanceUpdated', "Instance '{0}' updated", name); }
|
||||||
|
export function extensionDropped(name: string): string { return localize('arc.extensionDropped', "Extension '{0}' deleted", name); }
|
||||||
|
export function extensionsAdded(name: string): string { return localize('arc.extensionsAdded', "Extensions '{0}' added", name); }
|
||||||
export function copiedToClipboard(name: string): string { return localize('arc.copiedToClipboard', "{0} copied to clipboard", name); }
|
export function copiedToClipboard(name: string): string { return localize('arc.copiedToClipboard', "{0} copied to clipboard", name); }
|
||||||
export function clickTheTroubleshootButton(resourceType: string): string { return localize('arc.clickTheTroubleshootButton', "Click the troubleshoot button to open the Azure Arc {0} troubleshooting notebook.", resourceType); }
|
export function clickTheTroubleshootButton(resourceType: string): string { return localize('arc.clickTheTroubleshootButton', "Click the troubleshoot button to open the Azure Arc {0} troubleshooting notebook.", resourceType); }
|
||||||
export function dataStorage(value: string): string { return localize('arc.dataStorage', "{0} data", value); }
|
export function dataStorage(value: string): string { return localize('arc.dataStorage', "{0} data", value); }
|
||||||
@@ -241,6 +248,8 @@ export function copyValueToClipboard(valueName: string): string { return localiz
|
|||||||
export const pgConnectionRequired = localize('arc.pgConnectionRequired', "A connection is required to show and set database engine settings.");
|
export const pgConnectionRequired = localize('arc.pgConnectionRequired', "A connection is required to show and set database engine settings.");
|
||||||
export const miaaConnectionRequired = localize('arc.miaaConnectionRequired', "A connection is required to list the databases on this instance.");
|
export const miaaConnectionRequired = localize('arc.miaaConnectionRequired', "A connection is required to list the databases on this instance.");
|
||||||
export const couldNotFindControllerRegistration = localize('arc.couldNotFindControllerRegistration', "Could not find controller registration.");
|
export const couldNotFindControllerRegistration = localize('arc.couldNotFindControllerRegistration', "Could not find controller registration.");
|
||||||
|
export const dropMultipleExtensions = localize('arc.dropMultipleExtensions', "Currently dropping another extension, try again once that is completed.");
|
||||||
|
export function updateExtensionsFailed(error: any): string { return localize('arc.updateExtensionsFailed', "Editing extensions failed. {0}", getErrorMessage(error)); }
|
||||||
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", getErrorMessage(error)); }
|
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", getErrorMessage(error)); }
|
||||||
export function resetFailed(error: any): string { return localize('arc.resetFailed', "Reset failed. {0}", getErrorMessage(error)); }
|
export function resetFailed(error: any): string { return localize('arc.resetFailed', "Reset failed. {0}", getErrorMessage(error)); }
|
||||||
export function openDashboardFailed(error: any): string { return localize('arc.openDashboardFailed', "Error opening dashboard. {0}", getErrorMessage(error)); }
|
export function openDashboardFailed(error: any): string { return localize('arc.openDashboardFailed', "Error opening dashboard. {0}", getErrorMessage(error)); }
|
||||||
|
|||||||
@@ -10,12 +10,17 @@ import * as loc from '../../../localizedConstants';
|
|||||||
import { IconPathHelper, cssStyles } from '../../../constants';
|
import { IconPathHelper, cssStyles } from '../../../constants';
|
||||||
import { DashboardPage } from '../../components/dashboardPage';
|
import { DashboardPage } from '../../components/dashboardPage';
|
||||||
import { PostgresModel } from '../../../models/postgresModel';
|
import { PostgresModel } from '../../../models/postgresModel';
|
||||||
|
import { AddPGExtensionsDialog } from '../../dialogs/addPGExtensionsDialog';
|
||||||
|
import { Deferred } from '../../../common/promise';
|
||||||
|
|
||||||
export class PostgresExtensionsPage extends DashboardPage {
|
export class PostgresExtensionsPage extends DashboardPage {
|
||||||
|
|
||||||
private extensions: { name: string; }[] = [];
|
private extensionNames: string[] = [];
|
||||||
private extensionsTable!: azdata.DeclarativeTableComponent;
|
private extensionsTable!: azdata.DeclarativeTableComponent;
|
||||||
private extensionsLoading!: azdata.LoadingComponent;
|
private extensionsLoading!: azdata.LoadingComponent;
|
||||||
|
private addExtensionsButton!: azdata.ButtonComponent;
|
||||||
|
private _dropExtPromise?: Deferred<void>;
|
||||||
|
private extensionsLink!: azdata.HyperlinkComponent;
|
||||||
|
|
||||||
private readonly _azdataApi: azdataExt.IExtension;
|
private readonly _azdataApi: azdataExt.IExtension;
|
||||||
|
|
||||||
@@ -54,22 +59,22 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||||
}).component());
|
}).component());
|
||||||
|
|
||||||
const info = this.modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
|
const info = this.modelView.modelBuilder.text().withProps({
|
||||||
value: loc.extensionsFunction,
|
value: loc.extensionsFunction,
|
||||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
const link = this.modelView.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({
|
this.extensionsLink = this.modelView.modelBuilder.hyperlink().withProps({
|
||||||
label: loc.extensionsLearnMore,
|
label: loc.learnMore,
|
||||||
url: 'https://docs.microsoft.com/azure/azure-arc/data/using-extensions-in-postgresql-hyperscale-server-group',
|
url: 'https://www.postgresql.org/docs/12/external-extensions.html',
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
const infoAndLink = this.modelView.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component();
|
const infoAndLink = this.modelView.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component();
|
||||||
infoAndLink.addItem(info, { CSSStyles: { 'margin-right': '5px' } });
|
infoAndLink.addItem(info, { CSSStyles: { 'margin-right': '5px' } });
|
||||||
infoAndLink.addItem(link);
|
infoAndLink.addItem(this.extensionsLink);
|
||||||
content.addItem(infoAndLink, { CSSStyles: { 'margin-bottom': '15px', 'margin-top': '25px' } });
|
content.addItem(infoAndLink, { CSSStyles: { 'margin-bottom': '15px', 'margin-top': '25px' } });
|
||||||
|
|
||||||
this.extensionsTable = this.modelView.modelBuilder.declarativeTable().withProperties<azdata.DeclarativeTableProperties>({
|
this.extensionsTable = this.modelView.modelBuilder.declarativeTable().withProps({
|
||||||
ariaLabel: loc.extensionsTableLabel,
|
ariaLabel: loc.extensionsTableLabel,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
columns: [
|
columns: [
|
||||||
@@ -77,7 +82,15 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
displayName: loc.extensionName,
|
displayName: loc.extensionName,
|
||||||
valueType: azdata.DeclarativeDataType.string,
|
valueType: azdata.DeclarativeDataType.string,
|
||||||
isReadOnly: true,
|
isReadOnly: true,
|
||||||
width: '100%',
|
width: '95%',
|
||||||
|
headerCssStyles: cssStyles.tableHeader,
|
||||||
|
rowCssStyles: cssStyles.tableRow
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: loc.dropText,
|
||||||
|
valueType: azdata.DeclarativeDataType.component,
|
||||||
|
isReadOnly: false,
|
||||||
|
width: '10%',
|
||||||
headerCssStyles: cssStyles.tableHeader,
|
headerCssStyles: cssStyles.tableHeader,
|
||||||
rowCssStyles: cssStyles.tableRow
|
rowCssStyles: cssStyles.tableRow
|
||||||
}
|
}
|
||||||
@@ -86,8 +99,7 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.extensionsLoading = this.modelView.modelBuilder.loadingComponent()
|
this.extensionsLoading = this.modelView.modelBuilder.loadingComponent()
|
||||||
.withItem(this.extensionsTable)
|
.withItem(this.extensionsTable).withProps({
|
||||||
.withProperties<azdata.LoadingComponentProperties>({
|
|
||||||
loading: !this._postgresModel.configLastUpdated,
|
loading: !this._postgresModel.configLastUpdated,
|
||||||
loadingText: loc.extensionsTableLoading,
|
loadingText: loc.extensionsTableLoading,
|
||||||
loadingCompletedText: loc.extensionsTableLoadingComplete
|
loadingCompletedText: loc.extensionsTableLoadingComplete
|
||||||
@@ -101,15 +113,22 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
|
|
||||||
protected get toolbarContainer(): azdata.ToolbarContainer {
|
protected get toolbarContainer(): azdata.ToolbarContainer {
|
||||||
// Add extensions
|
// Add extensions
|
||||||
const addExtensionsButton = this.modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({
|
this.addExtensionsButton = this.modelView.modelBuilder.button().withProps({
|
||||||
label: loc.addExtensions,
|
label: loc.addExtensions,
|
||||||
|
ariaLabel: loc.addExtensions,
|
||||||
iconPath: IconPathHelper.add
|
iconPath: IconPathHelper.add
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.disposables.push(
|
this.disposables.push(
|
||||||
addExtensionsButton.onDidClick(async () => {
|
this.addExtensionsButton.onDidClick(async () => {
|
||||||
addExtensionsButton.enabled = false;
|
const addExtDialog = new AddPGExtensionsDialog(this._postgresModel);
|
||||||
|
addExtDialog.showDialog(loc.addExtensions);
|
||||||
|
|
||||||
|
let extArg = await addExtDialog.waitForClose();
|
||||||
|
if (extArg) {
|
||||||
try {
|
try {
|
||||||
|
this.addExtensionsButton.enabled = false;
|
||||||
|
let extensionList = this.extensionNames.join() + ',' + extArg;
|
||||||
await vscode.window.withProgress(
|
await vscode.window.withProgress(
|
||||||
{
|
{
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
@@ -117,10 +136,11 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
cancellable: false
|
cancellable: false
|
||||||
},
|
},
|
||||||
async (_progress, _token): Promise<void> => {
|
async (_progress, _token): Promise<void> => {
|
||||||
|
|
||||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||||
this._postgresModel.info.name,
|
this._postgresModel.info.name,
|
||||||
{
|
{
|
||||||
extensions: ''
|
extensions: extensionList
|
||||||
},
|
},
|
||||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars);
|
this._postgresModel.controllerModel.azdataAdditionalEnvVars);
|
||||||
|
|
||||||
@@ -132,27 +152,125 @@ export class PostgresExtensionsPage extends DashboardPage {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
vscode.window.showInformationMessage(loc.instanceUpdated(this._postgresModel.info.name));
|
vscode.window.showInformationMessage(loc.extensionsAdded(extensionList));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(loc.instanceUpdateFailed(this._postgresModel.info.name, error));
|
vscode.window.showErrorMessage(loc.updateExtensionsFailed(error));
|
||||||
} finally {
|
} finally {
|
||||||
addExtensionsButton.enabled = true;
|
this.addExtensionsButton.enabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return this.modelView.modelBuilder.toolbarContainer().component();
|
return this.modelView.modelBuilder.toolbarContainer().withToolbarItems([
|
||||||
|
{ component: this.addExtensionsButton }
|
||||||
|
]).component();
|
||||||
}
|
}
|
||||||
|
|
||||||
private refreshExtensionsTable(): void {
|
private refreshExtensionsTable(): void {
|
||||||
if (this._postgresModel.config) {
|
let extensions = this._postgresModel.config!.spec.engine.extensions;
|
||||||
this.extensions = this._postgresModel.config?.spec.engine.extensions;
|
this.extensionsTable.data = extensions.map(e => {
|
||||||
this.extensionsTable.data = this.extensions.map(e => [e.name]);
|
|
||||||
|
this.extensionNames.push(e.name);
|
||||||
|
|
||||||
|
return [e.name, this.createDropButton(e.name)];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates drop button to add to each row of extensions table.
|
||||||
|
* Allows user to drop individual extension.
|
||||||
|
* @param name name of postgres extension the drop button will be tied to.
|
||||||
|
*/
|
||||||
|
public createDropButton(name: string): azdata.ButtonComponent {
|
||||||
|
// Can drop individual extensions
|
||||||
|
let button = this.modelView.modelBuilder.button().withProps({
|
||||||
|
iconPath: IconPathHelper.delete,
|
||||||
|
ariaLabel: loc.dropExtension,
|
||||||
|
title: loc.dropExtension,
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
enabled: true
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.disposables.push(
|
||||||
|
button.onDidClick(async () => {
|
||||||
|
try {
|
||||||
|
this.addExtensionsButton.enabled = false;
|
||||||
|
button.enabled = false;
|
||||||
|
await this.dropExtension(name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this._postgresModel.refresh();
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage(loc.refreshFailed(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
vscode.window.showInformationMessage(loc.extensionDropped(name));
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage(loc.updateExtensionsFailed(error));
|
||||||
|
} finally {
|
||||||
|
this.addExtensionsButton.enabled = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dropping the citus extension is not supported.
|
||||||
|
if (name === 'citus') {
|
||||||
|
button.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls edit on postgres extensions with an updated extensions list.
|
||||||
|
* @param name name of postgres extension to not inlcude when editing list of extensions
|
||||||
|
*/
|
||||||
|
public async dropExtension(name: string): Promise<void> {
|
||||||
|
// Only allow one drop to be happening at a time
|
||||||
|
if (this._dropExtPromise) {
|
||||||
|
vscode.window.showErrorMessage(loc.dropMultipleExtensions);
|
||||||
|
return this._dropExtPromise.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dropExtPromise = new Deferred();
|
||||||
|
try {
|
||||||
|
await vscode.window.withProgress(
|
||||||
|
{
|
||||||
|
location: vscode.ProgressLocation.Notification,
|
||||||
|
title: loc.updatingInstance(this._postgresModel.info.name),
|
||||||
|
cancellable: false
|
||||||
|
},
|
||||||
|
async (_progress, _token): Promise<void> => {
|
||||||
|
let index = this.extensionNames.indexOf(name, 0);
|
||||||
|
this.extensionNames.splice(index, 1);
|
||||||
|
|
||||||
|
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||||
|
this._postgresModel.info.name,
|
||||||
|
{
|
||||||
|
extensions: this.extensionNames.join()
|
||||||
|
},
|
||||||
|
this._postgresModel.controllerModel.azdataAdditionalEnvVars
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this._dropExtPromise.resolve();
|
||||||
|
} catch (err) {
|
||||||
|
this._dropExtPromise.reject(err);
|
||||||
|
throw err;
|
||||||
|
} finally {
|
||||||
|
this._dropExtPromise = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleConfigUpdated(): void {
|
private handleConfigUpdated(): void {
|
||||||
|
if (this._postgresModel.config) {
|
||||||
this.extensionsLoading.loading = false;
|
this.extensionsLoading.loading = false;
|
||||||
|
this.extensionsLink.url = `https://www.postgresql.org/docs/${this._postgresModel.engineVersion}/external-extensions.html`;
|
||||||
|
this.extensionNames = [];
|
||||||
this.refreshExtensionsTable();
|
this.refreshExtensionsTable();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
extensions/arc/src/ui/dialogs/addPGExtensionsDialog.ts
Normal file
88
extensions/arc/src/ui/dialogs/addPGExtensionsDialog.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import * as azdata from 'azdata';
|
||||||
|
import { Deferred } from '../../common/promise';
|
||||||
|
import * as loc from '../../localizedConstants';
|
||||||
|
import { cssStyles } from '../../constants';
|
||||||
|
import { InitializingComponent } from '../components/initializingComponent';
|
||||||
|
import { PostgresModel } from '../../models/postgresModel';
|
||||||
|
|
||||||
|
export class AddPGExtensionsDialog extends InitializingComponent {
|
||||||
|
protected modelBuilder!: azdata.ModelBuilder;
|
||||||
|
|
||||||
|
protected extensionsListInputBox!: azdata.InputBoxComponent;
|
||||||
|
|
||||||
|
protected _completionPromise = new Deferred<string | undefined>();
|
||||||
|
|
||||||
|
constructor(protected _model: PostgresModel) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public showDialog(dialogTitle: string): azdata.window.Dialog {
|
||||||
|
const dialog = azdata.window.createModelViewDialog(dialogTitle);
|
||||||
|
dialog.cancelButton.onClick(() => this.handleCancel());
|
||||||
|
dialog.registerContent(async view => {
|
||||||
|
this.modelBuilder = view.modelBuilder;
|
||||||
|
|
||||||
|
const info = this.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
|
||||||
|
value: loc.extensionsFunction,
|
||||||
|
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
const link = this.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({
|
||||||
|
label: loc.extensionsLearnMore,
|
||||||
|
url: 'https://docs.microsoft.com/azure/azure-arc/data/using-extensions-in-postgresql-hyperscale-server-group',
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
const infoAndLink = this.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component();
|
||||||
|
infoAndLink.addItem(info, { CSSStyles: { 'margin-right': '5px' } });
|
||||||
|
infoAndLink.addItem(link);
|
||||||
|
|
||||||
|
this.extensionsListInputBox = this.modelBuilder.inputBox()
|
||||||
|
.withProperties<azdata.InputBoxProperties>({
|
||||||
|
value: '',
|
||||||
|
ariaLabel: loc.extensionsAddList,
|
||||||
|
enabled: true
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
let formModel = this.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
component: infoAndLink
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: this.extensionsListInputBox,
|
||||||
|
title: loc.extensionsAddList
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: ''
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
this.extensionsListInputBox.focus();
|
||||||
|
this.initialized = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.registerCloseValidator(async () => await this.validate());
|
||||||
|
dialog.okButton.label = loc.addExtensions;
|
||||||
|
dialog.cancelButton.label = loc.cancel;
|
||||||
|
azdata.window.openDialog(dialog);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async validate(): Promise<boolean> {
|
||||||
|
this._completionPromise.resolve(this.extensionsListInputBox.value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleCancel(): void {
|
||||||
|
this._completionPromise.resolve(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
public waitForClose(): Promise<string | undefined> {
|
||||||
|
return this._completionPromise.promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user