Compare commits

...

18 Commits

Author SHA1 Message Date
Karl Burtram
8439cde610 Bump SQL Tools to 1.5.0-alpha.52 2018-10-31 20:38:22 -07:00
Anthony Dresser
2080c525a7 Auto Scale Axis (#3070)
* fix input to chart that was causes scales to not auto size

* formatting

* formatting

* added comments
2018-10-31 20:33:09 -07:00
Aditya Bist
db2d380b6c Agent/edit job logic (#3023)
* lumped stepdata with jobdata in job dialog

* fix bug with empty steps

* added clumped and update steps and schedules from job dialog

* edit data sends one call instead of multiple

* cleaned code
2018-10-31 20:32:59 -07:00
Alan Ren
a06f80bdb1 fix for issue 3065 (#3067)
* fix for 3065

* remove the parameter, no need to save connection
2018-10-31 20:32:51 -07:00
Karl Burtram
1f76c85b1b Remove SQL Import dashboard tab (#3064) 2018-10-31 20:32:37 -07:00
Karl Burtram
cffc18d5ea Revert "Revert "Add a command line interface for connecting to a SQL Server (#3047)""
This reverts commit a747b6a500.
2018-10-31 20:32:17 -07:00
Karl Burtram
a747b6a500 Revert "Add a command line interface for connecting to a SQL Server (#3047)"
This reverts commit 7f66087d8c.
2018-10-31 14:39:46 -07:00
Aditya Bist
711b7bf622 fixed null ref (#3061) 2018-10-31 14:25:39 -07:00
Alan Ren
9b0757de9c a few ux improvements (#3057)
* style update

* checkbox styler

* casing update
2018-10-31 14:25:26 -07:00
Alan Ren
b9a0744a83 fix for issue 2719 (#3060) 2018-10-31 14:25:14 -07:00
Karl Burtram
c69915ca58 Bump SQL Tools to 1.5.0-alpha.51 2018-10-31 13:17:20 -07:00
Karl Burtram
a16835918a Fix build break in previous Query Plan commit 2018-10-31 13:04:32 -07:00
David Shiflet
f9e27d7112 Add a command line interface for connecting to a SQL Server (#3047)
* Add switches for server, database, user, integrated auth

* Refactor into new commandline service

* Open query editor when passed server on command line

* Add tests
2018-10-31 10:14:36 -07:00
Ryan
c072ba9c5c Add query plan theme support (#2991) (#3031)
Add monaco-editor and monaco-editor-hover to output otherwise backgrounds collide.
2018-10-31 10:14:26 -07:00
Alan Ren
807fb2ed8a fix missing footer for backup dialog (#3056)
@MattIrv  Thanks for helping out
2018-10-31 09:46:14 -07:00
Ruturaj Gujar
daf347b728 Fixed some typos and grammatical errors (#3027) 2018-10-31 09:46:06 -07:00
Karl Burtram
e76222db7a Change 'None' to 'Do not save' in Connection Dialog (#3051) 2018-10-30 10:46:24 -07:00
Karl Burtram
f676090901 Bump Azure Data Studio to 1.2.3 2018-10-30 10:28:29 -07:00
39 changed files with 611 additions and 283 deletions

View File

@@ -34,9 +34,9 @@ See the [change log](https://github.com/Microsoft/azuredatastudio/blob/master/CH
- Task History window to view current task execution status, completion results with error messages and task T-SQL scripting
- Scripting support to generate CREATE, SELECT, ALTER and DROP statements for database objects
- Workspaces with full Git integration and Find In Files support to managing T-SQL script libraries
- Modern light-weight shell with theming, user settings, full screen support, integrated terminal and numerous other features
- Modern light-weight shell with theming, user settings, full-screen support, integrated terminal and numerous other features
Here's some of these features in action.
Here are some of these features in action.
<img src='https://github.com/Microsoft/azuredatastudio/blob/master/docs/overview_screen.jpg' width='800px'>
@@ -69,25 +69,25 @@ We would like to thank all our users who raised issues, and in particular the fo
* AlexFsmn `Disabled connection name input when connecting to a server. #2566`
* SebastianPfliegel `Added more saveAsCsv options #2099`
* ianychoi `Fixes a typo: Mimunum -> Minimum #1994`
* AlexFsmn `Fixed bug where proper file extension wasn't appended to filename. #2151`
* AlexFsmn `Fixed bug where proper file extension wasn't appended to the filename. #2151`
* AlexFsmn `Added functionality for adding any file to import wizard #2329`
* AlexFsmn `Fixed background issue when copying a chart to clipboard #2215`
* AlexFsmn `Fixed problem where vertical charts didn't display labels correctly. #2263`
* AlexFsmn `Fixed Initial values for charts to match visuals #2266`
* AlexFsmn `Renamed chart option labels #2264`
* AlexFsmn `Added feature for opening file after exporting to CSV/XLS/JSON & query files #2216`
* AlexFsmn `Added feature for the opening file after exporting to CSV/XLS/JSON & query files #2216`
* AlexFsmm `Get Connection String should copy to clipboard #2175`
* lanceklinger `Fix for double clicking column handle in results table #1504`
* lanceklinger `Fix for double-clicking column handle in results table #1504`
* westerncj for `Removed duplicate contribution from README.md (#753)`
* ntovas for `Fix for duplicate extensions shown in "Save File" dialog. (#779)`
* SebastianPfliegel for `Add cursor snippet (#475)`
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
* mikaoelitiana for the fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
* alextercete for `Reinstate menu item to install from VSIX (#682)`
* alextercete for `Fix "No extension gallery service configured" error (#427)`
* mwiedemeyer for `Fix #58: Default sort order for DB size widget (#111)`
* AlexTroshkin for `Show disconnect in context menu only when connectionProfile connected (#150)`
* AlexTroshkin for `Fix #138: Invalid syntax color highlighting (identity not highlighting) (#140))`
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with case-sensitive collation. (#152)`
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with a case-sensitive collation. (#152)`
* SebastianPfliegel `Remove sqlExtensionHelp (#312)`
* olljanat for `Implemented npm version check (#314)`
* Adam Machanic for helping with the `whoisactive` extension
@@ -96,7 +96,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Italian: Aldo Donetti, Alessandro Alpi, Andrea Dottor, Bruni Luca, Gianluca Hotz, Luca Nardi, Luigi Bruno, Marco Dal Pino, Mirco Vanini, Pasquale Ceglie, Riccardo Cappello, Sergio Govoni, Stefano Demiliani
* German: Anna Henke-Gunvaldson, Ben Weissman, David Ullmer, J.M. ., Kai Modo, Konstantin Staschill, Kostja Klein, Lennart Trunk, Markus Ehrenmüller-Jensen, Mascha Kroenlein, Matthias Knoll, Mourad Louha, Thomas Hütter, Wolfgang Straßer
* Spanish: Alberto Poblacion, Andy Gonzalez, Carlos Mendible, Christian Araujo, Daniel D, Eickhel Mendoza, Ernesto Cardenas, Ivan Toledo Ivanovic, Fran Diaz, JESUS GIL, Jorge Serrano Pérez, José Saturnino Pimentel Juárez, Mauricio Hidalgo, Pablo Iglesias, Rikhardo Estrada Rdez, Thierry DEMAN, YOLANDA CUESTA ALTIERI
* Japanese: Fujio Kojima, Kazushi KAMEGAWA, Masayoshi Yamada, Masayuki Ozawa , Seiji Momoto, Takashi Kanai, Takayoshi Tanaka, Yoshihisa Ozaki, 庄垣内治
* Japanese: Fujio Kojima, Kazushi KAMEGAWA, Masayoshi Yamada, Masayuki Ozawa, Seiji Momoto, Takashi Kanai, Takayoshi Tanaka, Yoshihisa Ozaki, 庄垣内治
* Chinese (simplified): DAN YE, Joel Yang, Lynne Dong, RyanYu Zhang, Sheng Jiang, Wei Zhang, Zhiliang Xu
* Chinese (Traditional): Bruce Chen, Chiayi Yen, Kevin Yang, Winnie Lin, 保哥 Will, 謝政廷
* Korean: Do-Kyun Kim, Evelyn Kim, Helen Jung, Hong Jmee, jeongwoo choi, Jun Hyoung Lee, Jungsun Kim정선, Justin Yoo, Kavrith mucha, Kiwoong Youm, MinGyu Ju, MVP_JUNO BEA, Sejun Kim, SOONMAN KWON, sung man ko, Yeongrak Choi, younggun kim, Youngjae Kim, 소영 이
@@ -104,7 +104,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Portuguese Brazil: Daniel de Sousa, Diogo Duarte, Douglas Correa, Douglas Eccker, José Emanuel Mendes, Marcelo Fernandes, Marcondes Alexandre, Roberto Fonseca, Rodrigo Crespi
And of course we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/ThirdPartyNotices.txt)
And of course, we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/ThirdPartyNotices.txt)
## License

View File

@@ -9,6 +9,7 @@ import * as vscode from 'vscode';
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
import { JobData } from './jobData';
const localize = nls.loadMessageBundle();
@@ -45,8 +46,19 @@ export class AlertData implements IAgentDialogData {
wmiEventNamespace: string;
wmiEventQuery: string;
constructor(ownerUri:string, alertInfo: sqlops.AgentAlertInfo) {
private viaJobDialog: boolean;
private jobModel: JobData;
constructor(
ownerUri:string,
alertInfo: sqlops.AgentAlertInfo,
jobModel?: JobData,
viaJobDialog: boolean = false
) {
this.ownerUri = ownerUri;
this.viaJobDialog = viaJobDialog;
this.jobModel = jobModel;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
if (alertInfo) {
this.dialogMode = AgentDialogMode.EDIT;
@@ -60,7 +72,6 @@ export class AlertData implements IAgentDialogData {
this.includeEventDescription = alertInfo.includeEventDescription.toString();
this.isEnabled = alertInfo.isEnabled;
this.jobId = alertInfo.jobId;
this.jobName = alertInfo.jobName;
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
this.lastResponseDate = alertInfo.lastResponseDate;
this.messageId = alertInfo.messageId;
@@ -82,10 +93,18 @@ export class AlertData implements IAgentDialogData {
public async save() {
let agentService = await AgentUtils.getAgentService();
let result = this.dialogMode === AgentDialogMode.CREATE
? await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo())
: await agentService.updateAlert(this.ownerUri, this.originalName, this.toAgentAlertInfo());
let result: any;
// if it's called via the job dialog, add it to the
// job model
if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this);
return;
}
} else {
// has to be a create alert
result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo());
}
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));

View File

@@ -44,6 +44,7 @@ export class JobData implements IAgentDialogData {
public jobSteps: sqlops.AgentJobStepInfo[];
public jobSchedules: sqlops.AgentJobScheduleInfo[];
public alerts: sqlops.AgentAlertInfo[];
public jobId: string;
constructor(
ownerUri: string,
@@ -62,6 +63,7 @@ export class JobData implements IAgentDialogData {
this.jobSteps = jobInfo.JobSteps;
this.jobSchedules = jobInfo.JobSchedules;
this.alerts = jobInfo.Alerts;
this.jobId = jobInfo.jobId;
}
}
@@ -115,7 +117,6 @@ export class JobData implements IAgentDialogData {
let result = this.dialogMode === AgentDialogMode.CREATE
? await this._agentService.createJob(this.ownerUri, jobInfo)
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('jobData.saveErrorMessage', "Job update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
@@ -135,18 +136,6 @@ export class JobData implements IAgentDialogData {
};
}
public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) {
if (this.jobSchedules) {
let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name);
if (!existingSchedule) {
this.jobSchedules.push(schedule);
}
} else {
this.jobSchedules = [];
this.jobSchedules.push(schedule);
}
}
public toAgentJobInfo(): sqlops.AgentJobInfo {
return {
name: this.name,
@@ -177,7 +166,7 @@ export class JobData implements IAgentDialogData {
categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS
lastRun: '',
nextRun: '',
jobId: ''
jobId: this.jobId
};
}
}

View File

@@ -46,11 +46,13 @@ export class JobStepData implements IAgentDialogData {
public retryInterval: number;
public proxyName: string;
private jobModel: JobData;
private viaJobDialog: boolean;
constructor(ownerUri:string, jobModel?: JobData) {
constructor(ownerUri:string, jobModel?: JobData, viaJobDialog: boolean = false) {
this.ownerUri = ownerUri;
this.jobName = jobModel.name;
this.jobModel = jobModel;
this.viaJobDialog = viaJobDialog;
}
public async initialize() {
@@ -59,18 +61,16 @@ export class JobStepData implements IAgentDialogData {
public async save() {
let agentService = await AgentUtils.getAgentService();
let result: any;
if (this.dialogMode === AgentDialogMode.CREATE) {
if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.CREATE) {
// create job -> create step
// if it's called via the job dialog, add it to the
// job model
if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this);
return;
} else {
// edit job -> create step
result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this));
}
} else if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.EDIT) {
// edit job -> edit step
result = await agentService.updateJobStep(this.ownerUri, this.stepName, JobStepData.convertToAgentJobStepInfo(this));
} else {
// has to be a create step
result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this));
}
if (!result || !result.success) {
vscode.window.showErrorMessage(

View File

@@ -29,8 +29,6 @@ export class PickScheduleData implements IAgentDialogData {
}
public async save() {
let agentService = await AgentUtils.getAgentService();
this.selectedSchedule.jobName = this.jobName;
let result = await agentService.createJobSchedule(this.ownerUri, this.selectedSchedule);
}
}

View File

@@ -12,6 +12,7 @@ import { AgentUtils } from '../agentUtils';
import { AlertData } from '../data/alertData';
import { OperatorDialog } from './operatorDialog';
import { JobDialog } from './jobDialog';
import { JobData } from '../data/jobData';
const localize = nls.loadMessageBundle();
@@ -148,14 +149,23 @@ export class AlertDialog extends AgentDialog<AlertData> {
private delayMinutesTextBox: sqlops.InputBoxComponent;
private delaySecondsTextBox: sqlops.InputBoxComponent;
private jobs: string[];
private databases: string[];
private jobModel: JobData;
public jobId: string;
public jobName: string;
constructor(ownerUri: string, alertInfo: sqlops.AgentAlertInfo = undefined, jobs: string[]) {
constructor(
ownerUri: string,
jobModel: JobData,
alertInfo: sqlops.AgentAlertInfo = undefined,
viaJobDialog: boolean = false
) {
super(ownerUri,
new AlertData(ownerUri, alertInfo),
new AlertData(ownerUri, alertInfo, jobModel, viaJobDialog),
alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle);
this.jobs = jobs;
this.jobModel = jobModel;
this.jobId = this.jobId ? this.jobId : this.jobModel.jobId;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
}
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {
@@ -512,7 +522,8 @@ export class AlertDialog extends AgentDialog<AlertData> {
protected updateModel() {
this.model.name = this.nameTextBox.value;
this.model.isEnabled = this.enabledCheckBox.checked;
this.model.jobId = this.jobId;
this.model.jobName = this.jobName;
this.model.alertType = this.getDropdownValue(this.typeDropDown);
let databaseName = this.getDropdownValue(this.databaseDropDown);
this.model.databaseName = (databaseName !== AlertDialog.AllDatabases) ? databaseName : undefined;

View File

@@ -11,6 +11,7 @@ import { PickScheduleDialog } from './pickScheduleDialog';
import { AlertDialog } from './alertDialog';
import { AgentDialog } from './agentDialog';
import { AgentUtils } from '../agentUtils';
import { JobStepData } from '../data/jobStepData';
const localize = nls.loadMessageBundle();
@@ -110,11 +111,19 @@ export class JobDialog extends AgentDialog<JobData> {
private newAlertButton: sqlops.ButtonComponent;
private isEdit: boolean = false;
// Job objects
private steps: sqlops.AgentJobStepInfo[];
private schedules: sqlops.AgentJobScheduleInfo[];
private alerts: sqlops.AgentAlertInfo[] = [];
constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) {
super(
ownerUri,
new JobData(ownerUri, jobInfo),
jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle);
this.steps = this.model.jobSteps ? this.model.jobSteps : [];
this.schedules = this.model.jobSchedules ? this.model.jobSchedules : [];
this.alerts = this.model.alerts ? this.model.alerts : [];
this.isEdit = jobInfo ? true : false;
}
@@ -198,12 +207,7 @@ export class JobDialog extends AgentDialog<JobData> {
private initializeStepsTab() {
this.stepsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text()
.withProperties({
value: 'Feature Preview'
}).component();
let steps = this.model.jobSteps ? this.model.jobSteps : [];
let data = this.convertStepsToData(steps);
let data = this.steps ? this.convertStepsToData(this.steps) : [];
this.stepsTable = view.modelBuilder.table()
.withProperties({
columns: [
@@ -237,13 +241,11 @@ export class JobDialog extends AgentDialog<JobData> {
width: 80
}).component();
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model);
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, null, true);
stepDialog.onSuccess((step) => {
if (!this.model.jobSteps) {
this.model.jobSteps = [];
}
this.model.jobSteps.push(step);
this.stepsTable.data = this.convertStepsToData(this.model.jobSteps);
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
this.steps.push(stepInfo);
this.stepsTable.data = this.convertStepsToData(this.steps);
});
this.newStepButton.onDidClick((e)=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
@@ -277,7 +279,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.deleteStepButton.enabled = true;
this.editStepButton.enabled = true;
this.editStepButton.onDidClick(() => {
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData);
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData, true);
stepDialog.openDialog();
});
@@ -287,7 +289,6 @@ export class JobDialog extends AgentDialog<JobData> {
agentService.deleteJobStep(this.ownerUri, stepData).then((result) => {
if (result && result.success) {
delete steps[rowNumber];
this.model.jobSteps = steps;
let data = this.convertStepsToData(steps);
this.stepsTable.data = data;
}
@@ -299,10 +300,6 @@ export class JobDialog extends AgentDialog<JobData> {
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: previewTag,
title: ''
},
{
component: this.stepsTable,
title: this.JobStepsTopLabelString,
actions: [this.moveStepUpButton, this.moveStepDownButton, this.newStepButton, this.editStepButton, this.deleteStepButton]
@@ -313,10 +310,6 @@ export class JobDialog extends AgentDialog<JobData> {
private initializeAlertsTab() {
this.alertsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text()
.withProperties({
value: 'Feature Preview'
}).component();
let alerts = this.model.alerts ? this.model.alerts : [];
let data = this.convertAlertsToData(alerts);
this.alertsTable = view.modelBuilder.table()
@@ -327,7 +320,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.AlertTypeLabelString
],
data: data,
height: 430,
height: 750,
width: 400
}).component();
@@ -336,18 +329,24 @@ export class JobDialog extends AgentDialog<JobData> {
width: 80
}).component();
this.newAlertButton.onDidClick((e)=>{
let alertDialog = new AlertDialog(this.model.ownerUri, null, []);
alertDialog.onSuccess((dialogModel) => {
});
alertDialog.openDialog();
let alertDialog = new AlertDialog(this.model.ownerUri, this.model, null, true);
alertDialog.onSuccess((alert) => {
let alertInfo = alert.toAgentAlertInfo();
this.alerts.push(alertInfo);
this.alertsTable.data = this.convertAlertsToData(this.alerts);
});
this.newAlertButton.onDidClick(()=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
alertDialog.jobId = this.model.jobId;
alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
alertDialog.openDialog();
} else {
this.dialog.message = { text: this.BlankJobNameErrorText };
}
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: previewTag,
title: ''
}, {
component: this.alertsTable,
title: this.AlertsTopLabelString,
actions: [this.newAlertButton]
@@ -380,8 +379,11 @@ export class JobDialog extends AgentDialog<JobData> {
pickScheduleDialog.onSuccess((dialogModel) => {
let selectedSchedule = dialogModel.selectedSchedule;
if (selectedSchedule) {
selectedSchedule.jobName = this.model.name;
this.model.addJobSchedule(selectedSchedule);
let existingSchedule = this.schedules.find(item => item.name === selectedSchedule.name);
if (!existingSchedule) {
selectedSchedule.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
this.schedules.push(selectedSchedule);
}
this.populateScheduleTable();
}
});
@@ -402,8 +404,7 @@ export class JobDialog extends AgentDialog<JobData> {
}
private populateScheduleTable() {
let schedules = this.model.jobSchedules ? this.model.jobSchedules : [];
let data = this.convertSchedulesToData(schedules);
let data = this.convertSchedulesToData(this.schedules);
if (data.length > 0) {
this.schedulesTable.data = data;
this.schedulesTable.height = 750;
@@ -566,5 +567,17 @@ export class JobDialog extends AgentDialog<JobData> {
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
if (!this.model.jobSteps) {
this.model.jobSteps = [];
}
this.model.jobSteps = this.steps;
if (!this.model.jobSchedules) {
this.model.jobSchedules = [];
}
this.model.jobSchedules = this.schedules;
if (!this.model.alerts) {
this.model.alerts = [];
}
this.model.alerts = this.alerts;
}
}

View File

@@ -118,9 +118,10 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
server: string,
jobModel: JobData,
jobStepInfo?: sqlops.AgentJobStepInfo,
viaJobDialog: boolean = false
) {
super(ownerUri,
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel),
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog),
jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle);
this.stepId = jobStepInfo ?
jobStepInfo.id : jobModel.jobSteps ?

View File

@@ -14,6 +14,7 @@ import { ProxyDialog } from './dialogs/proxyDialog';
import { JobStepDialog } from './dialogs/jobStepDialog';
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
import { JobData } from './data/jobData';
import { AgentUtils } from './agentUtils';
const localize = nls.loadMessageBundle();
@@ -41,17 +42,23 @@ export class MainController {
let dialog = new JobDialog(ownerUri, jobInfo);
dialog.openDialog();
});
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobData: JobData, jobStepInfo: sqlops.AgentJobStepInfo) => {
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo);
dialog.openDialog();
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: sqlops.AgentJobInfo, jobStepInfo: sqlops.AgentJobStepInfo) => {
AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false);
dialog.openDialog();
});
});
vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => {
let dialog = new PickScheduleDialog(ownerUri, jobName);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo, jobs: string[]) => {
let dialog = new AlertDialog(ownerUri, alertInfo, jobs);
dialog.openDialog();
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: sqlops.AgentJobInfo, alertInfo: sqlops.AgentAlertInfo) => {
AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false);
dialog.openDialog();
});
});
vscode.commands.registerCommand('agent.openOperatorDialog', (ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo) => {
let dialog = new OperatorDialog(ownerUri, operatorInfo);

View File

@@ -42,33 +42,6 @@
"mac": "ctrl+i"
}
],
"dashboard.tabs": [
{
"id": "flat-file-import",
"title": "Flat File Import",
"description": "The flat file importer.",
"container": {
"flat-file-import-container": {}
}
}
],
"dashboard.containers": [
{
"id": "flat-file-import-container",
"container": {
"widgets-container": [
{
"name": "Tasks",
"widget": {
"tasks-widget": [
"flatFileImport.start"
]
}
}
]
}
}
],
"menus": {
"objectExplorer/item/context": [
{

View File

@@ -31,7 +31,7 @@ export class FlatFileWizard {
public async start(p: any, ...args: any[]) {
let model = <ImportDataModel>{};
let profile = <sqlops.IConnectionProfile>p.connectionProfile;
let profile = p ? <sqlops.IConnectionProfile>p.connectionProfile : null;
if (profile) {
model.serverId = profile.id;
model.database = profile.databaseName;

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "1.5.0-alpha.48",
"version": "1.5.0-alpha.52",
"downloadFileNames": {
"Windows_86": "win-x86-netcoreapp2.2.zip",
"Windows_64": "win-x64-netcoreapp2.2.zip",

View File

@@ -4,66 +4,69 @@
"type": "dark",
"colors": {
// base
"foreground": "#fffffe",
"focusBorder": "#0E639C",
// base
"foreground": "#fffffe",
"focusBorder": "#0078d7",
"selection.background": "#3062d6",
//text colors
"textLinkForeground": "#30B4FF",
"textLinkActiveForeground": "#30B4FF",
//text colors
"textLinkForeground": "#30b4ff",
"textLinkActiveForeground": "#30b4ff",
//Button control
"button.background": "#00BCF2",
"button.foreground": "#212121",
"button.hoverBackground": "#0099BC",
//Button control
"button.background": "#0078d7cc",
"button.foreground": "#ffffff",
"button.hoverBackground": "#0078d7",
// TODO add support for these
// "button.secondaryBackground": "#c8c8c8",
// "button.secondaryHoverBackground": "#a6a6a6",
// "button.secondaryForeground": "#333333",
// "button.disabledBackground": "#444444" ,
// "button.disabledForeground": "#888888" ,
// TODO add support for these
// "button.secondaryBackground": "#c8c8c8",
// "button.secondaryHoverBackground": "#a6a6a6",
// "button.secondaryForeground": "#333333",
// "button.disabledBackground": "#444444" ,
// "button.disabledForeground": "#888888" ,
//Dropdown Control
"dropdown.background": "#212121",
"dropdown.foreground": "#fffffe",
"dropdown.border": "#888888",
//Checkbox
"checkbox.disabled.foreground": "#888888",
//Input Control
"input.background": "#212121",
//Dropdown Control
"dropdown.background": "#212121",
"dropdown.foreground": "#fffffe",
"dropdown.border": "#888888",
//Input Control
"input.background": "#212121",
"input.border": "#888888",
"input.disabled.background": "#444444",
"input.disabled.foreground": "#888888",
"inputOption.activeBorder": "#007ACC",
"input.placeholderForeground": "#888888",
"inputValidation.errorBackground": "#D02E00",
"inputValidation.errorBorder": "#D02E00",
"inputOption.activeBorder": "#0078d7",
"input.placeholderForeground": "#888888",
"inputValidation.errorBackground": "#b62e00",
"inputValidation.errorBorder": "#b62e00",
//List and trees
"list.activeSelectionBackground": "#3062d6",
"list.hoverBackground": "#444444",
"pickerGroup.border": "#00BCF2",
//List and trees
"list.activeSelectionBackground": "#3062d6",
"list.hoverBackground": "#444444",
"pickerGroup.border": "#0078d7",
"activityBar.background": "#444444",
"sideBar.background": "#333333",
"sideBarTitle.foreground": "#BBBBBB",
"input.placeholderForeground": "#A6A6A6",
"editorGroupHeader.tabsBackground": "#444444",
"editor.background": "#212121",
"editor.foreground": "#ffffff",
"editorWidget.background": "#444444",
"editorLink.activeForeground": "#30B4FF",
"editorGroup.border": "#333333",
"editorGroup.background": "#212121",
"editorIndentGuide.activeBackground": "#707070",
"tab.activeBackground": "#212121",
"tab.activeForeground": "#ffffff",
"tab.inactiveBackground": "#444444",
"tab.inactiveForeground": "#b6b6b6",
"sideBarTitle.foreground": "#bbbbbb",
"input.placeholderForeground": "#a6a6a6",
"editorGroupHeader.tabsBackground": "#444444",
"editor.background": "#212121",
"editor.foreground": "#ffffff",
"editorWidget.background": "#444444",
"editorLink.activeForeground": "#30b4ff",
"editorGroup.border": "#333333",
"editorGroup.background": "#212121",
"editorIndentGuide.activeBackground": "#707070",
"tab.activeBackground": "#212121",
"tab.activeForeground": "#ffffff",
"tab.inactiveBackground": "#444444",
"tab.inactiveForeground": "#b6b6b6",
"tab.border": "#3c3c3c",
"panel.background": "#212121",
"panel.border": "#515151",
"panelTitle.activeForeground": "#ffffff",
"panel.background": "#212121",
"panel.border": "#515151",
"panelTitle.activeForeground": "#ffffff",
"panelTitle.inactiveForeground": "#888888"
},
"tokenColors": [

View File

@@ -5,18 +5,18 @@
"colors": {
// base
"foreground": "#4a4a4a",
"focusBorder": "#00BCF2",
"selection.background": "#C9D0D9",
"focusBorder": "#0078d7",
"selection.background": "#c9d0d9",
"widget.shadow": "#666666",
// text colors
"textLinkForeground": "#3062D6",
"textLinkActiveForeground": "#3062D6",
"textLinkForeground": "#3062d6",
"textLinkActiveForeground": "#3062d6",
//Button control
"button.background": "#00BCF2",
"button.foreground": "#212121",
"button.hoverBackground": "#0099BC",
"button.background": "#0078d7cc",
"button.foreground": "#ffffff",
"button.hoverBackground": "#0078d7",
// TODO add support for these
// "button.secondaryBackground": "#c8c8c8",
@@ -25,35 +25,38 @@
// "button.disabledBackground": "#eaeaea",
// "button.disabledForeground": "#888888",
//Checkbox
"checkbox.disabled.foreground": "#888888",
//Dropdown Control
"dropdown.background": "#fffffe",
"dropdown.background": "#ffffff",
"dropdown.foreground": "#4a4a4a",
"dropdown.border": "#C8C8C8",
"dropdown.border": "#c8c8c8",
//badge
"badge.background": "#777777",
"badge.foreground": "#ffffff",
//Input Control
"input.background": "#fffffe",
"input.background": "#ffffff",
"input.border": "#c8c8c8",
"input.disabled.background": "#dcdcdc",
"input.disabled.foreground": "#888888",
"inputOption.activeBorder": "#666666",
"input.placeholderForeground": "#767676",
"inputValidation.errorBackground": "#ffeaea",
"inputValidation.errorBorder": "#f1897f",
"inputValidation.errorBorder": "#b62e00",
//List and tree
"list.activeSelectionBackground": "#3062d6",
"list.hoverBackground": "#dcdcdc",
"pickerGroup.border": "#00BCF2",
"pickerGroup.border": "#0078d7",
// Workbench: Activity Bar
"activityBar.background": "#212121",
// Workbench: Side Bar
"sideBar.background": "#EAEAEA",
"sideBar.background": "#eaeaea",
"editorGroupHeader.tabsBackground": "#f4f4f4",
"editor.background": "#fffffe",
"editor.foreground": "#212121",
@@ -64,15 +67,15 @@
"editorIndentGuide.activeBackground": "#939393",
// Workbench: Tabs
"tab.activeBackground": "#FFFFFE",
"tab.activeForeground": "#4A4A4A",
"tab.activeBackground": "#ffffff",
"tab.activeForeground": "#4a4a4a",
"tab.inactiveBackground": "#f4f4f4",
"tab.inactiveForeground": "#707070",
"tab.border": "#EAEAEA",
"tab.border": "#eaeaea",
"tab.unfocusedInactiveForeground": "#888888",
"tab.unfocusedActiveForeground": "#212121",
"panel.background": "#FFFFFE",
"panel.border": "#C8C8C8",
"panel.background": "#ffffff",
"panel.border": "#c8c8c8",
"panelTitle.activeForeground": "#212121",
"panelTitle.inactiveForeground": "#757575"
},

View File

@@ -1,6 +1,6 @@
{
"name": "azuredatastudio",
"version": "1.2.2",
"version": "1.2.3",
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
"author": {
"name": "Microsoft Corporation"

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Color } from 'vs/base/common/color';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Widget } from 'vs/base/browser/ui/widget';
@@ -15,9 +16,14 @@ export interface ICheckboxOptions {
ariaLabel?: string;
}
export interface ICheckboxStyles {
disabledCheckboxForeground?: Color;
}
export class Checkbox extends Widget {
private _el: HTMLInputElement;
private _label: HTMLSpanElement;
private disabledCheckboxForeground: Color;
private _onChange = new Emitter<boolean>();
public readonly onChange: Event<boolean> = this._onChange.event;
@@ -65,6 +71,7 @@ export class Checkbox extends Widget {
public set enabled(val: boolean) {
this._el.disabled = !val;
this.updateStyle();
}
public get enabled(): boolean {
@@ -90,4 +97,13 @@ export class Checkbox extends Widget {
public enable(): void {
this.enabled = true;
}
public style(styles: ICheckboxStyles): void {
this.disabledCheckboxForeground = styles.disabledCheckboxForeground;
this.updateStyle();
}
private updateStyle(): void {
this._label.style.color = !this.enabled && this.disabledCheckboxForeground ? this.disabledCheckboxForeground.toString() : 'inherit';
}
}

View File

@@ -66,14 +66,11 @@
}
.monaco-shell .modal.flyout-dialog .modal-body,
.monaco-shell .modal.flyout-dialog .angular-modal-body {
margin-bottom: auto;
height: 100%;
}
.monaco-shell .modal.flyout-dialog .angular-modal-body,
/* Style for body and footer in modal dialog. This should be applied to dialog created with angular component. */
.monaco-shell .modal.flyout-dialog .modal-body-and-footer {
height: 100%;
flex: 1 1;
overflow: hidden;
}
/* modl body content style(excluding dialogErrorMessage section) for angulr component dialog */
@@ -85,6 +82,8 @@
.modal.flyout-dialog .angular-form {
height: 100%;
display: flex;
flex-direction: column;
}
.modal.flyout-dialog .dialog-label {
@@ -105,10 +104,6 @@
padding-left: 4px;
}
.modal.flyout-dialog .modal-body {
overflow-y: auto;
}
.vs-dark.monaco-shell .modal.flyout-dialog .input {
background-color: #3C3C3C;
}
@@ -187,7 +182,6 @@
.modal.flyout-dialog .dialog-message-header {
overflow: hidden;
overflow-y: hidden;
display: flex;
flex-direction: row;
}

View File

@@ -27,7 +27,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
export const MODAL_SHOWING_KEY = 'modalShowing';
export const MODAL_SHOWING_CONTEXT = new RawContextKey<Array<string>>(MODAL_SHOWING_KEY, []);
const INFO_ALT_TEXT = localize('infoAltText', 'Infomation');
const INFO_ALT_TEXT = localize('infoAltText', 'Information');
const WARNING_ALT_TEXT = localize('warningAltText', 'Warning');
const ERROR_ALT_TEXT = localize('errorAltText', 'Error');
const SHOW_DETAILS_TEXT = localize('showMessageDetails', 'Show Details');

View File

@@ -89,10 +89,6 @@
-moz-transition-property: width;
}
.hc-black .split-view-view .action-label {
background: none;
}
.hc-black .split-view-view > .header .action-label:before {
top: 4px !important;
}

View File

@@ -12,6 +12,7 @@ export const tableHeaderForeground = registerColor('table.headerForeground', { d
export const disabledInputBackground = registerColor('input.disabled.background', { dark: '#444444', light: '#dcdcdc', hc: Color.black }, nls.localize('disabledInputBoxBackground', "Disabled Input box background."));
export const disabledInputForeground = registerColor('input.disabled.foreground', { dark: '#888888', light: '#888888', hc: foreground }, nls.localize('disabledInputBoxForeground', "Disabled Input box foreground."));
export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused."));
export const disabledCheckboxForeground = registerColor('checkbox.disabled.foreground', { dark: '#888888', light: '#888888', hc: Color.black }, nls.localize('disabledCheckboxforeground', "Disabled checkbox foreground."));
export const listFocusAndSelectionBackground = registerColor('list.focusAndSelectionBackground', { dark: '#2c3295', light: '#2c3295', hc: null }, nls.localize('listFocusAndSelectionBackground', "List/Table background color for the selected and focus item when the list/table is active"));

View File

@@ -255,3 +255,10 @@ export function attachButtonStyler(widget: IThemable, themeService: IThemeServic
buttonFocusOutline: (style && style.buttonFocusOutline) || sqlcolors.buttonFocusOutline
}, widget);
}
export function attachCheckboxStyler(widget: IThemable, themeService: IThemeService, style?: { disabledCheckboxForeground?: cr.ColorIdentifier })
: IDisposable {
return attachStyler(themeService, {
disabledCheckboxForeground: (style && style.disabledCheckboxForeground) || sqlcolors.disabledCheckboxForeground
}, widget);
}

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* 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 { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface ICommandLineProcessing {
_serviceBrand: any;
/**
* Interprets the various Azure Data Studio-specific command line switches and
* performs the requisite tasks such as connecting to a server
*/
processCommandLine() : void;
}
export const ICommandLineProcessing = createDecorator<ICommandLineProcessing>('commandLineService');

View File

@@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------------------
* 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 { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import * as Constants from 'sql/parts/connection/common/constants';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import * as platform from 'vs/platform/registry/common/platform';
import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export class CommandLineService implements ICommandLineProcessing {
private _connectionProfile: ConnectionProfile;
private _showConnectionDialog: boolean;
constructor(
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
@IEnvironmentService private _environmentService: IEnvironmentService,
@IQueryEditorService private _queryEditorService: IQueryEditorService,
@IObjectExplorerService private _objectExplorerService: IObjectExplorerService,
@IEditorService private _editorService: IEditorService,
) {
let profile = null;
if (this._environmentService && this._environmentService.args.server) {
profile = new ConnectionProfile(_capabilitiesService, null);
// We want connection store to use any matching password it finds
profile.savePassword = true;
profile.providerName = Constants.mssqlProviderName;
profile.serverName = _environmentService.args.server;
profile.databaseName = _environmentService.args.database ? _environmentService.args.database : '';
profile.userName = _environmentService.args.user ? _environmentService.args.user : '';
profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin';
profile.connectionName = '';
profile.setOptionValue('applicationName', Constants.applicationName);
profile.setOptionValue('databaseDisplayName', profile.databaseName);
profile.setOptionValue('groupId', profile.groupId);
}
this._connectionProfile = profile;
const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions);
let sqlProvider = registry.getProperties(Constants.mssqlProviderName);
// We can't connect to object explorer until the MSSQL connection provider is registered
if (sqlProvider) {
this.processCommandLine();
} else {
registry.onNewProvider(e => {
if (e.id === Constants.mssqlProviderName) {
this.processCommandLine();
}
});
}
}
public _serviceBrand: any;
public processCommandLine(): void {
if (!this._connectionProfile && !this._connectionManagementService.hasRegisteredServers()) {
// prompt the user for a new connection on startup if no profiles are registered
this._connectionManagementService.showConnectionDialog();
} else if (this._connectionProfile) {
this._connectionManagementService.connectIfNotConnected(this._connectionProfile, 'connection')
.then(result => TaskUtilities.newQuery(this._connectionProfile,
this._connectionManagementService,
this._queryEditorService,
this._objectExplorerService,
this._editorService))
.catch(() => { });
}
}
}

View File

@@ -77,7 +77,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
private _onConnectRequestSent = new Emitter<void>();
private _onConnectionChanged = new Emitter<IConnectionParams>();
private _onLanguageFlavorChanged = new Emitter<sqlops.DidChangeLanguageFlavorParams>();
private _connectionGlobalStatus = new ConnectionGlobalStatus(this._statusBarService);
private _configurationEditService: ConfigurationEditingService;
@@ -124,16 +123,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
100 /* High Priority */
));
if (_capabilitiesService && Object.keys(_capabilitiesService.providers).length > 0 && !this.hasRegisteredServers()) {
// prompt the user for a new connection on startup if no profiles are registered
this.showConnectionDialog();
} else if (_capabilitiesService && !this.hasRegisteredServers()) {
_capabilitiesService.onCapabilitiesRegistered(e => {
// prompt the user for a new connection on startup if no profiles are registered
this.showConnectionDialog();
});
}
const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions);
let providerRegistration = (p: { id: string, properties: ConnectionProviderProperties }) => {
@@ -282,29 +271,30 @@ export class ConnectionManagementService extends Disposable implements IConnecti
* @param options to use after the connection is complete
*/
private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise<IConnectionResult> {
let self = this;
return new Promise<IConnectionResult>((resolve, reject) => {
// Load the password if it's not already loaded
this._connectionStore.addSavedPassword(connection).then(result => {
self._connectionStore.addSavedPassword(connection).then(result => {
let newConnection = result.profile;
let foundPassword = result.savedCred;
// If there is no password, try to load it from an existing connection
if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection)) {
let existingConnection = this._connectionStatusManager.findConnectionProfile(connection);
if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection)) {
let existingConnection = self._connectionStatusManager.findConnectionProfile(connection);
if (existingConnection && existingConnection.connectionProfile) {
newConnection.password = existingConnection.connectionProfile.password;
foundPassword = true;
}
}
// If the password is required and still not loaded show the dialog
if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) {
resolve(this.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options));
if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) {
resolve(self.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options));
} else {
// Try to connect
this.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => {
self.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => {
if (!connectionResult.connected && !connectionResult.errorHandled) {
// If connection fails show the dialog
resolve(this.showConnectionDialogOnError(connection, owner, connectionResult, options));
resolve(self.showConnectionDialogOnError(connection, owner, connectionResult, options));
} else {
//Resolve with the connection result
resolve(connectionResult);
@@ -390,7 +380,14 @@ export class ConnectionManagementService extends Disposable implements IConnecti
if (this._connectionStatusManager.isConnected(ownerUri)) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri));
} else {
this.connect(connection, ownerUri).then(connectionResult => {
const options: IConnectionCompletionOptions = {
saveTheConnection: false,
showConnectionDialogOnError: true,
showDashboard: purpose === 'dashboard',
params: undefined,
showFirewallRuleOnError: true,
};
this.connect(connection, ownerUri, options).then(connectionResult => {
if (connectionResult && connectionResult.connected) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri));
} else {

View File

@@ -17,7 +17,7 @@ import { IConnectionProfile } from 'sql/parts/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 { attachInputBoxStyler, attachButtonStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler';
import { attachButtonStyler, attachCheckboxStyler, attachEditableDropdownStyler, attachInputBoxStyler } from 'sql/common/theme/styler';
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
@@ -83,7 +83,7 @@ export class ConnectionWidget {
};
public NoneServerGroup: IConnectionProfileGroup = {
id: '',
name: localize('noneServerGroup', '<None>'),
name: localize('noneServerGroup', '<Do not save>'),
parentId: undefined,
color: undefined,
description: undefined,
@@ -274,6 +274,7 @@ export class ConnectionWidget {
this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService));
this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService));
this._toDispose.push(attachButtonStyler(this._advancedButton, this._themeService));
this._toDispose.push(attachCheckboxStyler(this._rememberPasswordCheckBox, this._themeService));
if (this._authTypeSelectBox) {
// Theme styler

View File

@@ -14,7 +14,7 @@ import { ModalFooterStyle } from 'sql/base/browser/ui/modal/modal';
import { CategoryView } from 'sql/base/browser/ui/modal/optionsDialog';
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
import { SplitView } from 'sql/base/browser/ui/splitview/splitview';
import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'sql/common/theme/styler';
import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler, attachCheckboxStyler } from 'sql/common/theme/styler';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants';
import { IBackupService, IBackupUiService, TaskExecutionMode } from 'sql/parts/disasterRecovery/backup/common/backupService';
@@ -523,6 +523,11 @@ export class BackupComponent {
this._toDispose.push(attachInputBoxStyler(this.mediaNameBox, this.themeService));
this._toDispose.push(attachInputBoxStyler(this.mediaDescriptionBox, this.themeService));
this._toDispose.push(attachInputBoxStyler(this.backupRetainDaysBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.copyOnlyCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.encryptCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.verifyCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.checksumCheckBox, this.themeService));
this._toDispose.push(attachCheckboxStyler(this.continueOnErrorCheckBox, this.themeService));
this._toDispose.push(this.backupTypeSelectBox.onDidSelect(selected => this.onBackupTypeChanged()));
this.addButtonClickHandler(this.addPathButton, () => this.onAddClick());

View File

@@ -17,7 +17,7 @@
}
.backup-dialog {
height: calc(100% - 15px)
height: 100%
}
.backup-dialog .advanced-main-header {

View File

@@ -33,7 +33,7 @@ import { Table } from 'sql/base/browser/ui/table/table';
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper';
import { Modal } from 'sql/base/browser/ui/modal/modal';
import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler';
import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler, attachCheckboxStyler } from 'sql/common/theme/styler';
import * as TelemetryKeys from 'sql/common/telemetryKeys';
import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants';
import { RestoreViewModel, RestoreOptionParam, SouceDatabaseNamesParam } from 'sql/parts/disasterRecovery/restore/restoreViewModel';
@@ -532,6 +532,7 @@ export class RestoreDialog extends Modal {
ariaLabel: label
});
});
this._register(attachCheckboxStyler(checkbox, this._themeService));
return checkbox;
}

View File

@@ -1,8 +1,7 @@
div.qp-node {
background-color: #FFFFCC;
margin: 2px;
padding: 2px;
border: 1px solid black;
border: 1px solid;
}
div.qp-statement-header {
margin: 2px;
@@ -33,8 +32,7 @@ div[class|='qp-icon'] {
.qp-tt {
top: 4em;
left: 2em;
border: 1px solid black;
background-color: #FFFFEE;
border: 1px solid;
padding: 2px;
width: 30em;
}
@@ -56,7 +54,7 @@ div[class|='qp-icon'] {
.qp-tt td,
.qp-tt th {
font-size: 11px;
border-bottom: solid 1px Black;
border-bottom: solid 1px;
padding: 1px;
}
@@ -204,8 +202,6 @@ div.qp-node:hover .qp-tt {
.qp-root {
display: table;
position: relative;
background-color: #fff;
color: #000;
}
.qp-root svg {

View File

@@ -219,14 +219,10 @@ export class NewStepAction extends Action {
public run(context: JobHistoryComponent): TPromise<boolean> {
let ownerUri = context.ownerUri;
let jobName = context.agentJobInfo.name;
let server = context.serverName;
let stepId = 0;
if (context.agentJobHistoryInfo && context.agentJobHistoryInfo.steps) {
stepId = context.agentJobHistoryInfo.steps.length + 1;
}
let jobInfo = context.agentJobInfo;
return new TPromise<boolean>((resolve, reject) => {
resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, jobName, server, stepId));
resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, server, jobInfo , null));
});
}
}

View File

@@ -923,33 +923,17 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
let steps = this.jobSteps[jobId];
job[0].JobSteps = steps;
}
let jobHistories = this.jobHistories[job[0].jobId];
let schedules: sqlops.AgentJobScheduleInfo[] = this.jobSchedules[job[0].jobId];
let alerts: sqlops.AgentAlertInfo[] = this.jobAlerts[job[0].jobId];
if (jobHistories && jobHistories[jobHistories.length-1]) {
// add schedules
if (schedules && schedules.length > 0) {
if (!job[0].JobSchedules) {
job[0].JobSchedules = [];
}
if (job[0].JobSchedules.length !== schedules.length) {
job[0].JobSchedules = [];
schedules.forEach(schedule => {
job[0].JobSchedules.push(schedule);
});
}
}
// add alerts
if (!job[0].Alerts) {
job[0].Alerts = [];
}
if (job[0].Alerts.length !== alerts.length) {
job[0].Alerts = [];
alerts.forEach(alert => {
job[0].Alerts.push(alert);
});
}
// add schedules
if (this.jobSchedules && this.jobSchedules[jobId]) {
let schedules = this.jobSchedules[jobId];
job[0].JobSchedules = schedules;
}
// add alerts
if (this.jobAlerts && this.jobAlerts[jobId]) {
let alerts = this.jobAlerts[jobId];
job[0].Alerts = alerts;
}
return job && job.length > 0 ? job[0] : undefined;
}

View File

@@ -14,6 +14,8 @@ import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
import { Checkbox, ICheckboxOptions } from 'sql/base/browser/ui/checkbox/checkbox';
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
import { attachCheckboxStyler } from 'sql/common/theme/styler';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
@Component({
selector: 'modelview-checkbox',
@@ -30,7 +32,8 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,) {
super(changeRef, el);
}
@@ -55,6 +58,7 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
args: e
});
}));
this._register(attachCheckboxStyler(this._input, this.themeService));
}
}

View File

@@ -326,7 +326,7 @@ export class ChartView extends Disposable implements IPanelView {
this.optionDisposables.push(attachInputBoxStyler(numberInput, this._themeService));
break;
case ControlType.dateInput:
let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'date' });
let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'datetime-local' });
dateInput.value = value || '';
dateInput.onDidChange(e => {
if (this.options[option.configEntry] !== e) {

View File

@@ -19,7 +19,7 @@ import { ChartType, DataDirection, LegendPosition, DataType, IPointDataSet, cust
const noneLineGraphs = [ChartType.Doughnut, ChartType.Pie];
const timeSeriesScales = {
const timeSeriesScales: ChartJs.ChartOptions = {
scales: {
xAxes: [{
type: 'time',
@@ -64,7 +64,7 @@ export class Graph implements IInsight {
this._theme = e;
this.data = this._data;
});
this._options = mixin(options, defaultOptions, false);
this.options = mixin(options, defaultOptions, false);
let canvasContainer = document.createElement('div');
canvasContainer.style.width = '100%';
@@ -89,9 +89,12 @@ export class Graph implements IInsight {
}
public set data(data: IInsightData) {
if (!data) {
return;
}
this._data = data;
let chartData: Array<ChartJs.ChartDataSets>;
let labels: Array<string>;
let chartData: Array<ChartJs.ChartDataSets>;
if (this.options.dataDirection === DataDirection.Horizontal) {
if (this.options.labelFirstColumn) {
@@ -158,19 +161,19 @@ export class Graph implements IInsight {
if (this.chartjs) {
this.chartjs.data.datasets = chartData;
this.chartjs.config.type = this.options.type;
this.chartjs.data.labels = labels;
// we don't want to include lables for timeSeries
this.chartjs.data.labels = this.originalType === 'timeSeries' ? [] : labels;
this.chartjs.options = this.transformOptions(this.options);
this.chartjs.update(0);
} else {
this.chartjs = new ChartJs(this.canvas.getContext('2d'), {
data: {
labels: labels,
// we don't want to include lables for timeSeries
labels: this.originalType === 'timeSeries' ? [] : labels,
datasets: chartData
},
type: this.options.type,
options: {
maintainAspectRatio: false
}
options: this.transformOptions(this.options)
});
}
}
@@ -197,15 +200,21 @@ export class Graph implements IInsight {
display: options.xAxisLabel ? true : false
},
ticks: {
fontColor: foreground,
max: options.xAxisMax,
min: options.xAxisMin
fontColor: foreground
},
gridLines: {
color: gridLines
}
}];
if (options.xAxisMax) {
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { max: options.xAxisMax } }] }, true, customMixin);
}
if (options.xAxisMin) {
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { min: options.xAxisMin } }] }, true, customMixin);
}
retval.scales.yAxes = [{
scaleLabel: {
fontColor: foreground,
@@ -213,22 +222,27 @@ export class Graph implements IInsight {
display: options.yAxisLabel ? true : false
},
ticks: {
fontColor: foreground,
max: options.yAxisMax,
min: options.yAxisMin
fontColor: foreground
},
gridLines: {
color: gridLines
}
}];
if (options.yAxisMax) {
retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { max: options.yAxisMax } }] }, true, customMixin);
}
if (options.yAxisMin) {
retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { min: options.yAxisMin } }] }, true, customMixin);
}
if (this.originalType === ChartType.TimeSeries) {
retval = mixin(retval, timeSeriesScales, true, customMixin);
if (options.xAxisMax) {
retval = mixin(retval, {
scales: {
xAxes: [{
type: 'time',
time: {
max: options.xAxisMax
}
@@ -241,7 +255,6 @@ export class Graph implements IInsight {
retval = mixin(retval, {
scales: {
xAxes: [{
type: 'time',
time: {
min: options.xAxisMin
}

View File

@@ -93,6 +93,10 @@ export class QueryPlan {
QP.showPlan(this.container, this._xml, {
jsTooltips: false
});
(<any>this.container.querySelectorAll('div.qp-tt')).forEach(toolTip=>{
toolTip.classList.add('monaco-editor');
toolTip.classList.add('monaco-editor-hover');
});
}
public get xml(): string {

View 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 Constants from 'sql/parts/connection/common/constants';
import * as Utils from 'sql/parts/connection/common/utils';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import * as sqlops from 'sqlops';
import { TPromise } from 'vs/base/common/winjs.base';
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { CapabilitiesService, ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService';
import { QueryEditorService } from 'sql/parts/query/services/queryEditorService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import {
IConnectionManagementService, IConnectionDialogService, INewConnectionParams,
ConnectionType, IConnectableInput, IConnectionCompletionOptions, IConnectionCallbacks,
IConnectionParams, IConnectionResult, IServerGroupController, IServerGroupDialogCallbacks,
RunQueryOnConnectionMode
} from 'sql/parts/connection/common/connectionManagement';
import { ConnectionStore } from 'sql/parts/connection/common/connectionStore';
import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test';
class TestParsedArgs implements ParsedArgs{
[arg: string]: any;
_: string[];
aad?: boolean;
add?: boolean;
database?:string;
debugBrkPluginHost?: string;
debugBrkSearch?: string;
debugId?: string;
debugPluginHost?: string;
debugSearch?: string;
diff?: boolean;
'disable-crash-reporter'?: string;
'disable-extension'?: string | string[];
'disable-extensions'?: boolean;
'disable-restore-windows'?: boolean;
'disable-telemetry'?: boolean;
'disable-updates'?: string;
'driver'?: string;
'enable-proposed-api'?: string | string[];
'export-default-configuration'?: string;
'extensions-dir'?: string;
extensionDevelopmentPath?: string;
extensionTestsPath?: string;
'file-chmod'?: boolean;
'file-write'?: boolean;
'folder-uri'?: string | string[];
goto?: boolean;
help?: boolean;
'install-extension'?: string | string[];
'install-source'?: string;
integrated?: boolean;
'list-extensions'?: boolean;
locale?: string;
log?: string;
logExtensionHostCommunication?: boolean;
'max-memory'?: number;
'new-window'?: boolean;
'open-url'?: boolean;
performance?: boolean;
'prof-append-timers'?: string;
'prof-startup'?: string;
'prof-startup-prefix'?: string;
'reuse-window'?: boolean;
server?: string;
'show-versions'?: boolean;
'skip-add-to-recently-opened'?: boolean;
'skip-getting-started'?: boolean;
'skip-release-notes'?: boolean;
status?: boolean;
'sticky-quickopen'?: boolean;
'uninstall-extension'?: string | string[];
'unity-launch'?: boolean; // Always open a new window, except if opening the first window or opening a file or folder as part of the launch.
'upload-logs'?: string;
user?: string;
'user-data-dir'?: string;
_urls?: string[];
verbose?: boolean;
version?: boolean;
wait?: boolean;
waitMarkerFilePath?: string;
}
suite('commandLineService tests', () => {
let capabilitiesService: CapabilitiesTestService;
let commandLineService : CommandLineService;
let environmentService : TypeMoq.Mock<EnvironmentService>;
let queryEditorService : TypeMoq.Mock<QueryEditorService>;
let editorService:TypeMoq.Mock<IEditorService>;
let objectExplorerService : TypeMoq.Mock<ObjectExplorerService>;
let connectionStore: TypeMoq.Mock<ConnectionStore>;
setup(() => {
capabilitiesService = new CapabilitiesTestService();
connectionStore = TypeMoq.Mock.ofType(ConnectionStore);
});
function getCommandLineService(connectionManagementService : IConnectionManagementService,
environmentService? : IEnvironmentService,
capabilitiesService? : ICapabilitiesService
) : CommandLineService
{
let service= new CommandLineService(
connectionManagementService,
capabilitiesService,
environmentService,
undefined,
undefined,
undefined
);
return service;
}
test('processCommandLine shows connection dialog by default', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable();
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => false);
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.verifiable(TypeMoq.Times.never());
let service = getCommandLineService(connectionManagementService.object);
service.processCommandLine();
connectionManagementService.verifyAll();
done();
});
test('processCommandLine does nothing if registered servers exist and no server name is provided', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true);
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.verifiable(TypeMoq.Times.never());
let service = getCommandLineService(connectionManagementService.object);
service.processCommandLine();
connectionManagementService.verifyAll();
done();
});
test('processCommandLine opens a new connection if a server name is passed', done => {
const connectionManagementService : TypeMoq.Mock<IConnectionManagementService>
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
const environmentService : TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
const args : TestParsedArgs = new TestParsedArgs();
args.server = 'myserver';
args.database = 'mydatabase';
environmentService.setup(e => e.args).returns(() => args).verifiable(TypeMoq.Times.atLeastOnce());
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true).verifiable(TypeMoq.Times.atMostOnce());
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), 'connection'))
.returns(() => new Promise<string>((resolve, reject) => { reject('unused');}))
.verifiable(TypeMoq.Times.once());
let service = getCommandLineService(connectionManagementService.object, environmentService.object, capabilitiesService);
service.processCommandLine();
environmentService.verifyAll();
connectionManagementService.verifyAll();
done();
});
});

View File

@@ -62,6 +62,13 @@ export interface ParsedArgs {
'upload-logs'?: string;
'driver'?: string;
'driver-verbose'?: boolean;
// {{SQL CARBON EDIT}}
aad?: boolean;
database?: string;
integrated?: boolean;
server?: string;
user?: string;
// {{SQL CARBON EDIT}}
}
export const IEnvironmentService = createDecorator<IEnvironmentService>('environmentService');

View File

@@ -33,7 +33,12 @@ const options: minimist.Opts = {
'export-default-configuration',
'install-source',
'upload-logs',
'driver'
'driver',
// {{SQL CARBON EDIT}}
'database',
'server',
'user',
// {{SQL CARBON EDIT}}
],
boolean: [
'help',
@@ -66,7 +71,11 @@ const options: minimist.Opts = {
'status',
'file-write',
'file-chmod',
'driver-verbose'
'driver-verbose',
// {{SQL CARBON EDIT}}
'aad',
'integrated',
// {{SQL CARBON EDIT}}
],
alias: {
add: 'a',
@@ -85,6 +94,12 @@ const options: minimist.Opts = {
'debugBrkPluginHost': 'inspect-brk-extensions',
'debugSearch': 'inspect-search',
'debugBrkSearch': 'inspect-brk-search',
// {{SQL CARBON EDIT}}
database: 'D',
integrated: 'E',
server: 'S',
user: 'U',
// {{SQL CARBON EDIT}}
}
};

View File

@@ -172,6 +172,10 @@ import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay';
// {{SQL CARBON EDIT}}
import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine';
import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService';
// {{SQL CARBON EDIT}}
interface WorkbenchParams {
configuration: IWindowConfiguration;
@@ -575,7 +579,9 @@ export class Workbench extends Disposable implements IPartService {
serviceCollection.set(IAccountManagementService, accountManagementService);
serviceCollection.set(IAccountPickerService, this.instantiationService.createInstance(AccountPickerService));
serviceCollection.set(IProfilerService, this.instantiationService.createInstance(ProfilerService));
// {{SQL CARBON EDIT}}
serviceCollection.set(ICommandLineProcessing, this.instantiationService.createInstance(CommandLineService));
// {{SQL CARBON EDIT}}
this._register(toDisposable(() => connectionManagementService.shutdown()));
this._register(toDisposable(() => accountManagementService.shutdown()));
this._register(toDisposable(() => capabilitiesService.shutdown()));