mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-04 11:01:38 -05:00
Merge branch 'master' into release/1.3
This commit is contained in:
@@ -69,7 +69,7 @@ export class AlertData implements IAgentDialogData {
|
|||||||
this.eventDescriptionKeyword = alertInfo.eventDescriptionKeyword;
|
this.eventDescriptionKeyword = alertInfo.eventDescriptionKeyword;
|
||||||
this.eventSource = alertInfo.eventSource;
|
this.eventSource = alertInfo.eventSource;
|
||||||
this.hasNotification = alertInfo.hasNotification;
|
this.hasNotification = alertInfo.hasNotification;
|
||||||
this.includeEventDescription = alertInfo.includeEventDescription.toString();
|
this.includeEventDescription = alertInfo.includeEventDescription ? alertInfo.includeEventDescription.toString() : null;
|
||||||
this.isEnabled = alertInfo.isEnabled;
|
this.isEnabled = alertInfo.isEnabled;
|
||||||
this.jobId = alertInfo.jobId;
|
this.jobId = alertInfo.jobId;
|
||||||
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
|
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
|
||||||
@@ -82,7 +82,7 @@ export class AlertData implements IAgentDialogData {
|
|||||||
this.databaseName = alertInfo.databaseName;
|
this.databaseName = alertInfo.databaseName;
|
||||||
this.countResetDate = alertInfo.countResetDate;
|
this.countResetDate = alertInfo.countResetDate;
|
||||||
this.categoryName = alertInfo.categoryName;
|
this.categoryName = alertInfo.categoryName;
|
||||||
this.alertType = alertInfo.alertType.toString();
|
this.alertType = alertInfo.alertType ? alertInfo.alertType.toString() : null;
|
||||||
this.wmiEventNamespace = alertInfo.wmiEventNamespace;
|
this.wmiEventNamespace = alertInfo.wmiEventNamespace;
|
||||||
this.wmiEventQuery = alertInfo.wmiEventQuery;
|
this.wmiEventQuery = alertInfo.wmiEventQuery;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async deploy() {
|
private async deploy() {
|
||||||
let service = await DataTierApplicationWizard.getService();
|
let service = await DataTierApplicationWizard.getService(this.model.server.providerName);
|
||||||
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
|
|
||||||
let result = await service.deployDacpac(this.model.filePath, this.model.database, this.model.upgradeExisting, ownerUri, sqlops.TaskExecutionMode.execute);
|
let result = await service.deployDacpac(this.model.filePath, this.model.database, this.model.upgradeExisting, ownerUri, sqlops.TaskExecutionMode.execute);
|
||||||
@@ -213,7 +213,7 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async extract() {
|
private async extract() {
|
||||||
let service = await DataTierApplicationWizard.getService();
|
let service = await DataTierApplicationWizard.getService(this.model.server.providerName);
|
||||||
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
|
|
||||||
let result = await service.extractDacpac(this.model.database, this.model.filePath, this.model.database, this.model.version, ownerUri, sqlops.TaskExecutionMode.execute);
|
let result = await service.extractDacpac(this.model.database, this.model.filePath, this.model.database, this.model.version, ownerUri, sqlops.TaskExecutionMode.execute);
|
||||||
@@ -224,7 +224,7 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async export() {
|
private async export() {
|
||||||
let service = await DataTierApplicationWizard.getService();
|
let service = await DataTierApplicationWizard.getService(this.model.server.providerName);
|
||||||
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
|
|
||||||
let result = await service.exportBacpac(this.model.database, this.model.filePath, ownerUri, sqlops.TaskExecutionMode.execute);
|
let result = await service.exportBacpac(this.model.database, this.model.filePath, ownerUri, sqlops.TaskExecutionMode.execute);
|
||||||
@@ -235,7 +235,7 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async import() {
|
private async import() {
|
||||||
let service = await DataTierApplicationWizard.getService();
|
let service = await DataTierApplicationWizard.getService(this.model.server.providerName);
|
||||||
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
let ownerUri = await sqlops.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
|
|
||||||
let result = await service.importBacpac(this.model.filePath, this.model.database, ownerUri, sqlops.TaskExecutionMode.execute);
|
let result = await service.importBacpac(this.model.filePath, this.model.database, ownerUri, sqlops.TaskExecutionMode.execute);
|
||||||
@@ -245,9 +245,8 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getService(): Promise<sqlops.DacFxServicesProvider> {
|
private static async getService(providerName: string): Promise<sqlops.DacFxServicesProvider> {
|
||||||
let currentConnection = await sqlops.connection.getCurrentConnection();
|
let service = sqlops.dataprotocol.getProvider<sqlops.DacFxServicesProvider>(providerName, sqlops.DataProviderType.DacFxServicesProvider);
|
||||||
let service = sqlops.dataprotocol.getProvider<sqlops.DacFxServicesProvider>(currentConnection.providerName, sqlops.DataProviderType.DacFxServicesProvider);
|
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
|
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
|
||||||
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
|
|
||||||
export interface IObservableCollection<T> {
|
export interface IObservableCollection<T> {
|
||||||
getLength(): number;
|
getLength(): number;
|
||||||
@@ -14,16 +15,12 @@ export interface IObservableCollection<T> {
|
|||||||
dispose(): void;
|
dispose(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoadCancellationToken {
|
|
||||||
isCancelled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DataWindow<T> {
|
class DataWindow<T> {
|
||||||
private _data: T[];
|
private _data: T[];
|
||||||
private _length: number = 0;
|
private _length: number = 0;
|
||||||
private _offsetFromDataSource: number = -1;
|
private _offsetFromDataSource: number = -1;
|
||||||
|
|
||||||
private lastLoadCancellationToken: LoadCancellationToken;
|
private cancellationToken = new CancellationTokenSource();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private loadFunction: (offset: number, count: number) => Thenable<T[]>,
|
private loadFunction: (offset: number, count: number) => Thenable<T[]>,
|
||||||
@@ -36,9 +33,7 @@ class DataWindow<T> {
|
|||||||
this.loadFunction = undefined;
|
this.loadFunction = undefined;
|
||||||
this.placeholderItemGenerator = undefined;
|
this.placeholderItemGenerator = undefined;
|
||||||
this.loadCompleteCallback = undefined;
|
this.loadCompleteCallback = undefined;
|
||||||
if (this.lastLoadCancellationToken) {
|
this.cancellationToken.cancel();
|
||||||
this.lastLoadCancellationToken.isCancelled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getStartIndex(): number {
|
public getStartIndex(): number {
|
||||||
@@ -65,17 +60,16 @@ class DataWindow<T> {
|
|||||||
this._length = length;
|
this._length = length;
|
||||||
this._data = undefined;
|
this._data = undefined;
|
||||||
|
|
||||||
if (this.lastLoadCancellationToken) {
|
this.cancellationToken.cancel();
|
||||||
this.lastLoadCancellationToken.isCancelled = true;
|
this.cancellationToken = new CancellationTokenSource();
|
||||||
}
|
const currentCancellation = this.cancellationToken;
|
||||||
|
|
||||||
if (length === 0) {
|
if (length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastLoadCancellationToken = new LoadCancellationToken();
|
|
||||||
this.loadFunction(offset, length).then(data => {
|
this.loadFunction(offset, length).then(data => {
|
||||||
if (!this.lastLoadCancellationToken.isCancelled) {
|
if (!currentCancellation.token.isCancellationRequested) {
|
||||||
this._data = data;
|
this._data = data;
|
||||||
this.loadCompleteCallback(this._offsetFromDataSource, this._offsetFromDataSource + this._length);
|
this.loadCompleteCallback(this._offsetFromDataSource, this._offsetFromDataSource + this._length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
|||||||
this._onRowCountChange.fire();
|
this._onRowCountChange.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
find(exp: string): Thenable<IFindPosition> {
|
find(exp: string, maxMatches: number = 0): Thenable<IFindPosition> {
|
||||||
if (!this._findFn) {
|
if (!this._findFn) {
|
||||||
return TPromise.wrapError(new Error('no find function provided'));
|
return TPromise.wrapError(new Error('no find function provided'));
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,8 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
|||||||
this._onFindCountChange.fire(this._findArray.length);
|
this._onFindCountChange.fire(this._findArray.length);
|
||||||
if (exp) {
|
if (exp) {
|
||||||
this._findObs = Observable.create((observer: Observer<IFindPosition>) => {
|
this._findObs = Observable.create((observer: Observer<IFindPosition>) => {
|
||||||
this._data.forEach((item, i) => {
|
for (let i = 0; i < this._data.length; i++) {
|
||||||
|
let item = this._data[i];
|
||||||
let result = this._findFn(item, exp);
|
let result = this._findFn(item, exp);
|
||||||
if (result) {
|
if (result) {
|
||||||
result.forEach(pos => {
|
result.forEach(pos => {
|
||||||
@@ -96,8 +97,11 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
|
|||||||
observer.next(index);
|
observer.next(index);
|
||||||
this._onFindCountChange.fire(this._findArray.length);
|
this._onFindCountChange.fire(this._findArray.length);
|
||||||
});
|
});
|
||||||
|
if (maxMatches > 0 && this._findArray.length > maxMatches) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
return this._findObs.take(1).toPromise().then(() => {
|
return this._findObs.take(1).toPromise().then(() => {
|
||||||
return this._findArray[this._findIndex];
|
return this._findArray[this._findIndex];
|
||||||
|
|||||||
@@ -304,14 +304,6 @@ table.jobprevruns > tbody {
|
|||||||
background-image: url('refresh_inverse.svg');
|
background-image: url('refresh_inverse.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobsview-component .agent-actionbar-container {
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-actionbar-container .monaco-action-bar > ul.actions-container > li.action-item {
|
.agent-actionbar-container .monaco-action-bar > ul.actions-container > li.action-item {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
@@ -414,4 +406,11 @@ jobsview-component .jobview-grid .slick-cell.error-row {
|
|||||||
#proxiesDiv .proxyview-proxynameindicatordisabled {
|
#proxiesDiv .proxyview-proxynameindicatordisabled {
|
||||||
width: 5px;
|
width: 5px;
|
||||||
background: red;
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#jobsDiv jobsview-component .monaco-toolbar.carbon-taskbar,
|
||||||
|
#operatorsDiv joboperatorsview-component .monaco-toolbar.carbon-taskbar,
|
||||||
|
#alertsDiv jobalertsview-component .monaco-toolbar.carbon-taskbar,
|
||||||
|
#proxiesDiv jobproxiesview-component .monaco-toolbar.carbon-taskbar {
|
||||||
|
margin: 10px 0px 10px 0px;
|
||||||
}
|
}
|
||||||
@@ -156,8 +156,8 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div #jobsteps style="flex: 1 1 auto; position: relative">
|
<div #jobsteps *ngIf="showSteps === true" style="flex: 1 1 auto; position: relative">
|
||||||
<jobstepsview-component *ngIf="showSteps === true" style="position: absolute; height: 100%; width: 100%"></jobstepsview-component>
|
<jobstepsview-component *ngIf="showSteps === true"></jobstepsview-component>
|
||||||
</div>
|
</div>
|
||||||
<h3 *ngIf="showSteps === false">No Steps Available</h3>
|
<h3 *ngIf="showSteps === false">No Steps Available</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
|||||||
private _agentJobInfo: sqlops.AgentJobInfo;
|
private _agentJobInfo: sqlops.AgentJobInfo;
|
||||||
private _noJobsAvailable: boolean = false;
|
private _noJobsAvailable: boolean = false;
|
||||||
|
|
||||||
private static readonly INITIAL_TREE_HEIGHT: number = 780;
|
|
||||||
private static readonly HEADING_HEIGHT: number = 24;
|
private static readonly HEADING_HEIGHT: number = 24;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
.all-jobs {
|
.all-jobs {
|
||||||
display: inline;
|
display: inline;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
padding-bottom: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview-container .overview-tab .resultsViewCollapsible {
|
.overview-container .overview-tab .resultsViewCollapsible {
|
||||||
@@ -266,14 +265,22 @@ jobhistory-component > .jobhistory-heading-container > .icon.in-progress {
|
|||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
jobhistory-component > .agent-actionbar-container {
|
||||||
border-top: 3px solid #f4f4f4;
|
border-top: 3px solid #f4f4f4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vs-dark jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
.vs-dark jobhistory-component > .agent-actionbar-container {
|
||||||
border-top: 3px solid #444444;
|
border-top: 3px solid #444444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hc-black jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
.hc-black jobhistory-component > .agent-actionbar-container {
|
||||||
border-top: 3px solid #2b56f2;
|
border-top: 3px solid #2b56f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobhistory-component .step-table.prev-run-list .monaco-tree-wrapper .monaco-tree-row {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobhistory-component .agent-actionbar-container > .monaco-toolbar.carbon-taskbar {
|
||||||
|
margin: 10px 0px 5px 0px;
|
||||||
}
|
}
|
||||||
@@ -80,4 +80,11 @@
|
|||||||
jobstepsview-component {
|
jobstepsview-component {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobstepsview-component .steps-tree .monaco-tree-wrapper .monaco-tree-row {
|
||||||
|
width: 99.2%;
|
||||||
|
}
|
||||||
@@ -591,7 +591,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
|
|||||||
|
|
||||||
private async curateJobHistory(jobs: sqlops.AgentJobInfo[], ownerUri: string) {
|
private async curateJobHistory(jobs: sqlops.AgentJobInfo[], ownerUri: string) {
|
||||||
const self = this;
|
const self = this;
|
||||||
jobs.forEach(async (job) => {
|
await Promise.all(jobs.map(async (job) => {
|
||||||
await this._jobManagementService.getJobHistory(ownerUri, job.jobId, job.name).then(async(result) => {
|
await this._jobManagementService.getJobHistory(ownerUri, job.jobId, job.name).then(async(result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
self.jobSteps[job.jobId] = result.steps ? result.steps : [];
|
self.jobSteps[job.jobId] = result.steps ? result.steps : [];
|
||||||
@@ -622,32 +622,23 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private createJobChart(jobId: string, jobHistories: sqlops.AgentJobHistoryInfo[]): void {
|
private createJobChart(jobId: string, jobHistories: sqlops.AgentJobHistoryInfo[]): void {
|
||||||
let chartHeights = this.getChartHeights(jobHistories);
|
let chartHeights = this.getChartHeights(jobHistories);
|
||||||
let runCharts = [];
|
let runCharts = [];
|
||||||
for (let i = 0; i < jobHistories.length; i++) {
|
for (let i = 0; i < chartHeights.length; i++) {
|
||||||
let runGraph = $(`table#${jobId}.jobprevruns > tbody > tr > td > div.bar${i}`);
|
let runGraph = $(`table#${jobId}.jobprevruns > tbody > tr > td > div.bar${i}`);
|
||||||
if (jobHistories && jobHistories.length > 0) {
|
runGraph.css('height', chartHeights[i]);
|
||||||
runGraph.css('height', chartHeights[i]);
|
let bgColor = jobHistories[i].runStatus === 0 ? 'red' : 'green';
|
||||||
let bgColor = jobHistories[i].runStatus === 0 ? 'red' : 'green';
|
runGraph.css('background', bgColor);
|
||||||
runGraph.css('background', bgColor);
|
runGraph.hover((e) => {
|
||||||
runGraph.hover((e) => {
|
let currentTarget = e.currentTarget;
|
||||||
let currentTarget = e.currentTarget;
|
currentTarget.title = jobHistories[i].runDuration;
|
||||||
currentTarget.title = jobHistories[i].runDuration;
|
});
|
||||||
});
|
if (runGraph.get(0)) {
|
||||||
if (runGraph.get(0)) {
|
runCharts.push(runGraph.get(0).outerHTML);
|
||||||
runCharts.push(runGraph.get(0).outerHTML);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
runGraph.css('height', '5px');
|
|
||||||
runGraph.css('background', 'red');
|
|
||||||
runGraph.hover((e) => {
|
|
||||||
let currentTarget = e.currentTarget;
|
|
||||||
currentTarget.title = 'Job not run.';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (runCharts.length > 0) {
|
if (runCharts.length > 0) {
|
||||||
@@ -658,7 +649,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
|
|||||||
// chart height normalization logic
|
// chart height normalization logic
|
||||||
private getChartHeights(jobHistories: sqlops.AgentJobHistoryInfo[]): string[] {
|
private getChartHeights(jobHistories: sqlops.AgentJobHistoryInfo[]): string[] {
|
||||||
if (!jobHistories || jobHistories.length === 0) {
|
if (!jobHistories || jobHistories.length === 0) {
|
||||||
return ['5px', '5px', '5px', '5px', '5px'];
|
return [];
|
||||||
}
|
}
|
||||||
let maxDuration: number = 0;
|
let maxDuration: number = 0;
|
||||||
jobHistories.forEach(history => {
|
jobHistories.forEach(history => {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
</code-component>
|
</code-component>
|
||||||
</div>
|
</div>
|
||||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: row">
|
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: row">
|
||||||
<div #preview style="flex: 1 1 auto; user-select: initial;" (dblclick)="toggleEditMode()">
|
<div #preview class ="notebook-preview" style="flex: 1 1 auto; user-select: initial;" (dblclick)="toggleEditMode()">
|
||||||
</div>
|
</div>
|
||||||
<div #moreactions class="moreActions" style="flex: 0 0 auto; display: flex; flex-flow:column;width: 20px; min-height: 20px; max-height: 20px; padding-top: 0px; orientation: portrait">
|
<div #moreactions class="moreActions" style="flex: 0 0 auto; display: flex; flex-flow:column;width: 20px; min-height: 20px; max-height: 20px; padding-top: 0px; orientation: portrait">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -149,10 +149,10 @@ export class SparkMagicContexts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let profile = connectionInfo as IConnectionProfile;
|
let profile = connectionInfo as IConnectionProfile;
|
||||||
if (foundSavedKernelInSpecs && specs && connectionInfo && profile.providerName === notebookConstants.hadoopKnoxProviderName) {
|
if (specs && connectionInfo && profile.providerName === notebookConstants.hadoopKnoxProviderName) {
|
||||||
// set default kernel to default spark kernel if profile exists
|
// set default kernel to default spark kernel if profile exists
|
||||||
// otherwise, set default to kernel info loaded from existing file
|
// otherwise, set default to kernel info loaded from existing file
|
||||||
defaultKernel = !savedKernelInfo ? specs.kernels.find((spec) => spec.name === notebookConstants.defaultSparkKernel) : savedKernelInfo;
|
defaultKernel = !foundSavedKernelInSpecs ? specs.kernels.find((spec) => spec.name === notebookConstants.defaultSparkKernel) : foundSavedKernelInSpecs;
|
||||||
} else {
|
} else {
|
||||||
// Handle kernels
|
// Handle kernels
|
||||||
if (savedKernelInfo && savedKernelInfo.name.toLowerCase().indexOf('spark') > -1) {
|
if (savedKernelInfo && savedKernelInfo.name.toLowerCase().indexOf('spark') > -1) {
|
||||||
|
|||||||
@@ -391,7 +391,10 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
promptForPath(defaultPath: string): TPromise<string> {
|
promptForPath(defaultPath: string): TPromise<string> {
|
||||||
return this.windowService.showSaveDialog({ defaultPath });
|
return this.windowService.showSaveDialog({
|
||||||
|
defaultPath: defaultPath,
|
||||||
|
filters: [{ name: localize('notebookFile', 'Notebook'), extensions: ['ipynb']}]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point to save notebook
|
// Entry point to save notebook
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { Widget } from 'vs/base/browser/ui/widget';
|
|||||||
import { Sash, IHorizontalSashLayoutProvider, ISashEvent, Orientation } from 'vs/base/browser/ui/sash/sash';
|
import { Sash, IHorizontalSashLayoutProvider, ISashEvent, Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
import { IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
||||||
import { FIND_IDS, MATCHES_LIMIT, CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel';
|
import { FIND_IDS, CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel';
|
||||||
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
|
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
|
||||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { ITheme, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
|
import { ITheme, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
@@ -36,7 +36,7 @@ const NLS_FIND_INPUT_PLACEHOLDER = nls.localize('placeholder.find', "Find");
|
|||||||
const NLS_PREVIOUS_MATCH_BTN_LABEL = nls.localize('label.previousMatchButton', "Previous match");
|
const NLS_PREVIOUS_MATCH_BTN_LABEL = nls.localize('label.previousMatchButton', "Previous match");
|
||||||
const NLS_NEXT_MATCH_BTN_LABEL = nls.localize('label.nextMatchButton', "Next match");
|
const NLS_NEXT_MATCH_BTN_LABEL = nls.localize('label.nextMatchButton', "Next match");
|
||||||
const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close");
|
const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close");
|
||||||
const NLS_MATCHES_COUNT_LIMIT_TITLE = nls.localize('title.matchesCountLimit', "Only the first 999 results are highlighted, but all find operations work on the entire text.");
|
const NLS_MATCHES_COUNT_LIMIT_TITLE = nls.localize('title.matchesCountLimit', "Your search returned a large number of results, only the first 999 matches will be highlighted.");
|
||||||
const NLS_MATCHES_LOCATION = nls.localize('label.matchesLocation', "{0} of {1}");
|
const NLS_MATCHES_LOCATION = nls.localize('label.matchesLocation', "{0} of {1}");
|
||||||
const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");
|
const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");
|
||||||
|
|
||||||
@@ -46,6 +46,8 @@ const FIND_INPUT_AREA_WIDTH = PART_WIDTH - 54;
|
|||||||
|
|
||||||
let MAX_MATCHES_COUNT_WIDTH = 69;
|
let MAX_MATCHES_COUNT_WIDTH = 69;
|
||||||
|
|
||||||
|
export const PROFILER_MAX_MATCHES = 999;
|
||||||
|
|
||||||
export const ACTION_IDS = {
|
export const ACTION_IDS = {
|
||||||
FIND_NEXT: 'findNext',
|
FIND_NEXT: 'findNext',
|
||||||
FIND_PREVIOUS: 'findPrev'
|
FIND_PREVIOUS: 'findPrev'
|
||||||
@@ -86,6 +88,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
|
|||||||
|
|
||||||
private _resizeSash: Sash;
|
private _resizeSash: Sash;
|
||||||
|
|
||||||
|
private searchTimeoutHandle: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
tableController: ITableController,
|
tableController: ITableController,
|
||||||
state: FindReplaceState,
|
state: FindReplaceState,
|
||||||
@@ -213,7 +217,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
|
|||||||
|
|
||||||
private _updateMatchesCount(): void {
|
private _updateMatchesCount(): void {
|
||||||
this._matchesCount.style.minWidth = MAX_MATCHES_COUNT_WIDTH + 'px';
|
this._matchesCount.style.minWidth = MAX_MATCHES_COUNT_WIDTH + 'px';
|
||||||
if (this._state.matchesCount >= MATCHES_LIMIT) {
|
if (this._state.matchesCount >= PROFILER_MAX_MATCHES) {
|
||||||
this._matchesCount.title = NLS_MATCHES_COUNT_LIMIT_TITLE;
|
this._matchesCount.title = NLS_MATCHES_COUNT_LIMIT_TITLE;
|
||||||
} else {
|
} else {
|
||||||
this._matchesCount.title = '';
|
this._matchesCount.title = '';
|
||||||
@@ -227,8 +231,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
|
|||||||
let label: string;
|
let label: string;
|
||||||
if (this._state.matchesCount > 0) {
|
if (this._state.matchesCount > 0) {
|
||||||
let matchesCount: string = String(this._state.matchesCount);
|
let matchesCount: string = String(this._state.matchesCount);
|
||||||
if (this._state.matchesCount >= MATCHES_LIMIT) {
|
if (this._state.matchesCount >= PROFILER_MAX_MATCHES) {
|
||||||
matchesCount += '+';
|
matchesCount = PROFILER_MAX_MATCHES + '+';
|
||||||
}
|
}
|
||||||
let matchesPosition: string = String(this._state.matchesPosition);
|
let matchesPosition: string = String(this._state.matchesPosition);
|
||||||
if (matchesPosition === '0') {
|
if (matchesPosition === '0') {
|
||||||
@@ -401,7 +405,14 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
|
|||||||
this._findInput.setWholeWords(!!this._state.wholeWord);
|
this._findInput.setWholeWords(!!this._state.wholeWord);
|
||||||
this._register(this._findInput.onKeyDown((e) => this._onFindInputKeyDown(e)));
|
this._register(this._findInput.onKeyDown((e) => this._onFindInputKeyDown(e)));
|
||||||
this._register(this._findInput.onInput(() => {
|
this._register(this._findInput.onInput(() => {
|
||||||
this._state.change({ searchString: this._findInput.getValue() }, true);
|
let self = this;
|
||||||
|
if (self.searchTimeoutHandle) {
|
||||||
|
clearTimeout(self.searchTimeoutHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.searchTimeoutHandle = setTimeout(function () {
|
||||||
|
self._state.change({ searchString: self._findInput.getValue() }, true);
|
||||||
|
}, 300);
|
||||||
}));
|
}));
|
||||||
this._register(this._findInput.onDidOptionChange(() => {
|
this._register(this._findInput.onDidOptionChange(() => {
|
||||||
this._state.change({
|
this._state.change({
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
|||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Dimension } from 'vs/base/browser/dom';
|
import { Dimension } from 'vs/base/browser/dom';
|
||||||
import { textFormatter } from 'sql/parts/grid/services/sharedServices';
|
import { textFormatter } from 'sql/parts/grid/services/sharedServices';
|
||||||
|
import { PROFILER_MAX_MATCHES } from 'sql/parts/profiler/editor/controller/profilerFindWidget';
|
||||||
|
|
||||||
export interface ProfilerTableViewState {
|
export interface ProfilerTableViewState {
|
||||||
scrollTop: number;
|
scrollTop: number;
|
||||||
@@ -214,7 +215,7 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll
|
|||||||
if (e.searchString) {
|
if (e.searchString) {
|
||||||
if (this._input && this._input.data) {
|
if (this._input && this._input.data) {
|
||||||
if (this._findState.searchString) {
|
if (this._findState.searchString) {
|
||||||
this._input.data.find(this._findState.searchString).then(p => {
|
this._input.data.find(this._findState.searchString, PROFILER_MAX_MATCHES).then(p => {
|
||||||
if (p) {
|
if (p) {
|
||||||
this._profilerTable.setActiveCell(p.row, p.col);
|
this._profilerTable.setActiveCell(p.row, p.col);
|
||||||
this._updateFinderMatchState();
|
this._updateFinderMatchState();
|
||||||
|
|||||||
@@ -305,6 +305,11 @@ let registryProperties = {
|
|||||||
'description': localize('sql.saveAsCsv.encoding', '[Optional] File encoding used when saving results as CSV'),
|
'description': localize('sql.saveAsCsv.encoding', '[Optional] File encoding used when saving results as CSV'),
|
||||||
'default': 'utf-8'
|
'default': 'utf-8'
|
||||||
},
|
},
|
||||||
|
'sql.results.streaming': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'description': localize('sql.results.streaming', 'Enable results streaming; contains few minor visual issues'),
|
||||||
|
'default': true
|
||||||
|
},
|
||||||
'sql.copyIncludeHeaders': {
|
'sql.copyIncludeHeaders': {
|
||||||
'type': 'boolean',
|
'type': 'boolean',
|
||||||
'description': localize('sql.copyIncludeHeaders', '[Optional] Configuration options for copying results from the Results View'),
|
'description': localize('sql.copyIncludeHeaders', '[Optional] Configuration options for copying results from the Results View'),
|
||||||
|
|||||||
@@ -188,23 +188,24 @@ export class GridPanel extends ViewletPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
private onResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
||||||
this.addResultSet(resultSet);
|
if (this.configurationService.getValue<boolean>('sql.results.streaming')) {
|
||||||
|
this.addResultSet(resultSet);
|
||||||
|
|
||||||
this.tables.map(t => {
|
this.tables.map(t => {
|
||||||
t.state.canBeMaximized = this.tables.length > 1;
|
t.state.canBeMaximized = this.tables.length > 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.maximumBodySize = this.tables.reduce((p, c) => {
|
this.maximumBodySize = this.tables.reduce((p, c) => {
|
||||||
return p + c.maximumSize;
|
return p + c.maximumSize;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
if (this.state && this.state.scrollPosition) {
|
if (this.state && this.state.scrollPosition) {
|
||||||
this.splitView.setScrollPosition(this.state.scrollPosition);
|
this.splitView.setScrollPosition(this.state.scrollPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
private updateResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
||||||
|
|
||||||
let resultsToUpdate: sqlops.ResultSetSummary[];
|
let resultsToUpdate: sqlops.ResultSetSummary[];
|
||||||
if (!Array.isArray(resultSet)) {
|
if (!Array.isArray(resultSet)) {
|
||||||
resultsToUpdate = [resultSet];
|
resultsToUpdate = [resultSet];
|
||||||
@@ -212,21 +213,42 @@ export class GridPanel extends ViewletPanel {
|
|||||||
resultsToUpdate = resultSet;
|
resultsToUpdate = resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let set of resultsToUpdate) {
|
if (this.configurationService.getValue<boolean>('sql.results.streaming')) {
|
||||||
let table = this.tables.find(t => t.resultSet.batchId === set.batchId && t.resultSet.id === set.id);
|
for (let set of resultsToUpdate) {
|
||||||
if (table) {
|
let table = this.tables.find(t => t.resultSet.batchId === set.batchId && t.resultSet.id === set.id);
|
||||||
table.updateResult(set);
|
if (table) {
|
||||||
} else {
|
table.updateResult(set);
|
||||||
warn('Got result set update request for non-existant table');
|
} else {
|
||||||
|
warn('Got result set update request for non-existant table');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.maximumBodySize = this.tables.reduce((p, c) => {
|
this.maximumBodySize = this.tables.reduce((p, c) => {
|
||||||
return p + c.maximumSize;
|
return p + c.maximumSize;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
if (this.state && this.state.scrollPosition) {
|
if (this.state && this.state.scrollPosition) {
|
||||||
this.splitView.setScrollPosition(this.state.scrollPosition);
|
this.splitView.setScrollPosition(this.state.scrollPosition);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let change = false;
|
||||||
|
|
||||||
|
for (let set of resultsToUpdate) {
|
||||||
|
if (set.complete) {
|
||||||
|
this.addResultSet(resultSet);
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change) {
|
||||||
|
this.maximumBodySize = this.tables.reduce((p, c) => {
|
||||||
|
return p + c.maximumSize;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (this.state && this.state.scrollPosition) {
|
||||||
|
this.splitView.setScrollPosition(this.state.scrollPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user