mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 11:01:37 -05:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8eb7bec1b | ||
|
|
565b7404f9 | ||
|
|
9cffe4d476 | ||
|
|
43be88a37c | ||
|
|
ea67859de7 | ||
|
|
c8986464ec | ||
|
|
7804f94d8b | ||
|
|
bfa77aebfc | ||
|
|
487fb02313 | ||
|
|
ef64038107 | ||
|
|
5d336accbc | ||
|
|
99047b2866 | ||
|
|
f611cf3b5a | ||
|
|
4ad059605c | ||
|
|
dc2ff97dd8 | ||
|
|
2b5265c103 | ||
|
|
2e98fde053 | ||
|
|
d5176e0eb7 | ||
|
|
eb0b2a847b | ||
|
|
cff5482f69 | ||
|
|
afc37973d0 | ||
|
|
3eada6c6ab | ||
|
|
7c39268fe5 | ||
|
|
eb67b299de | ||
|
|
3e7a09c1e3 |
10
.vscode/launch.json
vendored
10
.vscode/launch.json
vendored
@@ -152,6 +152,16 @@
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}/extensions/debug-auto-launch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Smoke Test",
|
||||
"program": "${workspaceFolder}/test/smoke/test/index.js",
|
||||
"cwd": "${workspaceFolder}/test/smoke",
|
||||
"env": {
|
||||
"BUILD_ARTIFACTSTAGINGDIRECTORY": "${workspaceFolder}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
|
||||
@@ -65,6 +65,8 @@ const excludedExtensions = [
|
||||
'vscode-colorize-tests',
|
||||
'ms-vscode.node-debug',
|
||||
'ms-vscode.node-debug2',
|
||||
// {{SQL CARBON EDIT}}
|
||||
'integration-tests',
|
||||
];
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
|
||||
@@ -26,6 +26,7 @@ export class JobData implements IAgentDialogData {
|
||||
private _operators: string[];
|
||||
private _defaultOwner: string;
|
||||
private _jobCompletionActionConditions: sqlops.CategoryValue[];
|
||||
private _jobCategoryIdsMap: sqlops.AgentJobCategory[];
|
||||
|
||||
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
|
||||
public name: string;
|
||||
@@ -46,6 +47,7 @@ export class JobData implements IAgentDialogData {
|
||||
public alerts: sqlops.AgentAlertInfo[];
|
||||
public jobId: string;
|
||||
public startStepId: number;
|
||||
public categoryType: number;
|
||||
|
||||
constructor(
|
||||
ownerUri: string,
|
||||
@@ -66,6 +68,8 @@ export class JobData implements IAgentDialogData {
|
||||
this.alerts = jobInfo.alerts;
|
||||
this.jobId = jobInfo.jobId;
|
||||
this.startStepId = jobInfo.startStepId;
|
||||
this.categoryId = jobInfo.categoryId;
|
||||
this.categoryType = jobInfo.categoryType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +77,10 @@ export class JobData implements IAgentDialogData {
|
||||
return this._jobCategories;
|
||||
}
|
||||
|
||||
public get jobCategoryIdsMap(): sqlops.AgentJobCategory[] {
|
||||
return this._jobCategoryIdsMap;
|
||||
}
|
||||
|
||||
public get operators(): string[] {
|
||||
return this._operators;
|
||||
}
|
||||
@@ -96,7 +104,7 @@ export class JobData implements IAgentDialogData {
|
||||
this._jobCategories = jobDefaults.categories.map((cat) => {
|
||||
return cat.name;
|
||||
});
|
||||
|
||||
this._jobCategoryIdsMap = jobDefaults.categories;
|
||||
this._defaultOwner = jobDefaults.owner;
|
||||
|
||||
this._operators = ['', this._defaultOwner];
|
||||
@@ -164,8 +172,8 @@ export class JobData implements IAgentDialogData {
|
||||
hasSchedule: false,
|
||||
hasStep: false,
|
||||
runnable: true,
|
||||
categoryId: 0,
|
||||
categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS
|
||||
categoryId: this.categoryId,
|
||||
categoryType: this.categoryType,
|
||||
lastRun: '',
|
||||
nextRun: '',
|
||||
jobId: this.jobId,
|
||||
|
||||
@@ -94,6 +94,9 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
private editStepButton: sqlops.ButtonComponent;
|
||||
private deleteStepButton: sqlops.ButtonComponent;
|
||||
|
||||
// Schedule tab controls
|
||||
private removeScheduleButton: sqlops.ButtonComponent;
|
||||
|
||||
// Notifications tab controls
|
||||
private notificationsTabTopLabel: sqlops.TextComponent;
|
||||
private emailCheckBox: sqlops.CheckBoxComponent;
|
||||
@@ -302,6 +305,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
this.stepsTable.data = this.convertStepsToData(this.steps);
|
||||
this.steps[previousRow].id = previousStepId;
|
||||
this.steps[rowNumber].id = currentStepId;
|
||||
this.stepsTable.selectedRows = [previousRow];
|
||||
});
|
||||
|
||||
this.moveStepDownButton.onDidClick(() => {
|
||||
@@ -316,6 +320,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
this.stepsTable.data = this.convertStepsToData(this.steps);
|
||||
this.steps[nextRow].id = nextStepId;
|
||||
this.steps[rowNumber].id = currentStepId;
|
||||
this.stepsTable.selectedRows = [nextRow];
|
||||
});
|
||||
|
||||
this.editStepButton.onDidClick(() => {
|
||||
@@ -346,20 +351,30 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
if (this.stepsTable.selectedRows.length === 1) {
|
||||
let rowNumber = this.stepsTable.selectedRows[0];
|
||||
AgentUtils.getAgentService().then((agentService) => {
|
||||
let steps = this.model.jobSteps ? this.model.jobSteps : [];
|
||||
let stepData = this.model.jobSteps[rowNumber];
|
||||
agentService.deleteJobStep(this.ownerUri, stepData).then((result) => {
|
||||
if (result && result.success) {
|
||||
delete steps[rowNumber];
|
||||
let data = this.convertStepsToData(steps);
|
||||
this.stepsTable.data = data;
|
||||
this.startStepDropdownValues = [];
|
||||
this.steps.forEach((step) => {
|
||||
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
|
||||
});
|
||||
this.startStepDropdown.values = this.startStepDropdownValues;
|
||||
}
|
||||
});
|
||||
let stepData = this.steps[rowNumber];
|
||||
if (stepData.jobId) {
|
||||
agentService.deleteJobStep(this.ownerUri, stepData).then((result) => {
|
||||
if (result && result.success) {
|
||||
this.steps.splice(rowNumber, 1);
|
||||
let data = this.convertStepsToData(this.steps);
|
||||
this.stepsTable.data = data;
|
||||
this.startStepDropdownValues = [];
|
||||
this.steps.forEach((step) => {
|
||||
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
|
||||
});
|
||||
this.startStepDropdown.values = this.startStepDropdownValues;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.steps.splice(rowNumber, 1);
|
||||
let data = this.convertStepsToData(this.steps);
|
||||
this.stepsTable.data = data;
|
||||
this.startStepDropdownValues = [];
|
||||
this.steps.forEach((step) => {
|
||||
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
|
||||
});
|
||||
this.startStepDropdown.values = this.startStepDropdownValues;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -468,7 +483,11 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
label: this.PickScheduleButtonString,
|
||||
width: 80
|
||||
}).component();
|
||||
this.pickScheduleButton.onDidClick((e)=>{
|
||||
this.removeScheduleButton = view.modelBuilder.button().withProperties({
|
||||
label: 'Remove schedule',
|
||||
width: 100
|
||||
}).component();
|
||||
this.pickScheduleButton.onDidClick(()=>{
|
||||
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri, this.model.name);
|
||||
pickScheduleDialog.onSuccess((dialogModel) => {
|
||||
let selectedSchedule = dialogModel.selectedSchedule;
|
||||
@@ -483,12 +502,23 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
});
|
||||
pickScheduleDialog.showDialog();
|
||||
});
|
||||
|
||||
this.removeScheduleButton.onDidClick(() => {
|
||||
if (this.schedulesTable.selectedRows.length === 1) {
|
||||
let selectedRow = this.schedulesTable.selectedRows[0];
|
||||
let selectedScheduleName = this.schedulesTable.data[selectedRow][1];
|
||||
for (let i = 0; i < this.schedules.length; i++) {
|
||||
if (this.schedules[i].name === selectedScheduleName) {
|
||||
this.schedules.splice(i, 1);
|
||||
}
|
||||
}
|
||||
this.populateScheduleTable();
|
||||
}
|
||||
});
|
||||
let formModel = view.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
component: this.schedulesTable,
|
||||
title: this.SchedulesTopLabelString,
|
||||
actions: [this.pickScheduleButton]
|
||||
actions: [this.pickScheduleButton, this.removeScheduleButton]
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
|
||||
await view.initializeModel(formModel);
|
||||
@@ -499,10 +529,9 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
|
||||
private populateScheduleTable() {
|
||||
let data = this.convertSchedulesToData(this.schedules);
|
||||
if (data.length > 0) {
|
||||
this.schedulesTable.data = data;
|
||||
this.schedulesTable.height = 750;
|
||||
}
|
||||
this.schedulesTable.data = data;
|
||||
this.schedulesTable.height = 750;
|
||||
|
||||
}
|
||||
|
||||
private initializeNotificationsTab() {
|
||||
@@ -674,5 +703,6 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
this.model.alerts = [];
|
||||
}
|
||||
this.model.alerts = this.alerts;
|
||||
this.model.categoryId = +this.model.jobCategoryIdsMap.find(cat => cat.name === this.model.category).id;
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,10 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
private readonly AdvancedTabText: string = localize('jobStepDialog.advanced', 'Advanced');
|
||||
private readonly OpenCommandText: string = localize('jobStepDialog.open', 'Open...');
|
||||
private readonly ParseCommandText: string = localize('jobStepDialog.parse','Parse');
|
||||
private readonly NextButtonText: string = localize('jobStepDialog.next', 'Next');
|
||||
private readonly PreviousButtonText: string = localize('jobStepDialog.previous','Previous');
|
||||
private readonly SuccessfulParseText: string = localize('jobStepDialog.successParse', 'The command was successfully parsed.');
|
||||
private readonly FailureParseText: string = localize('jobStepDialog.failParse', 'The command failed.');
|
||||
private readonly BlankStepNameErrorText: string = localize('jobStepDialog.blankStepName', 'The step name cannot be left blank');
|
||||
private readonly ProcessExitCodeText: string = localize('jobStepDialog.processExitCode', 'Process exit code of a successful command:');
|
||||
|
||||
// General Control Titles
|
||||
private readonly StepNameLabelString: string = localize('jobStepDialog.stepNameLabel', 'Step Name');
|
||||
@@ -62,6 +61,8 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
|
||||
// Dropdown options
|
||||
private readonly TSQLScript: string = localize('jobStepDialog.TSQL', 'Transact-SQL script (T-SQL)');
|
||||
private readonly Powershell: string = localize('jobStepDialog.powershell', 'PowerShell');
|
||||
private readonly CmdExec: string = localize('jobStepDialog.CmdExec', 'Operating system (CmdExec)');
|
||||
private readonly AgentServiceAccount: string = localize('jobStepDialog.agentServiceAccount', 'SQL Server Agent Service Account');
|
||||
private readonly NextStep: string = localize('jobStepDialog.nextStep', 'Go to the next step');
|
||||
private readonly QuitJobReportingSuccess: string = localize('jobStepDialog.quitJobSuccess', 'Quit the job reporting success');
|
||||
@@ -88,6 +89,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
private outputFileNameBox: sqlops.InputBoxComponent;
|
||||
private fileBrowserNameBox: sqlops.InputBoxComponent;
|
||||
private userInputBox: sqlops.InputBoxComponent;
|
||||
private processExitCodeBox: sqlops.InputBoxComponent;
|
||||
|
||||
// Dropdowns
|
||||
private typeDropdown: sqlops.DropDownComponent;
|
||||
@@ -100,8 +102,6 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
// Buttons
|
||||
private openButton: sqlops.ButtonComponent;
|
||||
private parseButton: sqlops.ButtonComponent;
|
||||
private nextButton: sqlops.ButtonComponent;
|
||||
private previousButton: sqlops.ButtonComponent;
|
||||
private outputFileBrowserButton: sqlops.ButtonComponent;
|
||||
|
||||
// Checkbox
|
||||
@@ -179,18 +179,6 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
inputType: 'text'
|
||||
})
|
||||
.component();
|
||||
this.nextButton = view.modelBuilder.button()
|
||||
.withProperties({
|
||||
label: this.NextButtonText,
|
||||
enabled: false,
|
||||
width: '80px'
|
||||
}).component();
|
||||
this.previousButton = view.modelBuilder.button()
|
||||
.withProperties({
|
||||
label: this.PreviousButtonText,
|
||||
enabled: false,
|
||||
width: '80px'
|
||||
}).component();
|
||||
}
|
||||
|
||||
private createGeneralTab(databases: string[], queryProvider: sqlops.QueryProvider) {
|
||||
@@ -208,7 +196,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
this.typeDropdown = view.modelBuilder.dropDown()
|
||||
.withProperties({
|
||||
value: this.TSQLScript,
|
||||
values: [this.TSQLScript]
|
||||
values: [this.TSQLScript, this.CmdExec, this.Powershell]
|
||||
})
|
||||
.component();
|
||||
this.runAsDropdown = view.modelBuilder.dropDown()
|
||||
@@ -218,33 +206,20 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
})
|
||||
.component();
|
||||
this.runAsDropdown.enabled = false;
|
||||
this.typeDropdown.onValueChanged((type) => {
|
||||
if (type.selected !== this.TSQLScript) {
|
||||
this.runAsDropdown.value = this.AgentServiceAccount;
|
||||
this.runAsDropdown.values = [this.runAsDropdown.value];
|
||||
} else {
|
||||
this.runAsDropdown.value = '';
|
||||
this.runAsDropdown.values = [''];
|
||||
}
|
||||
});
|
||||
this.databaseDropdown = view.modelBuilder.dropDown()
|
||||
.withProperties({
|
||||
value: databases[0],
|
||||
values: databases
|
||||
}).component();
|
||||
|
||||
this.processExitCodeBox = view.modelBuilder.inputBox()
|
||||
.withProperties({
|
||||
}).component();
|
||||
this.processExitCodeBox.enabled = false;
|
||||
|
||||
// create the commands section
|
||||
this.createCommands(view, queryProvider);
|
||||
|
||||
let buttonContainer = view.modelBuilder.flexContainer()
|
||||
.withLayout({
|
||||
flexFlow: 'row',
|
||||
justifyContent: 'space-between',
|
||||
width: 420
|
||||
}).withItems([this.openButton, this.parseButton, this.previousButton, this.nextButton], {
|
||||
flex: '1 1 50%'
|
||||
}).component();
|
||||
|
||||
let formModel = view.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
component: this.nameTextBox,
|
||||
@@ -258,14 +233,52 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
}, {
|
||||
component: this.databaseDropdown,
|
||||
title: this.DatabaseLabelString
|
||||
}, {
|
||||
component: this.processExitCodeBox,
|
||||
title: this.ProcessExitCodeText
|
||||
}, {
|
||||
component: this.commandTextBox,
|
||||
title: this.CommandLabelString,
|
||||
actions: [buttonContainer]
|
||||
actions: [this.openButton, this.parseButton]
|
||||
}], {
|
||||
horizontal: false,
|
||||
componentWidth: 420
|
||||
}).component();
|
||||
this.typeDropdown.onValueChanged((type) => {
|
||||
switch (type.selected) {
|
||||
case(this.TSQLScript):
|
||||
this.runAsDropdown.value = '';
|
||||
this.runAsDropdown.values = [''];
|
||||
this.runAsDropdown.enabled = false;
|
||||
this.databaseDropdown.enabled = true;
|
||||
this.databaseDropdown.values = databases;
|
||||
this.databaseDropdown.value = databases[0];
|
||||
this.processExitCodeBox.value = '';
|
||||
this.processExitCodeBox.enabled = false;
|
||||
break;
|
||||
case(this.Powershell):
|
||||
this.runAsDropdown.value = this.AgentServiceAccount;
|
||||
this.runAsDropdown.values = [this.runAsDropdown.value];
|
||||
this.runAsDropdown.enabled = true;
|
||||
this.databaseDropdown.enabled = false;
|
||||
this.databaseDropdown.values = [''];
|
||||
this.databaseDropdown.value = '';
|
||||
this.processExitCodeBox.value = '';
|
||||
this.processExitCodeBox.enabled = false;
|
||||
break;
|
||||
case(this.CmdExec):
|
||||
this.databaseDropdown.enabled = false;
|
||||
this.databaseDropdown.values = [''];
|
||||
this.databaseDropdown.value = '';
|
||||
this.runAsDropdown.value = this.AgentServiceAccount;
|
||||
this.runAsDropdown.values = [this.runAsDropdown.value];
|
||||
this.runAsDropdown.enabled = true;
|
||||
this.processExitCodeBox.enabled = true;
|
||||
this.processExitCodeBox.value = '0';
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
let formWrapper = view.modelBuilder.loadingComponent().withItem(formModel).component();
|
||||
formWrapper.loading = false;
|
||||
await view.initializeModel(formWrapper);
|
||||
@@ -524,6 +537,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
||||
this.model.outputFileName = this.outputFileNameBox.value;
|
||||
this.model.appendToLogFile = this.appendToExistingFileCheckbox.checked;
|
||||
this.model.command = this.commandTextBox.value ? this.commandTextBox.value : '';
|
||||
this.model.commandExecutionSuccessCode = this.processExitCodeBox.value ? +this.processExitCodeBox.value : 0;
|
||||
}
|
||||
|
||||
public async initializeDialog() {
|
||||
|
||||
@@ -90,12 +90,9 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof AzureResourceCredentialError) {
|
||||
this.appContext.apiWrapper.showErrorMessage(error.message);
|
||||
|
||||
this.appContext.apiWrapper.executeCommand('azure.resource.signin');
|
||||
} else {
|
||||
return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)];
|
||||
}
|
||||
return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export class AzureResourceTreeProvider implements TreeDataProvider<TreeNode>, IA
|
||||
return element.getChildren(true);
|
||||
}
|
||||
|
||||
if (!this.isSystemInitialized) {
|
||||
if (!this.isSystemInitialized && !this._loadingTimer) {
|
||||
this._loadingTimer = setInterval(async () => {
|
||||
try {
|
||||
// Call sqlops.accounts.getAllAccounts() to determine whether the system has been initialized.
|
||||
|
||||
@@ -40,4 +40,57 @@ export function generateGuid(): string {
|
||||
let clockSequenceHi: string = hexValues[8 + (Math.random() * 4) | 0];
|
||||
return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12);
|
||||
/* tslint:enable:no-bitwise */
|
||||
}
|
||||
|
||||
export function equals(one: any, other: any): boolean {
|
||||
if (one === other) {
|
||||
return true;
|
||||
}
|
||||
if (one === null || one === undefined || other === null || other === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (typeof one !== typeof other) {
|
||||
return false;
|
||||
}
|
||||
if (typeof one !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if ((Array.isArray(one)) !== (Array.isArray(other))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let i: number;
|
||||
let key: string;
|
||||
|
||||
if (Array.isArray(one)) {
|
||||
if (one.length !== other.length) {
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < one.length; i++) {
|
||||
if (!equals(one[i], other[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const oneKeys: string[] = [];
|
||||
|
||||
for (key in one) {
|
||||
oneKeys.push(key);
|
||||
}
|
||||
oneKeys.sort();
|
||||
const otherKeys: string[] = [];
|
||||
for (key in other) {
|
||||
otherKeys.push(key);
|
||||
}
|
||||
otherKeys.sort();
|
||||
if (!equals(oneKeys, otherKeys)) {
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < oneKeys.length; i++) {
|
||||
if (!equals(one[oneKeys[i]], other[oneKeys[i]])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import { AzureResourceTenantService } from '../azureResource/services/tenantServ
|
||||
|
||||
import { registerAzureResourceDatabaseServerCommands } from '../azureResource/providers/databaseServer/commands';
|
||||
import { registerAzureResourceDatabaseCommands } from '../azureResource/providers/database/commands';
|
||||
import { equals } from '../azureResource/utils';
|
||||
|
||||
export default class AzureResourceController extends ControllerBase {
|
||||
public activate(): Promise<boolean> {
|
||||
@@ -37,7 +38,16 @@ export default class AzureResourceController extends ControllerBase {
|
||||
const azureResourceTree = new AzureResourceTreeProvider(this.appContext);
|
||||
this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree));
|
||||
|
||||
this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => { azureResourceTree.notifyNodeChanged(undefined); });
|
||||
let previousAccounts = undefined;
|
||||
this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => {
|
||||
// the onDidChangeAccounts event will trigger in many cases where the accounts didn't actually change
|
||||
// the notifyNodeChanged event triggers a refresh which triggers a getChildren which can trigger this callback
|
||||
// this below check short-circuits the infinite callback loop
|
||||
if (!equals(e.accounts, previousAccounts)) {
|
||||
azureResourceTree.notifyNodeChanged(undefined);
|
||||
}
|
||||
previousAccounts = e.accounts;
|
||||
});
|
||||
|
||||
registerAzureResourceCommands(this.appContext, azureResourceTree);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"declaration": true
|
||||
"declaration": false
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.11",
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.15",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "0.0.18",
|
||||
|
||||
@@ -45,4 +45,6 @@ export interface DacFxDataModel extends BaseDataModel {
|
||||
filePath: string;
|
||||
version: string;
|
||||
upgradeExisting: boolean;
|
||||
scriptFilePath: string;
|
||||
generateScriptAndDeploy: boolean;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as nls from 'vscode-nls';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { SelectOperationPage } from './pages/selectOperationpage';
|
||||
import { DeployConfigPage } from './pages/deployConfigPage';
|
||||
import { DeployActionPage } from './pages/deployActionPage';
|
||||
import { DacFxSummaryPage } from './pages/dacFxSummaryPage';
|
||||
import { ExportConfigPage } from './pages/exportConfigPage';
|
||||
import { ExtractConfigPage } from './pages/extractConfigPage';
|
||||
@@ -30,7 +31,33 @@ export enum Operation {
|
||||
deploy,
|
||||
extract,
|
||||
import,
|
||||
export
|
||||
export,
|
||||
generateDeployScript
|
||||
}
|
||||
|
||||
export enum DeployOperationPath {
|
||||
selectOperation,
|
||||
deployOptions,
|
||||
deployAction,
|
||||
summary
|
||||
}
|
||||
|
||||
export enum ExtractOperationPath {
|
||||
selectOperation,
|
||||
options,
|
||||
summary
|
||||
}
|
||||
|
||||
export enum ImportOperationPath {
|
||||
selectOperation,
|
||||
options,
|
||||
summary
|
||||
}
|
||||
|
||||
export enum ExportOperationPath {
|
||||
selectOperation,
|
||||
options,
|
||||
summary
|
||||
}
|
||||
|
||||
export class DataTierApplicationWizard {
|
||||
@@ -60,6 +87,7 @@ export class DataTierApplicationWizard {
|
||||
this.wizard = sqlops.window.modelviewdialog.createWizard('Data-tier Application Wizard');
|
||||
let selectOperationWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.selectOperationPageName', 'Select an Operation'));
|
||||
let deployConfigWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.deployConfigPageName', 'Select Deploy Dacpac Settings'));
|
||||
let deployActionWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.deployActionPageName', 'Select Action'));
|
||||
let summaryWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.summaryPageName', 'Summary'));
|
||||
let extractConfigWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.extractConfigPageName', 'Select Extract Dacpac Settings'));
|
||||
let importConfigWizardPage = sqlops.window.modelviewdialog.createWizardPage(localize('dacFx.importConfigPageName', 'Select Import Bacpac Settings'));
|
||||
@@ -67,6 +95,7 @@ export class DataTierApplicationWizard {
|
||||
|
||||
this.pages.set('selectOperation', new Page(selectOperationWizardPage));
|
||||
this.pages.set('deployConfig', new Page(deployConfigWizardPage));
|
||||
this.pages.set('deployAction', new Page(deployActionWizardPage));
|
||||
this.pages.set('extractConfig', new Page(extractConfigWizardPage));
|
||||
this.pages.set('importConfig', new Page(importConfigWizardPage));
|
||||
this.pages.set('exportConfig', new Page(exportConfigWizardPage));
|
||||
@@ -87,6 +116,12 @@ export class DataTierApplicationWizard {
|
||||
await deployConfigDacFxPage.start();
|
||||
});
|
||||
|
||||
deployActionWizardPage.registerContent(async (view) => {
|
||||
let deployActionDacFxPage = new DeployActionPage(this, deployActionWizardPage, this.model, view);
|
||||
this.pages.get('deployAction').dacFxPage = deployActionDacFxPage;
|
||||
await deployActionDacFxPage.start();
|
||||
});
|
||||
|
||||
extractConfigWizardPage.registerContent(async (view) => {
|
||||
let extractConfigDacFxPage = new ExtractConfigPage(this, extractConfigWizardPage, this.model, view);
|
||||
this.pages.get('extractConfig').dacFxPage = extractConfigDacFxPage;
|
||||
@@ -113,39 +148,27 @@ export class DataTierApplicationWizard {
|
||||
|
||||
this.wizard.onPageChanged(async (event) => {
|
||||
let idx = event.newPage;
|
||||
let page: Page;
|
||||
|
||||
if (idx === 1) {
|
||||
switch (this.selectedOperation) {
|
||||
case Operation.deploy: {
|
||||
page = this.pages.get('deployConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.extract: {
|
||||
page = this.pages.get('extractConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.import: {
|
||||
page = this.pages.get('importConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.export: {
|
||||
page = this.pages.get('exportConfig');
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (idx === 2) {
|
||||
page = this.pages.get('summary');
|
||||
}
|
||||
let page = this.getPage(idx);
|
||||
|
||||
if (page !== undefined) {
|
||||
page.dacFxPage.setupNavigationValidator();
|
||||
page.dacFxPage.onPageEnter();
|
||||
}
|
||||
|
||||
//do onPageLeave for summary page so that GenerateScript button only shows up if upgrading database
|
||||
let idxLast = event.lastPage;
|
||||
|
||||
if (this.isSummaryPage(idxLast)) {
|
||||
let lastPage = this.pages.get('summary');
|
||||
if (lastPage) {
|
||||
lastPage.dacFxPage.onPageLeave();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.wizard.pages = [selectOperationWizardPage, deployConfigWizardPage, summaryWizardPage];
|
||||
this.wizard.pages = [selectOperationWizardPage, deployConfigWizardPage, deployActionWizardPage, summaryWizardPage];
|
||||
this.wizard.generateScriptButton.hidden = true;
|
||||
this.wizard.generateScriptButton.onClick(async () => await this.generateDeployScript());
|
||||
this.wizard.doneButton.onClick(async () => await this.executeOperation());
|
||||
|
||||
this.wizard.open();
|
||||
@@ -177,6 +200,15 @@ export class DataTierApplicationWizard {
|
||||
this.selectedOperation = Operation.export;
|
||||
break;
|
||||
}
|
||||
case Operation.generateDeployScript: {
|
||||
this.wizard.doneButton.label = localize('dacFx.generateScriptButton', 'Generate Script');
|
||||
this.selectedOperation = Operation.generateDeployScript;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (operation !== Operation.deploy && operation !== Operation.generateDeployScript) {
|
||||
this.model.upgradeExisting = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +230,10 @@ export class DataTierApplicationWizard {
|
||||
await this.export();
|
||||
break;
|
||||
}
|
||||
case Operation.generateDeployScript: {
|
||||
await this.generateDeployScript();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +281,64 @@ export class DataTierApplicationWizard {
|
||||
}
|
||||
}
|
||||
|
||||
private async generateDeployScript() {
|
||||
if (!this.model.scriptFilePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
let service = await DataTierApplicationWizard.getService(this.model.server.providerName);
|
||||
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
||||
this.wizard.message = {
|
||||
text: localize('dacfx.scriptGeneratingMessage', 'You can view the status of script generation in the Task History once the wizard is closed'),
|
||||
level: sqlops.window.modelviewdialog.MessageLevel.Information,
|
||||
description: ''
|
||||
};
|
||||
|
||||
let result = await service.generateDeployScript(this.model.filePath, this.model.database, this.model.scriptFilePath, ownerUri, sqlops.TaskExecutionMode.execute);
|
||||
if (!result || !result.success) {
|
||||
vscode.window.showErrorMessage(
|
||||
localize('alertData.deployErrorMessage', "Deploy failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
|
||||
}
|
||||
}
|
||||
|
||||
private getPage(idx: number): Page {
|
||||
let page: Page;
|
||||
|
||||
if (idx === 1) {
|
||||
switch (this.selectedOperation) {
|
||||
case Operation.deploy: {
|
||||
page = this.pages.get('deployConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.extract: {
|
||||
page = this.pages.get('extractConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.import: {
|
||||
page = this.pages.get('importConfig');
|
||||
break;
|
||||
}
|
||||
case Operation.export: {
|
||||
page = this.pages.get('exportConfig');
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ((this.selectedOperation === Operation.deploy || this.selectedOperation === Operation.generateDeployScript) && idx === DeployOperationPath.deployAction) {
|
||||
page = this.pages.get('deployAction');
|
||||
} else if (this.isSummaryPage(idx)) {
|
||||
page = this.pages.get('summary');
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
private isSummaryPage(idx: number): boolean {
|
||||
return this.selectedOperation === Operation.import && idx === ImportOperationPath.summary
|
||||
|| this.selectedOperation === Operation.export && idx === ExportOperationPath.summary
|
||||
|| this.selectedOperation === Operation.extract && idx === ExtractOperationPath.summary
|
||||
|| (this.selectedOperation === Operation.deploy || this.selectedOperation === Operation.generateDeployScript) && idx === DeployOperationPath.summary;
|
||||
}
|
||||
|
||||
private static async getService(providerName: string): Promise<sqlops.DacFxServicesProvider> {
|
||||
let service = sqlops.dataprotocol.getProvider<sqlops.DacFxServicesProvider>(providerName, sqlops.DataProviderType.DacFxServicesProvider);
|
||||
return service;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"declaration": true
|
||||
"declaration": false
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
||||
@@ -64,9 +64,9 @@ core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.11":
|
||||
version "0.2.11"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/bc80d2226699d23f45a2ec26129cbcdee4781ca9"
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.15":
|
||||
version "0.2.15"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/a2cd2db109de882f0959f7b6421c86afa585f460"
|
||||
dependencies:
|
||||
vscode-languageclient "3.5.1"
|
||||
|
||||
|
||||
17
extensions/integration-tests/.vscode/launch.json
vendored
Normal file
17
extensions/integration-tests/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["${workspaceFolder}/../../", "${workspaceFolder}/test", "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out" ],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceFolder}/out",
|
||||
"preLaunchTask": "npm"
|
||||
}
|
||||
]
|
||||
}
|
||||
31
extensions/integration-tests/.vscode/tasks.json
vendored
Normal file
31
extensions/integration-tests/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Available variables which can be used inside of strings.
|
||||
// ${workspaceFolder}: the root folder of the team
|
||||
// ${file}: the current opened file
|
||||
// ${relativeFile}: the current opened file relative to cwd
|
||||
// ${fileBasename}: the current opened file's basename
|
||||
// ${fileDirname}: the current opened file's dirname
|
||||
// ${fileExtname}: the current opened file's extension
|
||||
// ${cwd}: the current working directory of the spawned process
|
||||
|
||||
// A task runner that calls a custom npm script that compiles the extension.
|
||||
{
|
||||
"version": "0.1.0",
|
||||
|
||||
// we want to run npm
|
||||
"command": "npm",
|
||||
|
||||
// the command is a shell script
|
||||
"isShellCommand": true,
|
||||
|
||||
// show the output window only if unrecognized errors occur.
|
||||
"showOutput": "silent",
|
||||
|
||||
// we run the custom script "compile" as defined in package.json
|
||||
"args": ["run", "compile", "--loglevel", "silent"],
|
||||
|
||||
// The tsc compiler is started in watching mode
|
||||
"isWatching": true,
|
||||
|
||||
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
copy the extension installers to this folder
|
||||
2549
extensions/integration-tests/package-lock.json
generated
Normal file
2549
extensions/integration-tests/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
58
extensions/integration-tests/package.json
Normal file
58
extensions/integration-tests/package.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "integration-tests",
|
||||
"description": "Integration Tests",
|
||||
"version": "0.0.1",
|
||||
"publisher": "Microsoft",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"sqlops": "*"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"extensionDependencies": [
|
||||
"Microsoft.agent",
|
||||
"Microsoft.import",
|
||||
"Microsoft.profiler",
|
||||
"Microsoft.mssql",
|
||||
"Microsoft.notebook"
|
||||
],
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"type": "object",
|
||||
"title": "ADS Integration Test Configuration",
|
||||
"properties": {
|
||||
"test.testSetupCompleted": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"commands": [{
|
||||
"command": "test.setupIntegrationTest",
|
||||
"title": "Setup Integration Test",
|
||||
"category": "Test"
|
||||
},
|
||||
{
|
||||
"command": "test.waitForExtensionsToLoad",
|
||||
"title": "Wait For Extensions To Load",
|
||||
"category": "Test"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-colorize-tests ./tsconfig.json",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "7.0.43",
|
||||
"@types/chai": "3.4.34",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"vscode": "1.1.5",
|
||||
"chai": "3.5.0"
|
||||
}
|
||||
}
|
||||
32
extensions/integration-tests/readme.md
Normal file
32
extensions/integration-tests/readme.md
Normal file
@@ -0,0 +1,32 @@
|
||||
This integration-tests suite is based on the extension testing feature provided by VS Code, We can use this for:
|
||||
a. Commands for setting up the environment for feature testing.
|
||||
b. Adding test cases that do not need UI interaction or the test scenarios not supported by the UI automation framework (e.g. object explorer context menu – not html based)
|
||||
|
||||
extensionInstallers folder: copy the VISX installers for the extensions we would like to run the tests with.
|
||||
src folder: this is where the test file for features should be added, name the file like this: feature.test.ts. e.g. objectExplorer.test.ts
|
||||
|
||||
UI automation testing:
|
||||
the ADS UI automation test cases should be added under $root/test/smoke/src/sql folder. Each feature should create its own folder and add 2 files, one for accessing the feature and the other for the test cases. For example: objectExplorer.ts and objectExplorer.test.ts.
|
||||
|
||||
Setup step:
|
||||
1. Launch ADS
|
||||
2. Install extensions from /extensions/integration-tests/extensionInstallers by calling the test command in the integration-tests extension
|
||||
3. Set configuration values. E.g. Enable preview features by calling the test command in the integration-tests extension
|
||||
|
||||
For now this has only been tested for Windows platform
|
||||
|
||||
How to run the test:
|
||||
1. In the build pipeline:
|
||||
The integration tests and UI automation tests have been added to ADS windows pipeline to run the test and report the results, you can find the test result under the test tab.
|
||||
|
||||
2. Local environment:
|
||||
Integration tests:
|
||||
test-integration.bat or test-integration.sh under scripts folder
|
||||
|
||||
UI automation tests:
|
||||
navigate to test/smoke folder and run: node test/index.js
|
||||
You can also run UI automation from VSCode by selecting the launch option: Launch Smoke Test.
|
||||
|
||||
ADS will be launched using new temp folders: extension folder and data folder so that your local dev environment won't be changed.
|
||||
|
||||
|
||||
36
extensions/integration-tests/src/index.ts
Normal file
36
extensions/integration-tests/src/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as vscode from 'vscode';
|
||||
import { context } from './testContext';
|
||||
|
||||
const path = require('path');
|
||||
const testRunner = require('vscode/lib/testrunner');
|
||||
|
||||
const suite = 'Integration Tests';
|
||||
|
||||
const options: any = {
|
||||
ui: 'tdd',
|
||||
useColors: true,
|
||||
timeout: 600000
|
||||
};
|
||||
|
||||
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
|
||||
options.reporter = 'mocha-multi-reporters';
|
||||
options.reporterOptions = {
|
||||
reporterEnabled: 'spec, mocha-junit-reporter',
|
||||
mochaJunitReporterReporterOptions: {
|
||||
testsuitesTitle: `${suite} ${process.platform}`,
|
||||
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!vscode.workspace.getConfiguration('test')['testSetupCompleted']) {
|
||||
context.RunTest = false;
|
||||
}
|
||||
|
||||
testRunner.configure(options);
|
||||
|
||||
export = testRunner;
|
||||
77
extensions/integration-tests/src/main.ts
Normal file
77
extensions/integration-tests/src/main.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 vscode from 'vscode';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { normalize, join } from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const TEST_SETUP_COMPLETED_TEXT: string = 'Test Setup Completed';
|
||||
const EXTENSION_LOADED_TEXT: string = 'Test Extension Loaded';
|
||||
const ALL_EXTENSION_LOADED_TEXT: string = 'All Extensions Loaded';
|
||||
|
||||
var statusBarItemTimer: NodeJS.Timer;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
var statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
vscode.commands.registerCommand('test.setupIntegrationTest', async () => {
|
||||
let extensionInstallersFolder = normalize(join(__dirname, '../extensionInstallers'));
|
||||
let installers = fs.readdirSync(extensionInstallersFolder);
|
||||
for (let i = 0; i < installers.length; i++) {
|
||||
if (installers[i].endsWith('.vsix')) {
|
||||
let installerFullPath = join(extensionInstallersFolder, installers[i]);
|
||||
await sqlops.extensions.install(installerFullPath);
|
||||
}
|
||||
}
|
||||
await setConfiguration('workbench.enablePreviewFeatures', true);
|
||||
await setConfiguration('workbench.showConnectDialogOnStartup', false);
|
||||
await setConfiguration('test.testSetupCompleted', true);
|
||||
showStatusBarItem(statusBarItem, TEST_SETUP_COMPLETED_TEXT);
|
||||
});
|
||||
|
||||
vscode.commands.registerCommand('test.waitForExtensionsToLoad', async () => {
|
||||
let expectedExtensions = ['Microsoft.agent', 'Microsoft.import', 'Microsoft.mssql', 'Microsoft.profiler'];
|
||||
do {
|
||||
let extensions = vscode.extensions.all.filter(ext => { return expectedExtensions.indexOf(ext.id) !== -1; });
|
||||
|
||||
let isReady = true;
|
||||
for (let i = 0; i < extensions.length; i++) {
|
||||
let extension = extensions[i];
|
||||
isReady = isReady && extension.isActive;
|
||||
if (!isReady) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isReady) {
|
||||
showStatusBarItem(statusBarItem, ALL_EXTENSION_LOADED_TEXT);
|
||||
break;
|
||||
} else {
|
||||
await new Promise(resolve => { setTimeout(resolve, 1000); });
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
});
|
||||
showStatusBarItem(statusBarItem, EXTENSION_LOADED_TEXT);
|
||||
}
|
||||
|
||||
function showStatusBarItem(statusBarItem: vscode.StatusBarItem, text: string) {
|
||||
statusBarItem.text = text;
|
||||
statusBarItem.tooltip = text;
|
||||
statusBarItem.show();
|
||||
clearTimeout(statusBarItemTimer);
|
||||
statusBarItemTimer = setTimeout(function () {
|
||||
statusBarItem.hide();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate(): void {
|
||||
|
||||
}
|
||||
|
||||
async function setConfiguration(name: string, value: any) {
|
||||
await vscode.workspace.getConfiguration().update(name, value, true);
|
||||
}
|
||||
29
extensions/integration-tests/src/objectExplorer.test.ts
Normal file
29
extensions/integration-tests/src/objectExplorer.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 'mocha';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { context } from './testContext';
|
||||
import { getDefaultTestingServer } from './testConfig';
|
||||
import { connectToServer } from './utils';
|
||||
import assert = require('assert');
|
||||
|
||||
if (context.RunTest) {
|
||||
suite('Object Explorer integration test suite', () => {
|
||||
test('context menu test', async function () {
|
||||
await connectToServer(await getDefaultTestingServer());
|
||||
let nodes = <sqlops.objectexplorer.ObjectExplorerNode[]>await sqlops.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length === 1, `expecting 1 active connection, actual: ${nodes.length}`);
|
||||
let actions = await sqlops.objectexplorer.getNodeActions(nodes[0].connectionId, nodes[0].nodePath);
|
||||
const expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'Launch Profiler'];
|
||||
|
||||
const expectedString = expectedActions.join(',');
|
||||
const actualString = actions.join(',');
|
||||
assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`);
|
||||
});
|
||||
});
|
||||
}
|
||||
21
extensions/integration-tests/src/setup.test.ts
Normal file
21
extensions/integration-tests/src/setup.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 'mocha';
|
||||
import * as vscode from 'vscode';
|
||||
import { context } from './testContext';
|
||||
|
||||
if (!context.RunTest) {
|
||||
suite('integration test setup', () => {
|
||||
test('test setup', async function () {
|
||||
//Prepare the environment and make it ready for testing
|
||||
await vscode.commands.executeCommand('test.setupIntegrationTest');
|
||||
//Reload the window, this is required for some changes made by the 'test.setupIntegrationTest' to work
|
||||
await vscode.commands.executeCommand('workbench.action.reloadWindow');
|
||||
});
|
||||
});
|
||||
}
|
||||
92
extensions/integration-tests/src/testConfig.ts
Normal file
92
extensions/integration-tests/src/testConfig.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
TODO: Due to a runtime error, I duplicated this file at these 2 locations:
|
||||
$/extensions/integration-test/src/testConfig.ts
|
||||
$/test/smoke/src/sql/testConfig.ts
|
||||
for now, make sure to keep both files in sync.
|
||||
*/
|
||||
|
||||
interface ITestServerProfile {
|
||||
serverName: string;
|
||||
userName: string;
|
||||
password: string;
|
||||
authenticationType: AuthenticationType;
|
||||
database: string;
|
||||
provider: ConnectionProvider;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface INameDisplayNamePair {
|
||||
name: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
export enum AuthenticationType {
|
||||
Windows,
|
||||
SqlLogin
|
||||
}
|
||||
|
||||
export enum ConnectionProvider {
|
||||
SQLServer
|
||||
}
|
||||
|
||||
var connectionProviderMapping = {};
|
||||
var authenticationTypeMapping = {};
|
||||
connectionProviderMapping[ConnectionProvider.SQLServer] = { name: 'MSSQL', displayName: 'Microsoft SQL Server' };
|
||||
|
||||
authenticationTypeMapping[AuthenticationType.SqlLogin] = { name: 'SqlLogin', displayName: 'SQL Login' };
|
||||
authenticationTypeMapping[AuthenticationType.Windows] = { name: 'Integrated', displayName: 'Windows Authentication' };
|
||||
|
||||
export class TestServerProfile {
|
||||
constructor(private _profile: ITestServerProfile) { }
|
||||
public get serverName(): string { return this._profile.serverName; }
|
||||
public get userName(): string { return this._profile.userName; }
|
||||
public get password(): string { return this._profile.password; }
|
||||
public get database(): string { return this._profile.database; }
|
||||
public get version(): string { return this._profile.version; }
|
||||
public get provider(): ConnectionProvider { return this._profile.provider; }
|
||||
public get providerName(): string { return getEnumMappingEntry(connectionProviderMapping, this.provider).name; }
|
||||
public get providerDisplayName(): string { return getEnumMappingEntry(connectionProviderMapping, this.provider).displayName; }
|
||||
public get authenticationType(): AuthenticationType { return this._profile.authenticationType; }
|
||||
public get authenticationTypeName(): string { return getEnumMappingEntry(authenticationTypeMapping, this.authenticationType).name; }
|
||||
public get authenticationTypeDisplayName(): string { return getEnumMappingEntry(authenticationTypeMapping, this.authenticationType).displayName; }
|
||||
}
|
||||
|
||||
var TestingServers: TestServerProfile[] = [
|
||||
new TestServerProfile(
|
||||
{
|
||||
serverName: 'SQLTOOLS2017-3',
|
||||
userName: '',
|
||||
password: '',
|
||||
authenticationType: AuthenticationType.Windows,
|
||||
database: 'master',
|
||||
provider: ConnectionProvider.SQLServer,
|
||||
version: '2017'
|
||||
})
|
||||
];
|
||||
|
||||
function getEnumMappingEntry(mapping: any, enumValue: any): INameDisplayNamePair {
|
||||
let entry = mapping[enumValue];
|
||||
if (entry) {
|
||||
return entry;
|
||||
} else {
|
||||
throw `Unknown enum type: ${enumValue.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDefaultTestingServer(): Promise<TestServerProfile> {
|
||||
let servers = await getTestingServers();
|
||||
return servers[0];
|
||||
}
|
||||
|
||||
export async function getTestingServers(): Promise<TestServerProfile[]> {
|
||||
let promise = new Promise<TestServerProfile[]>(resolve => {
|
||||
resolve(TestingServers);
|
||||
});
|
||||
await promise;
|
||||
return promise;
|
||||
}
|
||||
8
extensions/integration-tests/src/testContext.ts
Normal file
8
extensions/integration-tests/src/testContext.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export var context = {
|
||||
RunTest: true
|
||||
};
|
||||
8
extensions/integration-tests/src/typings/ref.d.ts
vendored
Normal file
8
extensions/integration-tests/src/typings/ref.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/// <reference path='../../../../src/sql/sqlops.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/sqlops.proposed.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/sqlops.test.d.ts'/>
|
||||
/// <reference types='@types/node'/>
|
||||
38
extensions/integration-tests/src/utils.ts
Normal file
38
extensions/integration-tests/src/utils.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert = require('assert');
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as vscode from 'vscode';
|
||||
import { TestServerProfile } from './testConfig';
|
||||
|
||||
export async function connectToServer(server: TestServerProfile) {
|
||||
let connectionProfile: sqlops.IConnectionProfile = {
|
||||
serverName: server.serverName,
|
||||
databaseName: server.database,
|
||||
authenticationType: server.authenticationTypeName,
|
||||
providerName: server.providerName,
|
||||
connectionName: '',
|
||||
userName: server.userName,
|
||||
password: server.password,
|
||||
savePassword: false,
|
||||
groupFullName: undefined,
|
||||
saveProfile: true,
|
||||
id: undefined,
|
||||
groupId: undefined,
|
||||
options: {}
|
||||
};
|
||||
await ensureConnectionViewOpened();
|
||||
let result = <sqlops.ConnectionResult>await sqlops.connection.connect(connectionProfile);
|
||||
assert(result.connected, `Failed to connect to "${connectionProfile.serverName}", error code: ${result.errorCode}, error message: ${result.errorMessage}`);
|
||||
|
||||
//workaround
|
||||
//wait for OE to load
|
||||
await new Promise(c => setTimeout(c, 3000));
|
||||
}
|
||||
|
||||
export async function ensureConnectionViewOpened() {
|
||||
await vscode.commands.executeCommand('workbench.view.connections');
|
||||
}
|
||||
15
extensions/integration-tests/tsconfig.json
Normal file
15
extensions/integration-tests/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "ES5",
|
||||
"outDir": "out",
|
||||
"noUnusedLocals": true,
|
||||
"lib": [
|
||||
"es2015"
|
||||
],
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
2047
extensions/integration-tests/yarn.lock
Normal file
2047
extensions/integration-tests/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-mssql syntaxes/SQL.plist ./syntaxes/sql.tmLanguage.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.11",
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.15",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "^0.0.15"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "1.5.0-alpha.65",
|
||||
"version": "1.5.0-alpha.68",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.2.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.2.zip",
|
||||
|
||||
@@ -331,6 +331,14 @@ export interface DeployParams {
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
}
|
||||
|
||||
export interface GenerateDeployScriptParams {
|
||||
packageFilePath: string;
|
||||
databaseName: string;
|
||||
scriptFilePath: string;
|
||||
ownerUri: string;
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
}
|
||||
|
||||
export namespace ExportRequest {
|
||||
export const type = new RequestType<ExportParams, sqlops.DacFxResult, void, void>('dacfx/export');
|
||||
}
|
||||
@@ -347,4 +355,8 @@ export namespace DeployRequest {
|
||||
export const type = new RequestType<DeployParams, sqlops.DacFxResult, void, void>('dacfx/deploy');
|
||||
}
|
||||
|
||||
export namespace GenerateDeployScriptRequest {
|
||||
export const type = new RequestType<GenerateDeployScriptParams, sqlops.DacFxResult, void, void>('dacfx/generateDeploymentScript');
|
||||
}
|
||||
|
||||
// ------------------------------- < DacFx > ------------------------------------
|
||||
@@ -106,12 +106,26 @@ export class DacFxServicesFeature extends SqlOpsFeature<undefined> {
|
||||
);
|
||||
};
|
||||
|
||||
let generateDeployScript = (packageFilePath: string, targetDatabaseName: string, scriptFilePath: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> => {
|
||||
let params: contracts.GenerateDeployScriptParams = { packageFilePath: packageFilePath, databaseName: targetDatabaseName, scriptFilePath: scriptFilePath, ownerUri: ownerUri, taskExecutionMode: taskExecutionMode };
|
||||
return client.sendRequest(contracts.GenerateDeployScriptRequest.type, params).then(
|
||||
r => {
|
||||
return r;
|
||||
},
|
||||
e => {
|
||||
client.logFailedRequest(contracts.DeployRequest.type, e);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return sqlops.dataprotocol.registerDacFxServicesProvider({
|
||||
providerId: client.providerId,
|
||||
exportBacpac,
|
||||
importBacpac,
|
||||
extractDacpac,
|
||||
deployDacpac
|
||||
deployDacpac,
|
||||
generateDeployScript
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"declaration": true
|
||||
"declaration": false
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
||||
@@ -64,9 +64,9 @@ core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.11":
|
||||
version "0.2.11"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/bc80d2226699d23f45a2ec26129cbcdee4781ca9"
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.15":
|
||||
version "0.2.15"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/a2cd2db109de882f0959f7b6421c86afa585f460"
|
||||
dependencies:
|
||||
vscode-languageclient "3.5.1"
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ export class CreateSessionDialog {
|
||||
|
||||
private updateSessionName() {
|
||||
if (this.templatesBox.value) {
|
||||
this.sessionNameBox.value = `ADS_${this.templatesBox.value.toString()}`
|
||||
this.sessionNameBox.value = `ADS_${this.templatesBox.value.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "azuredatastudio",
|
||||
"version": "1.4.2",
|
||||
"version": "1.4.3",
|
||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
|
||||
20
scripts/sql-test-integration.bat
Normal file
20
scripts/sql-test-integration.bat
Normal file
@@ -0,0 +1,20 @@
|
||||
setlocal
|
||||
|
||||
pushd %~dp0\..
|
||||
|
||||
set VSCODEUSERDATADIR=%TMP%\adsuser-%RANDOM%-%TIME:~6,5%
|
||||
set VSCODEEXTENSIONSDIR=%TMP%\adsext-%RANDOM%-%TIME:~6,5%
|
||||
echo %VSCODEUSERDATADIR%
|
||||
echo %VSCODEEXTENSIONSDIR%
|
||||
@echo OFF
|
||||
|
||||
call .\scripts\code.bat --extensionDevelopmentPath=%~dp0\..\extensions\integration-tests --extensionTestsPath=%~dp0\..\extensions\integration-tests\out --user-data-dir=%VSCODEUSERDATADIR% --extensions-dir=%VSCODEEXTENSIONSDIR%
|
||||
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
rmdir /s /q %VSCODEUSERDATADIR%
|
||||
rmdir /s /q %VSCODEEXTENSIONSDIR%
|
||||
|
||||
popd
|
||||
|
||||
endlocal
|
||||
23
scripts/sql-test-integration.sh
Normal file
23
scripts/sql-test-integration.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||
ROOT=$(dirname $(dirname $(realpath "$0")))
|
||||
VSCODEUSERDATADIR=`mktemp -d -t 'myuserdatadir'`
|
||||
VSCODEEXTDIR=`mktemp -d -t 'myextdir'`
|
||||
else
|
||||
ROOT=$(dirname $(dirname $(readlink -f $0)))
|
||||
VSCODEUSERDATADIR=`mktemp -d 2>/dev/null`
|
||||
VSCODEEXTDIR=`mktemp -d 2>/dev/null`
|
||||
fi
|
||||
|
||||
cd $ROOT
|
||||
echo $VSCODEUSERDATADIR
|
||||
echo $VSCODEEXTDIR
|
||||
|
||||
./scripts/code.sh --extensionDevelopmentPath=$ROOT/extensions/integration-tests --extensionTestsPath=$ROOT/extensions/integration-tests/out --user-data-dir=$VSCODEUSERDATADIR --extensions-dir=$VSCODEEXTDIR
|
||||
|
||||
|
||||
rm -r $VSCODEUSERDATADIR
|
||||
rm -r $VSCODEEXTDIR
|
||||
@@ -8,7 +8,7 @@ import 'vs/css!./media/breadcrumb';
|
||||
import { Component, Inject, forwardRef, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
||||
import { toDisposableSubscription } from 'sql/base/node/rxjsUtils';
|
||||
import { IBreadcrumbService, MenuItem } from './interfaces';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import { Dropdown, IDropdownOptions } from 'sql/base/browser/ui/editableDropdown/dropdown';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { attachEditableDropdownStyler } from 'sql/common/theme/styler';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import { InputBox as vsInputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
@@ -12,7 +12,7 @@ import './panelStyles';
|
||||
|
||||
import { TabComponent } from './tab.component';
|
||||
import { ScrollableDirective } from 'sql/base/browser/ui/scrollable/scrollable.directive';
|
||||
import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
|
||||
import { subscriptionToDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Directive, Inject, forwardRef, ElementRef, Input } from '@angular/core'
|
||||
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { getContentHeight, addDisposableListener, EventType, getContentWidth } from 'vs/base/browser/dom';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
@Directive({
|
||||
selector: '[scrollable]'
|
||||
@@ -74,7 +74,7 @@ export class ScrollableDirective extends AngularDisposable {
|
||||
private resetScrollDimensions() {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
scrollHeight: this.verticalScroll === ScrollbarVisibility.Auto ? getContentHeight(this.scrolled) : undefined,
|
||||
height: this.verticalScroll === ScrollbarVisibility.Auto ? getContentHeight(this.parent) : undefined,
|
||||
height: this.verticalScroll === ScrollbarVisibility.Auto ? getContentHeight(this.parent) : undefined,
|
||||
scrollWidth: this.horizontalScroll === ScrollbarVisibility.Auto ? this.scrolled.scrollWidth : undefined,
|
||||
width: this.horizontalScroll === ScrollbarVisibility.Auto ? this.scrolled.offsetWidth : undefined
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import { SelectBox as vsSelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
|
||||
@@ -219,7 +219,7 @@ export class RowDetailView {
|
||||
public subscribeToOnAsyncResponse() {
|
||||
this.onAsyncResponse.subscribe((e, args) => {
|
||||
if (!args || !args.itemDetail) {
|
||||
throw 'Slick.RowDetailView plugin requires the onAsyncResponse() to supply "args.itemDetail" property.';
|
||||
throw new Error('Slick.RowDetailView plugin requires the onAsyncResponse() to supply "args.itemDetail" property.');
|
||||
}
|
||||
|
||||
// If we just want to load in a view directly we can use detailView property to do so
|
||||
@@ -278,7 +278,7 @@ export class RowDetailView {
|
||||
item._isPadding = false;
|
||||
item._parent = parent;
|
||||
item._offset = offset;
|
||||
item.name = parent.message ? parent.message : nls.localize('rowDetailView.loadError','Loading Error...');
|
||||
item.name = parent.message ? parent.message : nls.localize('rowDetailView.loadError', 'Loading Error...');
|
||||
parent._child = item;
|
||||
return item;
|
||||
}
|
||||
@@ -349,15 +349,13 @@ export class RowDetailView {
|
||||
//slick-cell to escape the cell overflow clipping.
|
||||
|
||||
//sneaky extra </div> inserted here-----------------v
|
||||
/* tslint:disable:no-unexternalized-strings */
|
||||
html.push("<div class='detailView-toggle collapse'></div></div>");
|
||||
html.push('<div class="detailView-toggle collapse"></div></div>');
|
||||
|
||||
html.push("<div id='cellDetailView_", dataContext.id, "' class='dynamic-cell-detail' "); //apply custom css to detail
|
||||
html.push("style='height:", dataContext._height, "px;"); //set total height of padding
|
||||
html.push("top:", rowHeight, "px'>"); //shift detail below 1st row
|
||||
html.push("<div id='detailViewContainer_", dataContext.id, "' class='detail-container' style='max-height:" + (dataContext._height - rowHeight + bottomMargin) + "px'>"); //sub ctr for custom styling
|
||||
html.push("<div id='innerDetailView_", dataContext.id, "'>", escape(dataContext._detailContent), "</div></div>");
|
||||
/* tslint:enable:no-unexternalized-strings */
|
||||
html.push(`<div id='cellDetailView_${dataContext.id}' class='dynamic-cell-detail' `); //apply custom css to detail
|
||||
html.push(`style=\'height:${dataContext._height}px;`); //set total height of padding
|
||||
html.push(`top:${rowHeight}px'>`); //shift detail below 1st row
|
||||
html.push(`<div id='detailViewContainer_${dataContext.id}"' class='detail-container' style='max-height:${(dataContext._height - rowHeight + bottomMargin)}px'>`); //sub ctr for custom styling
|
||||
html.push(`<div id='innerDetailView_${dataContext.id}'>${escape(dataContext._detailContent)}</div></div>`);
|
||||
//&omit a final closing detail container </div> that would come next
|
||||
|
||||
return html.join('');
|
||||
@@ -401,9 +399,9 @@ export class RowDetailView {
|
||||
this._grid.getOptions().minRowBuffer = item._sizePadding + 3;
|
||||
}
|
||||
|
||||
mainContainer.setAttribute('style', 'max-height: ' + item._height + 'px');
|
||||
mainContainer.setAttribute('style', `max-height: ${item._height}px`);
|
||||
if (cellItem) {
|
||||
cellItem.setAttribute('style', 'height: ' + item._height + 'px;top:' + rowHeight + 'px');
|
||||
cellItem.setAttribute('style', `height: ${item._height}px;top:${rowHeight}px`);
|
||||
}
|
||||
|
||||
let idxParent = this._dataView.getIdxById(item.id);
|
||||
|
||||
@@ -15,7 +15,6 @@ const sizePerDigit = 15;
|
||||
export class RowNumberColumn<T> implements Slick.Plugin<T> {
|
||||
private handler = new Slick.EventHandler();
|
||||
private grid: Slick.Grid<T>;
|
||||
private currentColumnWidth: number;
|
||||
|
||||
constructor(private options: IRowNumberColumnOptions) {
|
||||
}
|
||||
@@ -50,23 +49,14 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public updateRowCount(rowNum: number) {
|
||||
this.options.numberOfRows = rowNum;
|
||||
let columnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
if (columnWidth !== this.currentColumnWidth) {
|
||||
this.grid.setColumnWidths([this.getColumnDefinition()]);
|
||||
}
|
||||
}
|
||||
|
||||
public getColumnDefinition(): Slick.Column<T> {
|
||||
// that smallest we can make it is 22 due to padding and margins in the cells
|
||||
this.currentColumnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
return {
|
||||
id: 'rowNumber',
|
||||
name: '',
|
||||
field: 'rowNumber',
|
||||
width: this.currentColumnWidth,
|
||||
resizable: false,
|
||||
width: 22,
|
||||
resizable: true,
|
||||
cssClass: this.options.cssClass,
|
||||
focusable: false,
|
||||
selectable: false,
|
||||
|
||||
@@ -40,10 +40,14 @@ function defaultSort<T>(args: Slick.OnSortEventArgs<T>, data: Array<T>): Array<T
|
||||
}
|
||||
|
||||
export class TableDataView<T extends Slick.SlickData> implements IDisposableDataProvider<T> {
|
||||
//The data exposed publicly, when filter is enabled, _data holds the filtered data.
|
||||
private _data: Array<T>;
|
||||
//Used when filtering is enabled, _allData holds the complete set of data.
|
||||
private _allData: Array<T>;
|
||||
private _findArray: Array<IFindPosition>;
|
||||
private _findObs: Observable<IFindPosition>;
|
||||
private _findIndex: number;
|
||||
private _filterEnabled: boolean;
|
||||
|
||||
private _onRowCountChange = new Emitter<number>();
|
||||
get onRowCountChange(): Event<number> { return this._onRowCountChange.event; }
|
||||
@@ -51,10 +55,14 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
||||
private _onFindCountChange = new Emitter<number>();
|
||||
get onFindCountChange(): Event<number> { return this._onFindCountChange.event; }
|
||||
|
||||
private _onFilterStateChange = new Emitter<void>();
|
||||
get onFilterStateChange(): Event<void> { return this._onFilterStateChange.event; }
|
||||
|
||||
constructor(
|
||||
data?: Array<T>,
|
||||
private _findFn?: (val: T, exp: string) => Array<number>,
|
||||
private _sortFn?: (args: Slick.OnSortEventArgs<T>, data: Array<T>) => Array<T>
|
||||
private _sortFn?: (args: Slick.OnSortEventArgs<T>, data: Array<T>) => Array<T>,
|
||||
private _filterFn?: (data: Array<T>) => Array<T>
|
||||
) {
|
||||
if (data) {
|
||||
this._data = data;
|
||||
@@ -65,6 +73,35 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
||||
if (!_sortFn) {
|
||||
this._sortFn = defaultSort;
|
||||
}
|
||||
|
||||
if (!_filterFn) {
|
||||
this._filterFn = (dataToFilter) => dataToFilter;
|
||||
}
|
||||
this._filterEnabled = false;
|
||||
}
|
||||
|
||||
public get filterEnabled(): boolean {
|
||||
return this._filterEnabled;
|
||||
}
|
||||
|
||||
public filter() {
|
||||
if (!this.filterEnabled) {
|
||||
this._allData = new Array(...this._data);
|
||||
this._data = this._filterFn(this._allData);
|
||||
this._filterEnabled = true;
|
||||
}
|
||||
|
||||
this._data = this._filterFn(this._allData);
|
||||
this._onFilterStateChange.fire();
|
||||
}
|
||||
|
||||
public clearFilter() {
|
||||
if (this._filterEnabled) {
|
||||
this._data = this._allData;
|
||||
this._allData = [];
|
||||
this._filterEnabled = false;
|
||||
this._onFilterStateChange.fire();
|
||||
}
|
||||
}
|
||||
|
||||
sort(args: Slick.OnSortEventArgs<T>) {
|
||||
@@ -79,20 +116,39 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
||||
return this._data[index];
|
||||
}
|
||||
|
||||
getLengthNonFiltered(): number {
|
||||
return this.filterEnabled ? this._allData.length : this._data.length;
|
||||
}
|
||||
|
||||
push(items: Array<T>);
|
||||
push(item: T);
|
||||
push(input: T | Array<T>) {
|
||||
let inputArray = new Array();
|
||||
if (Array.isArray(input)) {
|
||||
this._data.push(...input);
|
||||
inputArray.push(...input);
|
||||
} else {
|
||||
this._data.push(input);
|
||||
inputArray.push(input);
|
||||
}
|
||||
this._onRowCountChange.fire();
|
||||
|
||||
if (this._filterEnabled) {
|
||||
this._allData.push(...inputArray);
|
||||
let filteredArray = this._filterFn(inputArray);
|
||||
if (filteredArray.length !== 0) {
|
||||
this._data.push(...filteredArray);
|
||||
}
|
||||
} else {
|
||||
this._data.push(...inputArray);
|
||||
}
|
||||
|
||||
this._onRowCountChange.fire(this.getLength());
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._data = new Array<T>();
|
||||
this._onRowCountChange.fire();
|
||||
if (this._filterEnabled) {
|
||||
this._allData = new Array<T>();
|
||||
}
|
||||
this._onRowCountChange.fire(this.getLength());
|
||||
}
|
||||
|
||||
find(exp: string, maxMatches: number = 0): Thenable<IFindPosition> {
|
||||
@@ -180,6 +236,7 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
||||
|
||||
dispose() {
|
||||
this._data = undefined;
|
||||
this._allData = undefined;
|
||||
this._findArray = undefined;
|
||||
this._findObs = undefined;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ import { DefaultUrlSerializer, UrlSerializer, UrlTree } from '@angular/router';
|
||||
* encode and decode the parentheses. Github issue angular/angular#10280, microsoft/carbon#1116
|
||||
*/
|
||||
export default class CustomUrlSerializer implements UrlSerializer {
|
||||
private _defaultUrlSerializer: DefaultUrlSerializer = new DefaultUrlSerializer();
|
||||
private _defaultUrlSerializer: DefaultUrlSerializer = new DefaultUrlSerializer();
|
||||
|
||||
parse(url: string): UrlTree {
|
||||
// Encode parentheses
|
||||
url = url.replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||
// Use the default serializer from here on
|
||||
return this._defaultUrlSerializer.parse(url);
|
||||
}
|
||||
parse(url: string): UrlTree {
|
||||
// Encode parentheses
|
||||
url = url.replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||
// Use the default serializer from here on
|
||||
return this._defaultUrlSerializer.parse(url);
|
||||
}
|
||||
|
||||
serialize(tree: UrlTree): string {
|
||||
// serialize parentheses after angular router
|
||||
return this._defaultUrlSerializer.serialize(tree).replace(/%28/g, '(').replace(/%29/g, ')');
|
||||
}
|
||||
serialize(tree: UrlTree): string {
|
||||
// serialize parentheses after angular router
|
||||
return this._defaultUrlSerializer.serialize(tree).replace(/%28/g, '(').replace(/%29/g, ')');
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
// localizable strings
|
||||
|
||||
export const InvalidProvider = 'Provider is invalid';
|
||||
export const SerializationDisabled = 'Saving results into different format disabled for this data provider.';
|
||||
|
||||
/**
|
||||
* Feature names
|
||||
|
||||
@@ -41,6 +41,7 @@ export const Accounts = 'Accounts';
|
||||
export const FireWallRule = 'FirewallRule';
|
||||
export const AutoOAuth = 'AutoOAuth';
|
||||
export const AddNewDashboardTab = 'AddNewDashboardTab';
|
||||
export const ProfilerFilter = 'ProfilerFilter';
|
||||
|
||||
// SQL Agent Events:
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
import { ITelemetryService, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { warn } from 'sql/base/common/log';
|
||||
|
||||
export interface IConnectionTelemetryData extends ITelemetryData {
|
||||
|
||||
1
src/sql/media/icons/clearfilter.svg
Normal file
1
src/sql/media/icons/clearfilter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>clearfilter</title><path d="M0,1H16V2.71l-6,6V15H6V8.71l-6-6ZM15,2.29V2H1v.29l6,6V14H9V8.29ZM15.29,10l.71.71L14.2,12.5,16,14.29l-.71.71L13.5,13.2,11.71,15,11,14.29l1.8-1.79L11,10.71l.71-.71,1.79,1.8Z"/></svg>
|
||||
|
After Width: | Height: | Size: 308 B |
1
src/sql/media/icons/clearfilter_inverse.svg
Normal file
1
src/sql/media/icons/clearfilter_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>clearfilter_inverse</title><path class="cls-1" d="M0,1H16V2.71l-6,6V15H6V8.71l-6-6ZM15,2.29V2H1v.29l6,6V14H9V8.29ZM15.29,10l.71.71L14.2,12.5,16,14.29l-.71.71L13.5,13.2,11.71,15,11,14.29l1.8-1.79L11,10.71l.71-.71,1.79,1.8Z"/></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
@@ -149,6 +149,15 @@
|
||||
background-image: url("filter_inverse.svg");
|
||||
}
|
||||
|
||||
.vs .icon.clear-filter {
|
||||
background-image: url("clearfilter.svg");
|
||||
}
|
||||
|
||||
.vs-dark .icon.clear-filter,
|
||||
.hc-black .icon.clear-filter {
|
||||
background-image: url("clearfilter_inverse.svg");
|
||||
}
|
||||
|
||||
.vs .icon.warning-badge,
|
||||
.vs-dark .icon.warning-badge,
|
||||
.hc-black .icon.warning-badge {
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:12px;font-family:FullMDL2Assets, Full MDL2 Assets;}</style></defs><title>filter_16x16</title><text class="cls-1" transform="translate(0 12)"> </text><path d="M0,1.53H16V3.24l-6,6v6.27H6V9.22l-6-6ZM15,2.82V2.53H1v.29l6,6v5.69H9V8.8Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>filter</title><path d="M0,1H16V2.68l-6,6v6.27H6V8.67l-6-6ZM15,2.26V2H1v.29l6,6v5.69H9V8.24Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 200 B |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:12px;font-family:FullMDL2Assets, Full MDL2 Assets;}.cls-1,.cls-2{fill:#fff;}</style></defs><title>filter_inverse_16x16</title><text class="cls-1" transform="translate(0.03 12.1)"> </text><path class="cls-2" d="M.05,1.63H16V3.33l-6,6v6.27H6V9.31l-6-6ZM15,2.91V2.62H1v.29l6,6v5.69H9V8.89Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>filter_inverse</title><path class="cls-1" d="M0,1H16V2.68l-6,6v6.27H6V8.67l-6-6ZM15,2.26V2H1v.29l6,6v5.69H9V8.24Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 268 B |
@@ -33,7 +33,7 @@ import { attachModalDialogStyler, attachButtonStyler, attachPanelStyler } from '
|
||||
import { AccountViewModel } from 'sql/parts/accountManagement/accountDialog/accountViewModel';
|
||||
import { AddAccountAction } from 'sql/parts/accountManagement/common/accountActions';
|
||||
import { AccountListRenderer, AccountListDelegate } from 'sql/parts/accountManagement/common/accountListRenderer';
|
||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/services/accountManagement/eventTypes';
|
||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
||||
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { AccountDialog } from 'sql/parts/accountManagement/accountDialog/accountDialog';
|
||||
import { IErrorMessageService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
|
||||
export class AccountDialogController {
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IAccountManagementService } from 'sql/services/accountManagement/interfaces';
|
||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/services/accountManagement/eventTypes';
|
||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
||||
|
||||
/**
|
||||
* View model for account dialog
|
||||
|
||||
@@ -49,18 +49,18 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row {
|
||||
.account-view .list-row {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .icon {
|
||||
.account-view .list-row .icon {
|
||||
flex: 0 0 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
background-size: 50px;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .icon .badge {
|
||||
.account-view .list-row .icon .badge {
|
||||
position: absolute;
|
||||
top: 43px;
|
||||
left: 43px;
|
||||
@@ -69,17 +69,17 @@
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .icon .badge .badge-content {
|
||||
.account-view .list-row .icon .badge .badge-content {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-size: 22px;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .actions-container {
|
||||
.account-view .list-row .actions-container {
|
||||
flex: 0 0 50px;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .actions-container .action-item .action-label {
|
||||
.account-view .list-row .actions-container .action-item .action-label {
|
||||
width: 16px;
|
||||
margin-left: 20px;
|
||||
margin-right: 10px;
|
||||
@@ -88,16 +88,16 @@
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .actions-container .action-item .action-label.icon.remove {
|
||||
.account-view .list-row .actions-container .action-item .action-label.icon.remove {
|
||||
background-size: 14px !important;
|
||||
}
|
||||
|
||||
.account-view .provider-view .list-row .actions-container {
|
||||
.account-view .list-row .actions-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.account-view .provider-view .monaco-list .monaco-list-row:hover .list-row .actions-container,
|
||||
.account-view .provider-view .monaco-list .monaco-list-row.selected .list-row .actions-container,
|
||||
.account-view .provider-view .monaco-list .monaco-list-row.focused .list-row .actions-container{
|
||||
.account-view .monaco-list .monaco-list-row:hover .list-row .actions-container,
|
||||
.account-view .monaco-list .monaco-list-row.selected .list-row .actions-container,
|
||||
.account-view .monaco-list .monaco-list-row.focused .list-row .actions-container{
|
||||
display: block;
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import { Themable, STATUS_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
import { IAccountManagementService } from 'sql/services/accountManagement/interfaces';
|
||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
||||
|
||||
export class AccountListStatusbarItem extends Themable implements IStatusbarItem {
|
||||
private _manageLinkedAccountAction: IAction;
|
||||
|
||||
@@ -8,9 +8,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
import { IErrorMessageService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { AutoOAuthDialog } from 'sql/parts/accountManagement/autoOAuthDialog/autoOAuthDialog';
|
||||
import { IAccountManagementService } from 'sql/services/accountManagement/interfaces';
|
||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
|
||||
export class AutoOAuthDialogController {
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
|
||||
@@ -12,8 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
|
||||
import { error } from 'sql/base/common/log';
|
||||
import { IAccountManagementService } from 'sql/services/accountManagement/interfaces';
|
||||
import { IErrorMessageService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
||||
import { IDialogService, IConfirmation } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -83,7 +82,6 @@ export class RemoveAccountAction extends Action {
|
||||
private _account: sqlops.Account,
|
||||
@IDialogService private _dialogService: IDialogService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IErrorMessageService private _errorMessageService: IErrorMessageService,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
super(RemoveAccountAction.ID, RemoveAccountAction.LABEL, 'remove-account-action icon remove');
|
||||
@@ -107,15 +105,15 @@ export class RemoveAccountAction extends Action {
|
||||
return new TPromise((resolve, reject) => {
|
||||
self._accountManagementService.removeAccount(self._account.key)
|
||||
.then(
|
||||
(result) => { resolve(result); },
|
||||
(err) => {
|
||||
// Must handle here as this is an independent action
|
||||
self._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('removeAccountFailed', 'Failed to remove account')
|
||||
});
|
||||
resolve(false);
|
||||
}
|
||||
(result) => { resolve(result); },
|
||||
(err) => {
|
||||
// Must handle here as this is an independent action
|
||||
self._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('removeAccountFailed', 'Failed to remove account')
|
||||
});
|
||||
resolve(false);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,13 +13,14 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { localize } from 'vs/nls';
|
||||
import { buttonBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
@@ -27,9 +28,8 @@ import { Modal } from 'sql/base/browser/ui/modal/modal';
|
||||
import { FirewallRuleViewModel } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleViewModel';
|
||||
import { attachModalDialogStyler, attachButtonStyler } from 'sql/common/theme/styler';
|
||||
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
||||
import { IAccountPickerService } from 'sql/parts/accountManagement/common/interfaces';
|
||||
import { IAccountPickerService } from 'sql/platform/accountManagement/common/accountPicker';
|
||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
// TODO: Make the help link 1) extensible (01/08/2018, https://github.com/Microsoft/azuredatastudio/issues/450)
|
||||
// in case that other non-Azure sign in is to be used
|
||||
@@ -65,7 +65,7 @@ export class FirewallRuleDialog extends Modal {
|
||||
constructor(
|
||||
@IAccountPickerService private _accountPickerService: IAccountPickerService,
|
||||
@IPartService partService: IPartService,
|
||||
@IWorkbenchThemeService private _workbenchThemeService: IWorkbenchThemeService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IContextViewService private _contextViewService: IContextViewService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@@ -79,7 +79,7 @@ export class FirewallRuleDialog extends Modal {
|
||||
partService,
|
||||
telemetryService,
|
||||
clipboardService,
|
||||
_workbenchThemeService,
|
||||
themeService,
|
||||
contextKeyService,
|
||||
{
|
||||
isFlyout: true,
|
||||
@@ -206,8 +206,8 @@ export class FirewallRuleDialog extends Modal {
|
||||
builder.append(firewallRuleSection);
|
||||
});
|
||||
|
||||
this._register(this._workbenchThemeService.onDidColorThemeChange(e => this.updateTheme(e)));
|
||||
this.updateTheme(this._workbenchThemeService.getColorTheme());
|
||||
this._register(this._themeService.onThemeChange(e => this.updateTheme(e)));
|
||||
this.updateTheme(this._themeService.getTheme());
|
||||
|
||||
$(this._IPAddressInput).on(DOM.EventType.CLICK, () => {
|
||||
this.onFirewallRuleOptionSelected(true);
|
||||
@@ -243,7 +243,7 @@ export class FirewallRuleDialog extends Modal {
|
||||
}
|
||||
|
||||
// Update theming that is specific to firewall rule flyout body
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
private updateTheme(theme: ITheme): void {
|
||||
let linkColor = theme.getColor(buttonBackground);
|
||||
let link = linkColor ? linkColor.toString() : null;
|
||||
if (this._helpLink) {
|
||||
|
||||
@@ -9,12 +9,12 @@ import Severity from 'vs/base/common/severity';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IErrorMessageService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { FirewallRuleDialog } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleDialog';
|
||||
import { IAccountManagementService, AzureResource } from 'sql/services/accountManagement/interfaces';
|
||||
import { IResourceProviderService } from 'sql/parts/accountManagement/common/interfaces';
|
||||
import { IAccountManagementService, AzureResource } from 'sql/platform/accountManagement/common/interfaces';
|
||||
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
|
||||
export class FirewallRuleDialogController {
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import { ChangeDetectorRef, ElementRef, Component, forwardRef, Inject } from '@a
|
||||
import { NgForm } from '@angular/forms';
|
||||
|
||||
import { ITaskDialogComponentParams } from 'sql/services/bootstrap/bootstrapParams';
|
||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||
import { IAdminService } from 'sql/parts/admin/common/adminService';
|
||||
import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo';
|
||||
import { IAdminService } from 'sql/workbench/services/admin/common/adminService';
|
||||
import { ITaskDialogComponent } from 'sql/parts/tasks/common/tasks';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { ElementRef, Component, Inject, forwardRef } from '@angular/core';
|
||||
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
|
||||
import { IDashboardComponentParams } from 'sql/services/bootstrap/bootstrapParams';
|
||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||
import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo';
|
||||
|
||||
export const CREATELOGIN_SELECTOR: string = 'createlogin-component';
|
||||
|
||||
@@ -21,8 +21,8 @@ export class CreateLoginComponent {
|
||||
public connection: ConnectionManagementInfo;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||
@Inject(IBootstrapParams) private _params: IDashboardComponentParams
|
||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||
@Inject(IBootstrapParams) private _params: IDashboardComponentParams
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CreateLoginInput } from './createLoginInput';
|
||||
import { CreateLoginModule } from './createLogin.module';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IMetadataService } from 'sql/services/metadata/metadataService';
|
||||
import { IScriptingService } from 'sql/services/scripting/scriptingService';
|
||||
import { CreateLoginInput } from 'sql/parts/admin/security/createLoginInput';
|
||||
import { CreateLoginModule } from 'sql/parts/admin/security/createLogin.module';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IMetadataService } from 'sql/platform/metadata/common/metadataService';
|
||||
import { IScriptingService } from 'sql/platform/scripting/common/scriptingService';
|
||||
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
||||
import { bootstrapAngular, IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
|
||||
import { CREATELOGIN_SELECTOR } from 'sql/parts/admin/security/createLogin.component';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorInput, EditorModel } from 'vs/workbench/common/editor';
|
||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
|
||||
export class CreateLoginInput extends EditorInput {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
|
||||
import { EditorInput, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||
@@ -16,8 +14,8 @@ import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||
import { IQueryEditorOptions } from 'sql/parts/query/common/queryEditorService';
|
||||
import { QueryPlanInput } from 'sql/parts/queryPlan/queryPlanInput';
|
||||
import { NotebookInput, NotebookInputModel, NotebookInputValidator } from 'sql/parts/notebook/notebookInput';
|
||||
import { DEFAULT_NOTEBOOK_PROVIDER, INotebookService } from 'sql/services/notebook/notebookService';
|
||||
import { getProvidersForFileName } from 'sql/parts/notebook/notebookUtils';
|
||||
import { DEFAULT_NOTEBOOK_PROVIDER, INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
|
||||
import { getProvidersForFileName, getStandardKernelsForProvider } from 'sql/parts/notebook/notebookUtils';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
|
||||
const fs = require('fs');
|
||||
@@ -71,6 +69,10 @@ export function convertEditorInput(input: EditorInput, options: IQueryEditorOpti
|
||||
let notebookInputModel = new NotebookInputModel(uri, undefined, false, undefined);
|
||||
notebookInputModel.providerId = providerIds.filter(provider => provider !== DEFAULT_NOTEBOOK_PROVIDER)[0];
|
||||
notebookInputModel.providers = providerIds;
|
||||
notebookInputModel.providers.forEach(provider => {
|
||||
let standardKernels = getStandardKernelsForProvider(provider, notebookService);
|
||||
notebookInputModel.standardKernels = standardKernels;
|
||||
});
|
||||
let notebookInput: NotebookInput = instantiationService.createInstance(NotebookInput, fileName, notebookInputModel);
|
||||
return notebookInput;
|
||||
});
|
||||
|
||||
@@ -8,8 +8,8 @@ import { Action } from 'vs/base/common/actions';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { INotificationService, INotificationActions } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs';
|
||||
@@ -159,7 +159,7 @@ export class GetCurrentConnectionStringAction extends Action {
|
||||
return new TPromise<void>((resolve, reject) => {
|
||||
let activeInput = this._editorService.activeEditor;
|
||||
if (activeInput && (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput)
|
||||
&& this._connectionManagementService.isConnected(activeInput.uri)) {
|
||||
&& this._connectionManagementService.isConnected(activeInput.uri)) {
|
||||
let includePassword = false;
|
||||
let connectionProfile = this._connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||
this._connectionManagementService.getConnectionString(connectionProfile.id, includePassword).then(result => {
|
||||
|
||||
@@ -7,9 +7,9 @@ import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
|
||||
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||
import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IConnectionComponentCallbacks, IConnectionComponentController, IConnectionValidateResult } from 'sql/parts/connection/connectionDialog/connectionDialogService';
|
||||
import { ConnectionWidget } from 'sql/parts/connection/connectionDialog/connectionWidget';
|
||||
import { AdvancedPropertiesController } from 'sql/parts/connection/connectionDialog/advancedPropertiesController';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as Utils from 'sql/parts/connection/common/utils';
|
||||
import * as Utils from 'sql/platform/connection/common/utils';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { ConnectionProviderProperties } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
|
||||
|
||||
@@ -6,20 +6,19 @@
|
||||
'use strict';
|
||||
|
||||
import {
|
||||
IConnectionDialogService, IConnectionManagementService, IErrorMessageService,
|
||||
IConnectionDialogService, IConnectionManagementService,
|
||||
ConnectionType, INewConnectionParams, IConnectionCompletionOptions, IConnectionResult
|
||||
} from 'sql/parts/connection/common/connectionManagement';
|
||||
} from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionDialogWidget, OnShowUIResponse } from 'sql/parts/connection/connectionDialog/connectionDialogWidget';
|
||||
import { ConnectionController } from 'sql/parts/connection/connectionDialog/connectionController';
|
||||
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { entries } from 'sql/base/common/objects';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -28,12 +27,11 @@ import * as platform from 'vs/base/common/platform';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { trim } from 'vs/base/common/strings';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export interface IConnectionValidateResult {
|
||||
isValid: boolean;
|
||||
@@ -87,14 +85,14 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
@ICommandService private _commandService: ICommandService
|
||||
) { }
|
||||
/**
|
||||
* Gets the default provider with the following actions
|
||||
* 1. Checks if master provider(map) has data
|
||||
* 2. If so, filters provider paramter against master map
|
||||
* 3. Fetches the result array and extracts the first element
|
||||
* 4. If none of the above data exists, returns 'MSSQL'
|
||||
* @returns: Default provider as string
|
||||
*/
|
||||
/**
|
||||
* Gets the default provider with the following actions
|
||||
* 1. Checks if master provider(map) has data
|
||||
* 2. If so, filters provider paramter against master map
|
||||
* 3. Fetches the result array and extracts the first element
|
||||
* 4. If none of the above data exists, returns 'MSSQL'
|
||||
* @returns: Default provider as string
|
||||
*/
|
||||
private getDefaultProviderName(): string {
|
||||
let defaultProvider: string;
|
||||
if (this._providerNameToDisplayNameMap) {
|
||||
|
||||
@@ -7,13 +7,13 @@ import 'vs/css!./media/connectionDialog';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
import { attachModalDialogStyler, attachButtonStyler } from 'sql/common/theme/styler';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { Modal } from 'sql/base/browser/ui/modal/modal';
|
||||
import { IConnectionManagementService, INewConnectionParams } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionManagementService, INewConnectionParams } from 'sql/platform/connection/common/connectionManagement';
|
||||
import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper';
|
||||
import { TreeCreationUtils } from 'sql/parts/objectExplorer/viewlet/treeCreationUtils';
|
||||
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { TabbedPanel, PanelTabIdentifier } from 'sql/base/browser/ui/panel/panel';
|
||||
import { RecentConnectionTreeController, RecentConnectionActionsProvider } from 'sql/parts/connection/connectionDialog/recentConnectionTreeController';
|
||||
import { SavedConnectionTreeController } from 'sql/parts/connection/connectionDialog/savedConnectionTreeController';
|
||||
|
||||
@@ -13,16 +13,16 @@ import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
|
||||
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
||||
import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper';
|
||||
import { IConnectionComponentCallbacks } from 'sql/parts/connection/connectionDialog/connectionDialogService';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
|
||||
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
import { ConnectionProfile } from '../common/connectionProfile';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import * as styler from 'sql/common/theme/styler';
|
||||
import { IAccountManagementService } from 'sql/services/accountManagement/interfaces';
|
||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ClearSingleRecentConnectionAction } from 'sql/parts/connection/common/connectionActions';
|
||||
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import mouse = require('vs/base/browser/mouseEvent');
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
|
||||
export class RecentConnectionActionsProvider extends ContributableActionProvider {
|
||||
private _onRecentConnectionRemoved = new Emitter<void>();
|
||||
@@ -33,7 +33,7 @@ export class RecentConnectionActionsProvider extends ContributableActionProvider
|
||||
private getRecentConnectionActions(tree: ITree, element: any): IAction[] {
|
||||
let actions: IAction[] = [];
|
||||
let clearSingleConnectionAction = this._instantiationService.createInstance(ClearSingleRecentConnectionAction, ClearSingleRecentConnectionAction.ID,
|
||||
ClearSingleRecentConnectionAction.LABEL,<IConnectionProfile>element);
|
||||
ClearSingleRecentConnectionAction.LABEL, <IConnectionProfile>element);
|
||||
clearSingleConnectionAction.onRecentConnectionRemoved(() => this._onRecentConnectionRemoved.fire());
|
||||
actions.push(clearSingleConnectionAction);
|
||||
return actions;
|
||||
|
||||
@@ -8,12 +8,12 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
import { IAngularEventingService, AngularEventType, IAngularEvent } from 'sql/services/angularEventing/angularEventingService';
|
||||
import { IAngularEventingService, AngularEventType, IAngularEvent } from 'sql/platform/angularEventing/common/angularEventingService';
|
||||
import { INewDashboardTabDialogService } from 'sql/parts/dashboard/newDashboardTabDialog/interface';
|
||||
import { IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
||||
import { toDisposableSubscription } from 'sql/base/node/rxjsUtils';
|
||||
|
||||
export class EditDashboardAction extends Action {
|
||||
|
||||
private static readonly ID = 'editDashboard';
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/commo
|
||||
import { error } from 'sql/base/common/log';
|
||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||
import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo';
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||
@@ -21,7 +21,7 @@ import { CONTROLHOST_CONTAINER } from 'sql/parts/dashboard/containers/dashboardC
|
||||
import { NAV_SECTION } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
||||
import { IDashboardContainerRegistry, Extensions as DashboardContainerExtensions } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||
import { SingleConnectionManagementService } from 'sql/services/common/commonServiceInterface.service';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
|
||||
const dashboardcontainerRegistry = Registry.as<IDashboardContainerRegistry>(DashboardContainerExtensions.dashboardContainerContributions);
|
||||
const containerTypes = [
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!sql/parts/dashboard/common/dashboardPage';
|
||||
import 'sql/parts/dashboard/common/dashboardPanelStyles';
|
||||
|
||||
import { Component, Inject, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Component, Inject, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, ChangeDetectorRef } from '@angular/core';
|
||||
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface, SingleConnectionManagementService } from 'sql/services/common/commonServiceInterface.service';
|
||||
@@ -16,13 +16,13 @@ import { PanelComponent } from 'sql/base/browser/ui/panel/panel.component';
|
||||
import { IDashboardRegistry, Extensions as DashboardExtensions, IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||
import { PinUnpinTabAction, AddFeatureTabAction } from './actions';
|
||||
import { TabComponent, TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
import { AngularEventType, IAngularEventingService } from 'sql/services/angularEventing/angularEventingService';
|
||||
import { AngularEventType, IAngularEventingService } from 'sql/platform/angularEventing/common/angularEventingService';
|
||||
import { DashboardTab, IConfigModifierCollection } from 'sql/parts/dashboard/common/interfaces';
|
||||
import * as dashboardHelper from 'sql/parts/dashboard/common/dashboardHelper';
|
||||
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import * as types from 'vs/base/common/types';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as types from 'vs/base/common/types';
|
||||
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { registerTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||
import { generateContainerTypeSchemaProperties } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||
import { NAV_SECTION, validateNavSectionContributionAndRegisterIcon } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
import { OnDestroy } from '@angular/core';
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
import { SingleConnectionManagementService } from 'sql/services/common/commonServiceInterface.service';
|
||||
|
||||
|
||||
@@ -5,22 +5,15 @@
|
||||
|
||||
import 'vs/css!./dashboardGridContainer';
|
||||
|
||||
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter } from '@angular/core';
|
||||
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||
import { concat } from 'rxjs/operator/concat';
|
||||
import { Component, Inject, Input, forwardRef, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { TabConfig, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||
import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
|
||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||
import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
export interface GridCellConfig {
|
||||
|
||||
@@ -8,11 +8,10 @@ import 'vs/css!./dashboardHomeContainer';
|
||||
import { Component, forwardRef, Input, ChangeDetectorRef, Inject, ViewChild, ContentChild } from '@angular/core';
|
||||
|
||||
import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.component';
|
||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { AngularEventType, IAngularEventingService } from 'sql/services/angularEventing/angularEventingService';
|
||||
import { AngularEventType, IAngularEventingService } from 'sql/platform/angularEventing/common/angularEventingService';
|
||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||
import { ScrollableDirective } from 'sql/base/browser/ui/scrollable/scrollable.directive';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
|
||||
@@ -5,20 +5,13 @@
|
||||
|
||||
import 'vs/css!./dashboardWidgetContainer';
|
||||
|
||||
import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
||||
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||
import { Component, Inject, Input, forwardRef, ViewChild, OnDestroy, ChangeDetectorRef, AfterContentInit } from '@angular/core';
|
||||
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { TabConfig, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||
import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
|
||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||
import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -6,8 +6,8 @@ import 'vs/css!sql/media/icons/common-icons';
|
||||
import 'vs/css!./dashboardWidgetWrapper';
|
||||
|
||||
import {
|
||||
Component, Input, Inject, forwardRef, ComponentFactoryResolver, AfterContentInit, ViewChild,
|
||||
ElementRef, OnInit, ChangeDetectorRef, OnDestroy, ReflectiveInjector, Injector, Type, ComponentRef
|
||||
Component, Input, Inject, forwardRef, ComponentFactoryResolver, ViewChild,
|
||||
ElementRef, OnInit, ChangeDetectorRef, ReflectiveInjector, Injector, Type, ComponentRef
|
||||
} from '@angular/core';
|
||||
|
||||
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
||||
@@ -15,7 +15,7 @@ import { WidgetConfig, WIDGET_CONFIG, IDashboardWidget } from 'sql/parts/dashboa
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||
import { error } from 'sql/base/common/log';
|
||||
import { RefreshWidgetAction, ToggleMoreWidgetAction, DeleteWidgetAction, CollapseWidgetAction } from 'sql/parts/dashboard/common/actions';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
/* Widgets */
|
||||
import { PropertiesWidgetComponent } from 'sql/parts/dashboard/widgets/properties/propertiesWidget.component';
|
||||
@@ -24,10 +24,8 @@ import { TasksWidget } from 'sql/parts/dashboard/widgets/tasks/tasksWidget.compo
|
||||
import { InsightsWidget } from 'sql/parts/dashboard/widgets/insights/insightsWidget.component';
|
||||
import { WebviewWidget } from 'sql/parts/dashboard/widgets/webview/webviewWidget.component';
|
||||
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import * as themeColors from 'vs/workbench/common/theme';
|
||||
@@ -36,7 +34,6 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
const componentMap: { [x: string]: Type<IDashboardWidget> } = {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./webviewContent';
|
||||
|
||||
import { Component, forwardRef, Input, OnInit, Inject, ChangeDetectorRef, ElementRef } from '@angular/core';
|
||||
import { Component, forwardRef, Input, OnInit, Inject, ElementRef } from '@angular/core';
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Parts, IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
@@ -17,8 +17,8 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
||||
import { WebviewElement } from 'vs/workbench/parts/webview/electron-browser/webviewElement';
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { IDashboardWebview, IDashboardViewService } from 'sql/services/dashboard/common/dashboardViewService';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { IDashboardWebview, IDashboardViewService } from 'sql/platform/dashboard/common/dashboardViewService';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
@@ -12,9 +12,9 @@ import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboar
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||
import { subscriptionToDisposable, AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { subscriptionToDisposable, AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
|
||||
import 'vs/css!./dashboard';
|
||||
|
||||
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { DashboardServiceInterface } from './services/dashboardServiceInterface.service';
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import * as Utils from 'sql/parts/connection/common/utils';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import * as Utils from 'sql/platform/connection/common/utils';
|
||||
import { RefreshWidgetAction, EditDashboardAction } from 'sql/parts/dashboard/common/actions';
|
||||
import { DashboardPage } from 'sql/parts/dashboard/common/dashboardPage.component';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { AngularDisposable } from 'sql/base/node/lifecycle';
|
||||
|
||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
@@ -11,7 +11,7 @@ import { FormsModule } from '@angular/forms';
|
||||
import { NgGridModule } from 'angular2-grid';
|
||||
import { ChartsModule } from 'ng2-charts/ng2-charts';
|
||||
|
||||
import CustomUrlSerializer from 'sql/common/urlSerializer';
|
||||
import CustomUrlSerializer from 'sql/base/node/urlSerializer';
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||
import { Extensions as ComponentExtensions, IComponentRegistry } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||
import { IBootstrapParams, ISelector, providerIterator } from 'sql/services/bootstrap/bootstrapService';
|
||||
|
||||
@@ -19,10 +19,10 @@ import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService';
|
||||
import { IDashboardComponentParams } from 'sql/services/bootstrap/bootstrapParams';
|
||||
import { DASHBOARD_SELECTOR } from 'sql/parts/dashboard/dashboard.component';
|
||||
import { ConnectionContextKey } from 'sql/parts/connection/common/connectionContextKey';
|
||||
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IDashboardService } from 'sql/platform/dashboard/browser/dashboardService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
export class DashboardEditor extends BaseEditor {
|
||||
|
||||
@@ -10,8 +10,8 @@ import URI from 'vs/base/common/uri';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
|
||||
export class DashboardInput extends EditorInput {
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user