mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Add generate script option to DacFx wizard (#3789)
* Add generate script option to deploy scenario * add action to summary page and fixed page adding/removing so that summary page will have the correct step number * updating contract based on change in sqltoolsservice * added enums to make index checks more clear * cleaned up onPageChanged() * bump sqltoolsservice version to 68
This commit is contained in:
@@ -49,6 +49,14 @@ export class DacFxSummaryPage extends BasePage {
|
||||
async onPageEnter(): Promise<boolean> {
|
||||
this.populateTable();
|
||||
this.loader.loading = false;
|
||||
if (this.model.upgradeExisting && this.model.generateScriptAndDeploy) {
|
||||
this.instance.wizard.generateScriptButton.hidden = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async onPageLeave(): Promise<boolean> {
|
||||
this.instance.wizard.generateScriptButton.hidden = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -68,6 +76,10 @@ export class DacFxSummaryPage extends BasePage {
|
||||
let sourceServer = localize('dacfx.sourceServerName', 'Source Server');
|
||||
let sourceDatabase = localize('dacfx.sourceDatabaseName', 'Source Database');
|
||||
let fileLocation = localize('dacfx.fileLocation', 'File Location');
|
||||
let scriptLocation = localize('dacfx.scriptLocation', 'Deployment Script Location');
|
||||
let action = localize('dacfx.action', 'Action');
|
||||
let deploy = localize('dacfx.deploy', 'Deploy');
|
||||
let generateScript = localize('dacfx.generateScript', 'Generate Deployment Script');
|
||||
|
||||
switch (this.instance.selectedOperation) {
|
||||
case Operation.deploy: {
|
||||
@@ -75,6 +87,13 @@ export class DacFxSummaryPage extends BasePage {
|
||||
[targetServer, this.model.serverName],
|
||||
[fileLocation, this.model.filePath],
|
||||
[targetDatabase, this.model.database]];
|
||||
if (this.model.generateScriptAndDeploy) {
|
||||
data[3] = [scriptLocation, this.model.scriptFilePath];
|
||||
data[4] = [action, generateScript + ', ' + deploy];
|
||||
}
|
||||
else {
|
||||
data[3] = [action, deploy];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Operation.extract: {
|
||||
@@ -99,12 +118,21 @@ export class DacFxSummaryPage extends BasePage {
|
||||
[fileLocation, this.model.filePath]];
|
||||
break;
|
||||
}
|
||||
case Operation.generateDeployScript: {
|
||||
data = [
|
||||
[targetServer, this.model.serverName],
|
||||
[fileLocation, this.model.filePath],
|
||||
[targetDatabase, this.model.database],
|
||||
[scriptLocation, this.model.scriptFilePath],
|
||||
[action, generateScript]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.table.updateProperties({
|
||||
data: data,
|
||||
columns: ['Setting', 'Value'],
|
||||
width: 600,
|
||||
width: 700,
|
||||
height: 200
|
||||
});
|
||||
}
|
||||
|
||||
176
extensions/import/src/wizard/pages/deployActionPage.ts
Normal file
176
extensions/import/src/wizard/pages/deployActionPage.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { DacFxDataModel } from '../api/models';
|
||||
import { DataTierApplicationWizard, Operation } from '../dataTierApplicationWizard';
|
||||
import { DacFxConfigPage } from '../api/dacFxConfigPage';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class DeployActionPage extends DacFxConfigPage {
|
||||
|
||||
protected readonly wizardPage: sqlops.window.modelviewdialog.WizardPage;
|
||||
protected readonly instance: DataTierApplicationWizard;
|
||||
protected readonly model: DacFxDataModel;
|
||||
protected readonly view: sqlops.ModelView;
|
||||
private deployRadioButton: sqlops.RadioButtonComponent;
|
||||
private deployScriptRadioButton: sqlops.RadioButtonComponent;
|
||||
private scriptRadioButton: sqlops.RadioButtonComponent;
|
||||
private form: sqlops.FormContainer;
|
||||
|
||||
public constructor(instance: DataTierApplicationWizard, wizardPage: sqlops.window.modelviewdialog.WizardPage, model: DacFxDataModel, view: sqlops.ModelView) {
|
||||
super(instance, wizardPage, model, view);
|
||||
}
|
||||
|
||||
async start(): Promise<boolean> {
|
||||
let deployComponent = await this.createDeployRadioButton();
|
||||
let deployScriptComponent = await this.createDeployScriptRadioButton();
|
||||
let scriptComponent = await this.createScriptRadioButton();
|
||||
let fileBrowserComponent = await this.createFileBrowser();
|
||||
|
||||
this.form = this.view.modelBuilder.formContainer()
|
||||
.withFormItems(
|
||||
[
|
||||
deployComponent,
|
||||
scriptComponent,
|
||||
deployScriptComponent,
|
||||
fileBrowserComponent
|
||||
]).component();
|
||||
await this.view.initializeModel(this.form);
|
||||
|
||||
//default have the first radio button checked
|
||||
this.deployRadioButton.checked = true;
|
||||
this.toggleFileBrowser(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async onPageEnter(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private async createDeployRadioButton(): Promise<sqlops.FormComponent> {
|
||||
this.deployRadioButton = this.view.modelBuilder.radioButton()
|
||||
.withProperties({
|
||||
name: 'selectedDeployAction',
|
||||
label: localize('dacFx.deployRadioButtonLabel', 'Deploy'),
|
||||
}).component();
|
||||
|
||||
this.deployRadioButton.onDidClick(() => {
|
||||
this.model.generateScriptAndDeploy = false;
|
||||
this.instance.setDoneButton(Operation.deploy);
|
||||
this.toggleFileBrowser(false);
|
||||
});
|
||||
|
||||
return {
|
||||
component: this.deployRadioButton,
|
||||
title: ''
|
||||
};
|
||||
}
|
||||
|
||||
private async createDeployScriptRadioButton(): Promise<sqlops.FormComponent> {
|
||||
this.deployScriptRadioButton = this.view.modelBuilder.radioButton()
|
||||
.withProperties({
|
||||
name: 'selectedDeployAction',
|
||||
label: localize('dacFx.deployScriptRadioButtonLabel', 'Generate Deployment Script and Deploy'),
|
||||
}).component();
|
||||
|
||||
this.deployScriptRadioButton.onDidClick(() => {
|
||||
this.model.generateScriptAndDeploy = true;
|
||||
this.instance.setDoneButton(Operation.deploy);
|
||||
this.toggleFileBrowser(true);
|
||||
});
|
||||
|
||||
return {
|
||||
component: this.deployScriptRadioButton,
|
||||
title: ''
|
||||
};
|
||||
}
|
||||
|
||||
private async createScriptRadioButton(): Promise<sqlops.FormComponent> {
|
||||
this.scriptRadioButton = this.view.modelBuilder.radioButton()
|
||||
.withProperties({
|
||||
name: 'selectedDeployAction',
|
||||
label: localize('dacFx.scriptRadioButtonLabel', 'Generate Deployment Script'),
|
||||
}).component();
|
||||
|
||||
this.scriptRadioButton.onDidClick(() => {
|
||||
this.model.generateScriptAndDeploy = false;
|
||||
this.toggleFileBrowser(true);
|
||||
|
||||
//change button text and operation
|
||||
this.instance.setDoneButton(Operation.generateDeployScript);
|
||||
});
|
||||
|
||||
return {
|
||||
component: this.scriptRadioButton,
|
||||
title: ''
|
||||
};
|
||||
}
|
||||
|
||||
private async createFileBrowser(): Promise<sqlops.FormComponentGroup> {
|
||||
this.createFileBrowserParts();
|
||||
|
||||
//default filepath
|
||||
let now = new Date();
|
||||
let datetime = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + '-' + now.getHours() + '-' + now.getMinutes();
|
||||
this.fileTextBox.value= path.join(os.homedir(), this.model.database + '_UpgradeDACScript_' + datetime + '.sql');
|
||||
this.model.scriptFilePath = this.fileTextBox.value;
|
||||
|
||||
this.fileButton.onDidClick(async (click) => {
|
||||
let fileUri = await vscode.window.showSaveDialog(
|
||||
{
|
||||
defaultUri: vscode.Uri.file(this.fileTextBox.value),
|
||||
saveLabel: localize('dacfxDeployScript.saveFile', 'Save'),
|
||||
filters: {
|
||||
'SQL Files': ['sql'],
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!fileUri) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fileTextBox.value = fileUri.fsPath;
|
||||
this.model.scriptFilePath = fileUri.fsPath;
|
||||
});
|
||||
|
||||
this.fileTextBox.onTextChanged(async () => {
|
||||
this.model.scriptFilePath = this.fileTextBox.value;
|
||||
});
|
||||
|
||||
return {
|
||||
title: '',
|
||||
components: [
|
||||
{
|
||||
title: localize('dacfx.generatedScriptLocation','Deployment Script Location'),
|
||||
component: this.fileTextBox,
|
||||
layout: {
|
||||
horizontal: true,
|
||||
componentWidth: 400
|
||||
},
|
||||
actions: [this.fileButton]
|
||||
},],
|
||||
};
|
||||
}
|
||||
|
||||
private toggleFileBrowser(enable: boolean): void {
|
||||
this.fileTextBox.enabled = enable;
|
||||
this.fileButton.enabled = enable;
|
||||
}
|
||||
|
||||
public setupNavigationValidator() {
|
||||
this.instance.registerNavigationValidator(() => {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -58,11 +58,6 @@ export class SelectOperationPage extends BasePage {
|
||||
}
|
||||
|
||||
async onPageEnter(): Promise<boolean> {
|
||||
let numPages = this.instance.wizard.pages.length;
|
||||
for (let i = numPages - 1; i > 2; --i) {
|
||||
await this.instance.wizard.removePage(i);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,12 +69,14 @@ export class SelectOperationPage extends BasePage {
|
||||
}).component();
|
||||
|
||||
this.deployRadioButton.onDidClick(() => {
|
||||
// remove the previous page
|
||||
this.instance.wizard.removePage(1);
|
||||
this.removePages();
|
||||
|
||||
// add deploy page
|
||||
let page = this.instance.pages.get('deployConfig');
|
||||
this.instance.wizard.addPage(page.wizardPage, 1);
|
||||
//add deploy pages
|
||||
let configPage = this.instance.pages.get('deployConfig');
|
||||
this.instance.wizard.addPage(configPage.wizardPage, 1);
|
||||
let actionPage = this.instance.pages.get('deployAction');
|
||||
this.instance.wizard.addPage(actionPage.wizardPage, 2);
|
||||
this.addSummaryPage(3);
|
||||
|
||||
// change button text and operation
|
||||
this.instance.setDoneButton(Operation.deploy);
|
||||
@@ -99,12 +96,12 @@ export class SelectOperationPage extends BasePage {
|
||||
}).component();
|
||||
|
||||
this.extractRadioButton.onDidClick(() => {
|
||||
// remove the previous pages
|
||||
this.instance.wizard.removePage(1);
|
||||
this.removePages();
|
||||
|
||||
// add the extract page
|
||||
let page = this.instance.pages.get('extractConfig');
|
||||
this.instance.wizard.addPage(page.wizardPage, 1);
|
||||
this.addSummaryPage(2);
|
||||
|
||||
// change button text and operation
|
||||
this.instance.setDoneButton(Operation.extract);
|
||||
@@ -124,12 +121,12 @@ export class SelectOperationPage extends BasePage {
|
||||
}).component();
|
||||
|
||||
this.importRadioButton.onDidClick(() => {
|
||||
// remove the previous page
|
||||
this.instance.wizard.removePage(1);
|
||||
this.removePages();
|
||||
|
||||
// add the import page
|
||||
let page = this.instance.pages.get('importConfig');
|
||||
this.instance.wizard.addPage(page.wizardPage, 1);
|
||||
this.addSummaryPage(2);
|
||||
|
||||
// change button text and operation
|
||||
this.instance.setDoneButton(Operation.import);
|
||||
@@ -149,12 +146,12 @@ export class SelectOperationPage extends BasePage {
|
||||
}).component();
|
||||
|
||||
this.exportRadioButton.onDidClick(() => {
|
||||
// remove the 2 previous pages
|
||||
this.instance.wizard.removePage(1);
|
||||
this.removePages();
|
||||
|
||||
// add the export pages
|
||||
let page = this.instance.pages.get('exportConfig');
|
||||
this.instance.wizard.addPage(page.wizardPage, 1);
|
||||
this.addSummaryPage(2);
|
||||
|
||||
// change button text and operation
|
||||
this.instance.setDoneButton(Operation.export);
|
||||
@@ -166,6 +163,18 @@ export class SelectOperationPage extends BasePage {
|
||||
};
|
||||
}
|
||||
|
||||
private removePages() {
|
||||
let numPages = this.instance.wizard.pages.length;
|
||||
for (let i = numPages - 1; i > 0; --i) {
|
||||
this.instance.wizard.removePage(i);
|
||||
}
|
||||
}
|
||||
|
||||
private addSummaryPage(index: number) {
|
||||
let summaryPage = this.instance.pages.get('summary');
|
||||
this.instance.wizard.addPage(summaryPage.wizardPage, index);
|
||||
}
|
||||
|
||||
public setupNavigationValidator() {
|
||||
this.instance.registerNavigationValidator(() => {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user