mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 09:59:47 -05:00
Exclude Object Types Coming from DacFx and tests all working as expected (#20015)
* Include Objects Coming from DacFx and tests all working as expected * Exclude Object types functionality is working as expected and Unit tests * more refactor updates * Updated comments and prop name * Addressing the coments and code updates accordingly * Updating according to the comments * STS vbump * These changes should be deleted with SC changes, not here * format fixed
This commit is contained in:
committed by
GitHub
parent
66115d8f80
commit
2b5d2f0a0b
@@ -149,11 +149,12 @@ export const nameMustNotBeEmpty = localize('nameMustNotBeEmpty', "Name must not
|
||||
export const AdvancedOptionsButton = localize('advancedOptionsButton', 'Advanced...');
|
||||
export const AdvancedPublishOptions = localize('advancedPublishOptions', 'Advanced Publish Options');
|
||||
export const PublishOptions = localize('publishOptions', 'Publish Options');
|
||||
export const ExcludeObjectTypeTab = localize('excludeObjectTypes', 'Exclude Object Types');
|
||||
export const ResetButton: string = localize('reset', "Reset");
|
||||
export const OptionDescription: string = localize('optionDescription', "Option Description");
|
||||
export const OptionName: string = localize('optionName', "Option Name");
|
||||
export const OptionInclude: string = localize('Include', "Include");
|
||||
export function OptionNotFoundWarningMessage(label: string) { return localize('OptionNotFoundWarningMessage', "label: {0} does not exist in the options value name lookup", label); }
|
||||
export const OptionInclude: string = localize('include', "Include");
|
||||
export function OptionNotFoundWarningMessage(label: string) { return localize('optionNotFoundWarningMessage', "label: {0} does not exist in the options value name lookup", label); }
|
||||
|
||||
// Deploy
|
||||
export const SqlServerName = 'SQL server';
|
||||
|
||||
@@ -325,13 +325,6 @@ export async function defaultAzureAccountServiceFactory(): Promise<vscodeMssql.I
|
||||
export async function getDefaultPublishDeploymentOptions(project: ISqlProject): Promise<mssql.DeploymentOptions | vscodeMssql.DeploymentOptions> {
|
||||
const schemaCompareService = await getSchemaCompareService();
|
||||
const result = await schemaCompareService.schemaCompareGetDefaultOptions();
|
||||
// re-include database-scoped credentials
|
||||
if (getAzdataApi()) {
|
||||
result.defaultDeploymentOptions.excludeObjectTypes.value = (result.defaultDeploymentOptions as mssql.DeploymentOptions).excludeObjectTypes.value?.filter(x => x !== mssql.SchemaObjectType.DatabaseScopedCredentials);
|
||||
} else {
|
||||
result.defaultDeploymentOptions.excludeObjectTypes.value = (result.defaultDeploymentOptions as vscodeMssql.DeploymentOptions).excludeObjectTypes.value?.filter(x => x !== vscodeMssql.SchemaObjectType.DatabaseScopedCredentials);
|
||||
}
|
||||
|
||||
// this option needs to be true for same database references validation to work
|
||||
if (project.databaseReferences.length > 0) {
|
||||
result.defaultDeploymentOptions.booleanOptionsDictionary.includeCompositeObjects.value = true;
|
||||
|
||||
@@ -145,7 +145,6 @@ export class PublishDatabaseDialog {
|
||||
this.connectionRow = this.createConnectionRow(view);
|
||||
this.databaseRow = this.createDatabaseRow(view);
|
||||
const displayOptionsButton = this.createOptionsButton(view);
|
||||
displayOptionsButton.enabled = false;
|
||||
|
||||
const horizontalFormSection = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
horizontalFormSection.addItems([profileRow, this.databaseRow]);
|
||||
@@ -172,12 +171,10 @@ export class PublishDatabaseDialog {
|
||||
title: constants.selectConnectionRadioButtonsTitle,
|
||||
component: selectConnectionRadioButtons
|
||||
},*/
|
||||
/* TODO : Disabling deployment options for the July release
|
||||
{
|
||||
component: displayOptionsButton,
|
||||
title: ''
|
||||
}
|
||||
*/
|
||||
]
|
||||
}
|
||||
], {
|
||||
@@ -938,7 +935,12 @@ export class PublishDatabaseDialog {
|
||||
* Gets the default deployment options from the dacfx service
|
||||
*/
|
||||
public async getDefaultDeploymentOptions(): Promise<DeploymentOptions> {
|
||||
return await utils.getDefaultPublishDeploymentOptions(this.project) as DeploymentOptions;
|
||||
const defaultDeploymentOptions = await utils.getDefaultPublishDeploymentOptions(this.project) as DeploymentOptions;
|
||||
if (defaultDeploymentOptions && defaultDeploymentOptions.excludeObjectTypes !== undefined) {
|
||||
// For publish dialog no default exclude options should exists
|
||||
defaultDeploymentOptions.excludeObjectTypes.value = [];
|
||||
}
|
||||
return defaultDeploymentOptions;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,6 +24,9 @@ export class PublishOptionsDialog {
|
||||
private optionsFlexBuilder: azdataType.FlexContainer | undefined;
|
||||
private optionsChanged: boolean = false;
|
||||
private isResetOptionsClicked: boolean = false;
|
||||
private excludeObjectTypesOptionsTab: azdataType.window.DialogTab | undefined;
|
||||
private excludeObjectTypesOptionsTable: azdataType.TableComponent | undefined;
|
||||
private excludeObjectTypesOptionsFlexBuilder: azdataType.FlexContainer | undefined;
|
||||
|
||||
constructor(defaultOptions: mssql.DeploymentOptions, private publish: PublishDatabaseDialog) {
|
||||
this.optionsModel = new DeployOptionsModel(defaultOptions);
|
||||
@@ -31,8 +34,10 @@ export class PublishOptionsDialog {
|
||||
|
||||
protected initializeDialog(): void {
|
||||
this.optionsTab = utils.getAzdataApi()!.window.createTab(constants.PublishOptions);
|
||||
this.intializeDeploymentOptionsDialogTab();
|
||||
this.dialog.content = [this.optionsTab];
|
||||
this.excludeObjectTypesOptionsTab = utils.getAzdataApi()!.window.createTab(constants.ExcludeObjectTypeTab);
|
||||
this.initializeDeploymentOptionsDialogTab();
|
||||
this.initializeExcludeObjectTypesOptionsDialogTab();
|
||||
this.dialog.content = [this.optionsTab, this.excludeObjectTypesOptionsTab];
|
||||
}
|
||||
|
||||
public openDialog(): void {
|
||||
@@ -55,7 +60,7 @@ export class PublishOptionsDialog {
|
||||
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
||||
}
|
||||
|
||||
private intializeDeploymentOptionsDialogTab(): void {
|
||||
private initializeDeploymentOptionsDialogTab(): void {
|
||||
this.optionsTab?.registerContent(async view => {
|
||||
this.descriptionHeading = view.modelBuilder.table().withProps({
|
||||
data: [],
|
||||
@@ -113,6 +118,34 @@ export class PublishOptionsDialog {
|
||||
});
|
||||
}
|
||||
|
||||
private initializeExcludeObjectTypesOptionsDialogTab(): void {
|
||||
this.excludeObjectTypesOptionsTab?.registerContent(async view => {
|
||||
this.excludeObjectTypesOptionsTable = view.modelBuilder.table().component();
|
||||
await this.updateExcludeObjectsTable();
|
||||
|
||||
// Update exclude type options value on checkbox onchange
|
||||
this.disposableListeners.push(this.excludeObjectTypesOptionsTable!.onCellAction!((rowState) => {
|
||||
const checkboxState = <azdataType.ICheckboxCellActionEventArgs>rowState;
|
||||
if (checkboxState && checkboxState.row !== undefined) {
|
||||
// data[row][1] contains the exclude type option display name
|
||||
const displayName = this.excludeObjectTypesOptionsTable?.data[checkboxState.row][1];
|
||||
this.optionsModel.setExcludeObjectTypesOptionValue(displayName, checkboxState.checked);
|
||||
this.optionsChanged = true;
|
||||
// customButton[0] is the reset button, enabling it when option checkbox is changed
|
||||
this.dialog.customButtons[0].enabled = true;
|
||||
}
|
||||
}));
|
||||
|
||||
this.excludeObjectTypesOptionsFlexBuilder = view.modelBuilder.flexContainer()
|
||||
.withLayout({
|
||||
flexFlow: 'column'
|
||||
}).component();
|
||||
|
||||
this.excludeObjectTypesOptionsFlexBuilder.addItem(this.excludeObjectTypesOptionsTable, { CSSStyles: { 'overflow': 'scroll', 'height': '80vh', 'padding-top': '2px' } });
|
||||
await view.initializeModel(this.excludeObjectTypesOptionsFlexBuilder);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the default options to the options table area
|
||||
*/
|
||||
@@ -141,12 +174,41 @@ export class PublishOptionsDialog {
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the default options to the exclude objects table area
|
||||
*/
|
||||
private async updateExcludeObjectsTable(): Promise<void> {
|
||||
const data = this.optionsModel.getExcludeObjectTypesOptionsData();
|
||||
await this.excludeObjectTypesOptionsTable?.updateProperties({
|
||||
data: data,
|
||||
columns: [
|
||||
<azdataType.CheckboxColumn>
|
||||
{
|
||||
value: constants.OptionInclude,
|
||||
type: utils.getAzdataApi()!.ColumnType.checkBox,
|
||||
action: utils.getAzdataApi()!.ActionOnCellCheckboxCheck.customAction,
|
||||
headerCssClass: 'display-none',
|
||||
cssClass: 'no-borders align-with-header',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
value: constants.OptionName,
|
||||
headerCssClass: 'display-none',
|
||||
cssClass: 'no-borders align-with-header',
|
||||
width: 50
|
||||
}
|
||||
],
|
||||
ariaRowCount: data.length
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok button click, will update the deployment options with selections
|
||||
*/
|
||||
protected execute(): void {
|
||||
// Update the model deploymentoptions with the updated table component values
|
||||
// Update the model deploymentoptions with the updated options/excludeObjects table component values
|
||||
this.optionsModel.setDeploymentOptions();
|
||||
this.optionsModel.setExcludeObjectTypesToDeploymentOptions();
|
||||
// Set the publish deploymentoptions with the updated table component values
|
||||
this.publish.setDeploymentOptions(this.optionsModel.deploymentOptions);
|
||||
this.disposeListeners();
|
||||
@@ -173,14 +235,19 @@ export class PublishOptionsDialog {
|
||||
const result = await this.publish.getDefaultDeploymentOptions();
|
||||
this.optionsModel.deploymentOptions = result;
|
||||
|
||||
// reset optionsvalueNameLookup with default deployment options
|
||||
// reset optionsvalueNameLookup and excludeObjectTypesLookup with default deployment options
|
||||
this.optionsModel.setOptionsToValueNameLookup();
|
||||
this.optionsModel.setExcludeObjectTypesLookup();
|
||||
|
||||
await this.updateOptionsTable();
|
||||
this.optionsFlexBuilder?.removeItem(this.optionsTable!);
|
||||
this.optionsFlexBuilder?.insertItem(this.optionsTable!, 0, { CSSStyles: { 'overflow': 'scroll', 'height': '65vh', 'padding-top': '2px' } });
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.PublishOptionsDialog, TelemetryActions.resetOptions);
|
||||
|
||||
await this.updateExcludeObjectsTable();
|
||||
this.excludeObjectTypesOptionsFlexBuilder?.removeItem(this.excludeObjectTypesOptionsTable!);
|
||||
this.excludeObjectTypesOptionsFlexBuilder?.addItem(this.excludeObjectTypesOptionsTable!, { CSSStyles: { 'overflow': 'scroll', 'height': '80vh', 'padding-top': '2px' } });
|
||||
|
||||
// setting optionsChanged to false when reset click, if optionsChanged is true during execute, that means there is an option changed after reset
|
||||
this.isResetOptionsClicked = true;
|
||||
this.optionsChanged = false;
|
||||
|
||||
@@ -10,9 +10,11 @@ import * as constants from '../../common/constants';
|
||||
export class DeployOptionsModel {
|
||||
// key is the option display name and values are checkboxValue and optionName
|
||||
private optionsValueNameLookup: { [key: string]: mssql.IOptionWithValue } = {};
|
||||
private excludeObjectTypesLookup: { [key: string]: mssql.IOptionWithValue } = {};
|
||||
|
||||
constructor(public deploymentOptions: mssql.DeploymentOptions) {
|
||||
this.setOptionsToValueNameLookup();
|
||||
this.setExcludeObjectTypesLookup();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -69,4 +71,62 @@ export class DeployOptionsModel {
|
||||
}
|
||||
return optionName !== undefined ? this.deploymentOptions.booleanOptionsDictionary[optionName.optionName].description : '';
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets exclude object types option's checkbox values and property name to the excludeObjectTypesLookup map
|
||||
*/
|
||||
public setExcludeObjectTypesLookup(): void {
|
||||
Object.entries(this.deploymentOptions.objectTypesDictionary).forEach(option => {
|
||||
const optionValue: mssql.IOptionWithValue = {
|
||||
optionName: option[0],
|
||||
checked: this.getExcludeObjectTypeOptionCheckStatus(option[0])
|
||||
};
|
||||
this.excludeObjectTypesLookup[option[1]] = optionValue;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize options data from objectTypesDictionary for table component
|
||||
* Returns data as [booleanValue, optionName]
|
||||
*/
|
||||
public getExcludeObjectTypesOptionsData(): any[][] {
|
||||
let data: any[][] = [];
|
||||
Object.entries(this.deploymentOptions.objectTypesDictionary).forEach(option => {
|
||||
// option[1] is the display name and option[0] is the optionName
|
||||
data.push([this.getExcludeObjectTypeOptionCheckStatus(option[0]), option[1]]);
|
||||
});
|
||||
|
||||
return data.sort((a, b) => a[1].localeCompare(b[1]));
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the selected/default value of the object type option
|
||||
* return true for the deploymentOptions.excludeObjectTypes option, if it is in ObjectTypesDictionary
|
||||
*/
|
||||
public getExcludeObjectTypeOptionCheckStatus(optionName: string): boolean {
|
||||
return (this.deploymentOptions.excludeObjectTypes.value?.find(x => x.toLowerCase() === optionName.toLowerCase())) !== undefined ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the checkbox value to the excludeObjectTypesLookup map
|
||||
*/
|
||||
public setExcludeObjectTypesOptionValue(displayName: string, checked: boolean): void {
|
||||
this.excludeObjectTypesLookup[displayName].checked = checked;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the selected option checkbox value to the deployment options
|
||||
*/
|
||||
public setExcludeObjectTypesToDeploymentOptions(): void {
|
||||
let finalExcludedObjectTypes: string[] = [];
|
||||
Object.entries(this.excludeObjectTypesLookup).forEach(option => {
|
||||
// option[1] holds checkedbox value and optionName
|
||||
if (option[1].checked) {
|
||||
finalExcludedObjectTypes.push(option[1].optionName);
|
||||
}
|
||||
});
|
||||
|
||||
this.deploymentOptions.excludeObjectTypes.value = finalExcludedObjectTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('Publish Dialog Deploy Options Model', () => {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
Object.entries(model.deploymentOptions.booleanOptionsDictionary).forEach(option => {
|
||||
// option[1] contains the value, description and displayName
|
||||
should(model.getOptionDescription(option[1].displayName)).not.equal(undefined);
|
||||
should(model.getOptionDescription(option[1].displayName)).not.equal(undefined, 'publish option description should not be undefined');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,4 +27,31 @@ describe('Publish Dialog Deploy Options Model', () => {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
should(model.getOptionDescription('')).equal('');
|
||||
});
|
||||
|
||||
|
||||
it('Should have no default exclude object types', function (): void {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
should(model.deploymentOptions.excludeObjectTypes.value.length).be.equal(0, 'There should be no object types excluded from excludeObjectTypes');
|
||||
|
||||
// should return true for all object type options as there are no default excludeObjectTypes in the deployment options
|
||||
Object.keys(model.deploymentOptions.objectTypesDictionary).forEach(option => {
|
||||
should(model.getExcludeObjectTypeOptionCheckStatus(option)).equal(false, 'excludeObjectTypes property should be empty by default and return false');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should have atleast one default exclude object types', function (): void {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
model.deploymentOptions.excludeObjectTypes.value = ['SampleProperty1'];
|
||||
|
||||
should(model.deploymentOptions.excludeObjectTypes.value.length).be.equal(1, 'There should be one excluded object');
|
||||
|
||||
// should return true for all exclude object types options and false for the exising defauit option
|
||||
Object.keys(model.deploymentOptions.objectTypesDictionary).forEach(option => {
|
||||
if (option === 'SampleProperty1') {
|
||||
should(model.getExcludeObjectTypeOptionCheckStatus(option)).equal(true, 'should return true for the excludeObjectTypes SampleProperty1 ');
|
||||
} else {
|
||||
should(model.getExcludeObjectTypeOptionCheckStatus(option)).equal(false, 'should return false for all excludeObjectTypes property as it is empty');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,6 +31,10 @@ export function getDeploymentOptions(): mssql.DeploymentOptions {
|
||||
booleanOptionsDictionary: {
|
||||
'SampleProperty1': { value: false, description: sampleDesc, displayName: sampleName },
|
||||
'SampleProperty2': { value: false, description: sampleDesc, displayName: sampleName }
|
||||
},
|
||||
objectTypesDictionary: {
|
||||
'SampleProperty1': sampleName,
|
||||
'SampleProperty2': sampleName
|
||||
}
|
||||
};
|
||||
return defaultOptions;
|
||||
|
||||
Reference in New Issue
Block a user