Add nupkg option to add database reference dialog (#22772)

* add nupkg option to add database reference dialog

* Add required indicator

* only show nupkg radio button for SDK-style projects

* fix enable ok button

* hookup

* fix typo
This commit is contained in:
Kim Santiago
2023-04-19 10:09:15 -07:00
committed by GitHub
parent c29bb27d9e
commit 39a28c5f51
3 changed files with 111 additions and 10 deletions

View File

@@ -292,6 +292,10 @@ export const referenceRadioButtonsGroupTitle = localize('referenceRadioButtonsGr
export const projectLabel = localize('projectLocString', "Project");
export const systemDatabase = localize('systemDatabase', "System database");
export const dacpacText = localize('dacpacText', "Data-tier application (.dacpac)");
export const nupkgText = localize('nupkgText', "Published data-tier application (.nupkg)");
export const nupkgNamePlaceholder = localize('nupkgNamePlaceholder', "NuGet package name");
export const version = localize('version', "Version");
export const versionPlaceholder = localize('versionPlaceholder', "NuGet package version");
export const selectDacpac = localize('selectDacpac', "Select .dacpac");
export const sameDatabase = localize('sameDatabase', "Same database");
export const differentDbSameServer = localize('differentDbSameServer', "Different database, same server");

View File

@@ -27,7 +27,7 @@ import { ShellCommandOptions } from '../tools/shellExecutionHelper';
import { BuildHelper } from '../tools/buildHelper';
import { readPublishProfile, savePublishProfile } from '../models/publishProfile/publishProfile';
import { AddDatabaseReferenceDialog } from '../dialogs/addDatabaseReferenceDialog';
import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings } from '../models/IDatabaseReferenceSettings';
import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings, INugetPackageReferenceSettings } from '../models/IDatabaseReferenceSettings';
import { DatabaseReferenceTreeItem } from '../models/tree/databaseReferencesTreeItem';
import { CreateProjectFromDatabaseDialog } from '../dialogs/createProjectFromDatabaseDialog';
import { UpdateProjectFromDatabaseDialog } from '../dialogs/updateProjectFromDatabaseDialog';
@@ -65,7 +65,7 @@ export enum TaskExecutionMode {
executeAndScript = 2
}
export type AddDatabaseReferenceSettings = ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings;
export type AddDatabaseReferenceSettings = ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings | INugetPackageReferenceSettings;
interface FileWatcherStatus {
fileWatcher: vscode.FileSystemWatcher;
@@ -1193,11 +1193,13 @@ export class ProjectsController {
await project.addProjectReference(projectReferenceSettings);
} else if ((<ISystemDatabaseReferenceSettings>settings).systemDb !== undefined) {
await project.addSystemDatabaseReference(<ISystemDatabaseReferenceSettings>settings);
} else {
} else if ((<IDacpacReferenceSettings>settings).dacpacFileLocation !== undefined) {
// update dacpacFileLocation to relative path to project file
const dacpacRefSettings = settings as IDacpacReferenceSettings;
dacpacRefSettings.dacpacFileLocation = vscode.Uri.file(path.relative(project.projectFolderPath, dacpacRefSettings.dacpacFileLocation.fsPath));
await project.addDatabaseReference(dacpacRefSettings);
} else {
await project.addNugetPackageReference(<INugetPackageReferenceSettings>settings);
}
this.refreshProjectsTree(context);

View File

@@ -12,16 +12,17 @@ import * as utils from '../common/utils';
import { Project } from '../models/project';
import { cssStyles } from '../common/uiConstants';
import { IconPathHelper } from '../common/iconHelper';
import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings } from '../models/IDatabaseReferenceSettings';
import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings, INugetPackageReferenceSettings } from '../models/IDatabaseReferenceSettings';
import { Deferred } from '../common/promise';
import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry';
import { SystemDatabase } from 'mssql';
import { ProjectType, SystemDatabase } from 'mssql';
import { DbServerValues, ensureSetOrDefined, populateResultWithVars } from './utils';
export enum ReferenceType {
project,
systemDb,
dacpac
dacpac,
nupkg
}
export class AddDatabaseReferenceDialog {
@@ -35,6 +36,9 @@ export class AddDatabaseReferenceDialog {
private systemDatabaseFormComponent: azdataType.FormComponent | undefined;
public dacpacTextbox: azdataType.InputBoxComponent | undefined;
private dacpacFormComponent: azdataType.FormComponent | undefined;
public nupkgNameTextbox: azdataType.InputBoxComponent | undefined;
public nupkgVersionTextbox: azdataType.InputBoxComponent | undefined;
private nupkgFormComponent: azdataType.FormComponentGroup | undefined;
public locationDropdown: azdataType.DropDownComponent | undefined;
public databaseNameTextbox: azdataType.InputBoxComponent | undefined;
public databaseVariableTextbox: azdataType.InputBoxComponent | undefined;
@@ -50,7 +54,7 @@ export class AddDatabaseReferenceDialog {
private toDispose: vscode.Disposable[] = [];
private initDialogComplete: Deferred = new Deferred();
public addReference: ((proj: Project, settings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings) => any) | undefined;
public addReference: ((proj: Project, settings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings | INugetPackageReferenceSettings) => any) | undefined;
constructor(private project: Project) {
this.dialog = utils.getAzdataApi()!.window.createModelViewDialog(constants.addDatabaseReferenceDialogName, 'addDatabaseReferencesDialog');
@@ -106,6 +110,7 @@ export class AddDatabaseReferenceDialog {
const radioButtonGroup = this.createRadioButtons();
this.systemDatabaseFormComponent = this.createSystemDatabaseDropdown();
this.dacpacFormComponent = this.createDacpacTextbox();
this.nupkgFormComponent = this.createNupkgFormComponentGroup();
const locationDropdown = this.createLocationDropdown();
const variableSection = this.createVariableSection();
this.suppressMissingDependenciesErrorsCheckbox = view.modelBuilder.checkBox().withProps({
@@ -150,7 +155,7 @@ export class AddDatabaseReferenceDialog {
}
public async addReferenceClick(): Promise<void> {
let referenceSettings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings;
let referenceSettings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings | INugetPackageReferenceSettings;
if (this.currentReferenceType === ReferenceType.systemDb) {
const systemDbRef: ISystemDatabaseReferenceSettings = {
@@ -170,7 +175,7 @@ export class AddDatabaseReferenceDialog {
};
referenceSettings = projRef;
} else { // this.currentReferenceType === ReferenceType.dacpac
} else if (this.currentReferenceType === ReferenceType.dacpac) {
const dacpacRef: IDacpacReferenceSettings = {
databaseName: ensureSetOrDefined(this.databaseNameTextbox?.value),
dacpacFileLocation: vscode.Uri.file(<string>this.dacpacTextbox?.value),
@@ -178,6 +183,14 @@ export class AddDatabaseReferenceDialog {
};
referenceSettings = dacpacRef;
} else { // this.currentReferenceType === ReferenceType.nupkg
const nupkgRef: INugetPackageReferenceSettings = {
packageName: <string>this.nupkgNameTextbox?.value,
packageVersion: <string>this.nupkgVersionTextbox?.value,
suppressMissingDependenciesErrors: <boolean>this.suppressMissingDependenciesErrorsCheckbox?.checked
}
referenceSettings = nupkgRef;
}
const dbServerValues: DbServerValues = {
@@ -236,6 +249,18 @@ export class AddDatabaseReferenceDialog {
}
});
const nupkgRadioButton = this.view!.modelBuilder.radioButton()
.withProps({
name: 'referenceType',
label: constants.nupkgText
}).component();
nupkgRadioButton.onDidChangeCheckedState((checked) => {
if (checked) {
this.nupkgRadioButtonClick();
}
});
if (this.projectDropdown?.values?.length) {
this.projectRadioButton.checked = true;
this.currentReferenceType = ReferenceType.project;
@@ -247,9 +272,16 @@ export class AddDatabaseReferenceDialog {
this.projectRadioButton.enabled = false;
}
const radioButtons = [this.projectRadioButton, this.systemDatabaseRadioButton, dacpacRadioButton];
// only add the nupkg radio button for SDK-style projects
if (this.project.sqlProjStyle === ProjectType.SdkStyle) {
radioButtons.push(nupkgRadioButton);
}
let flexRadioButtonsModel: azdataType.FlexContainer = this.view!.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'column' })
.withItems([this.projectRadioButton, this.systemDatabaseRadioButton, dacpacRadioButton])
.withItems(radioButtons)
.withProps({ ariaRole: 'radiogroup', ariaLabel: constants.referenceRadioButtonsGroupTitle })
.component();
@@ -262,6 +294,7 @@ export class AddDatabaseReferenceDialog {
public projectRadioButtonClick(): void {
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.dacpacFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.systemDatabaseFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponentGroup>this.nupkgFormComponent);
this.formBuilder!.insertFormItem(<azdataType.FormComponent>this.projectFormComponent, 2);
this.locationDropdown!.values = constants.locationDropdownValues;
@@ -275,6 +308,7 @@ export class AddDatabaseReferenceDialog {
public systemDbRadioButtonClick(): void {
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.dacpacFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.projectFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponentGroup>this.nupkgFormComponent);
this.formBuilder!.insertFormItem(<azdataType.FormComponent>this.systemDatabaseFormComponent, 2);
// update dropdown values because only different database, same server is a valid location for system db references
@@ -290,6 +324,7 @@ export class AddDatabaseReferenceDialog {
public dacpacRadioButtonClick(): void {
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.systemDatabaseFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.projectFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponentGroup>this.nupkgFormComponent);
this.formBuilder!.insertFormItem(<azdataType.FormComponent>this.dacpacFormComponent, 2);
this.locationDropdown!.values = constants.locationDropdownValues;
@@ -300,6 +335,20 @@ export class AddDatabaseReferenceDialog {
this.updateExampleUsage();
}
public nupkgRadioButtonClick(): void {
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.systemDatabaseFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.projectFormComponent);
this.formBuilder!.removeFormItem(<azdataType.FormComponent>this.dacpacFormComponent);
this.formBuilder!.insertFormItem(<azdataType.FormComponentGroup>this.nupkgFormComponent, 2);
this.locationDropdown!.values = constants.locationDropdownValues;
this.currentReferenceType = ReferenceType.nupkg;
this.updateEnabledInputBoxes();
this.tryEnableAddReferenceButton();
this.updateExampleUsage();
}
private async createProjectDropdown(): Promise<azdataType.FormComponent> {
this.projectDropdown = this.view!.modelBuilder.dropDown().withProps({
ariaLabel: constants.databaseProject
@@ -361,6 +410,34 @@ export class AddDatabaseReferenceDialog {
};
}
private createNupkgFormComponentGroup(): azdataType.FormComponentGroup {
this.nupkgNameTextbox = this.view!.modelBuilder.inputBox().withProps({
ariaLabel: constants.nupkgText,
placeHolder: constants.nupkgNamePlaceholder,
required: true
}).component();
this.nupkgVersionTextbox = this.view!.modelBuilder.inputBox().withProps({
ariaLabel: constants.version,
placeHolder: constants.versionPlaceholder,
required: true
}).component();
return {
components: [
{
title: constants.nupkgText,
component: this.nupkgNameTextbox
},
{
title: constants.version,
component: this.nupkgVersionTextbox
}
],
title: ''
}
}
private createLoadDacpacButton(): azdataType.ButtonComponent {
const loadDacpacButton = this.view!.modelBuilder.button().withProps({
ariaLabel: constants.selectDacpac,
@@ -466,6 +543,12 @@ export class AddDatabaseReferenceDialog {
this.databaseVariableTextbox!.value = dacpacName ? `${dacpacName}` : '';
break;
}
case ReferenceType.nupkg: {
const nupkgName = this.nupkgNameTextbox!.value ? path.parse(this.nupkgNameTextbox!.value!).name : '';
this.databaseNameTextbox!.value = nupkgName;
this.databaseVariableTextbox!.value = nupkgName ? `${nupkgName}` : '';
break;
}
}
}
}
@@ -603,6 +686,10 @@ export class AddDatabaseReferenceDialog {
this.dialog.okButton.enabled = this.dacpacRequiredFieldsFilled();
break;
}
case ReferenceType.nupkg: {
this.dialog.okButton.enabled = this.nupkgRequiredFieldsFilled();
break;
}
}
}
@@ -621,6 +708,14 @@ export class AddDatabaseReferenceDialog {
|| ((this.locationDropdown?.value === constants.differentDbDifferentServer && this.differentDatabaseDifferentServerRequiredFieldsFilled())));
}
private nupkgRequiredFieldsFilled(): boolean {
return !!this.nupkgNameTextbox?.value
&& !!this.nupkgVersionTextbox?.value
&& ((this.locationDropdown?.value === constants.sameDatabase)
|| (this.locationDropdown?.value === constants.differentDbSameServer && this.differentDatabaseSameServerRequiredFieldsFilled())
|| ((this.locationDropdown?.value === constants.differentDbDifferentServer && this.differentDatabaseDifferentServerRequiredFieldsFilled())));
}
private differentDatabaseSameServerRequiredFieldsFilled(): boolean {
return !!this.databaseNameTextbox?.value;
}