mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Add Alert, Operator and Proxy panel tabs (#1811)
* Add Create Alert dialog * Add Job Alerts view * Stage WIP * Add Proxy View component * Hook up proxy and operator view callbacks * Style cleanup * Add additonal columns to views
This commit is contained in:
25
extensions/agent/client/src/data/createAlertData.ts
Normal file
25
extensions/agent/client/src/data/createAlertData.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import { AgentUtils } from '../agentUtils';
|
||||||
|
|
||||||
|
export class CreateAlertData {
|
||||||
|
public ownerUri: string;
|
||||||
|
private _alert: sqlops.AgentAlertInfo;
|
||||||
|
|
||||||
|
constructor(ownerUri:string) {
|
||||||
|
this.ownerUri = ownerUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async initialize() {
|
||||||
|
let agentService = await AgentUtils.getAgentService();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async save() {
|
||||||
|
}
|
||||||
|
}
|
||||||
29
extensions/agent/client/src/data/createScheduleData.ts
Normal file
29
extensions/agent/client/src/data/createScheduleData.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import { AgentUtils } from '../agentUtils';
|
||||||
|
|
||||||
|
export class CreateScheduleData {
|
||||||
|
public ownerUri: string;
|
||||||
|
public schedules: sqlops.AgentJobScheduleInfo[];
|
||||||
|
public selectedSchedule: sqlops.AgentJobScheduleInfo;
|
||||||
|
|
||||||
|
constructor(ownerUri:string) {
|
||||||
|
this.ownerUri = ownerUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async initialize() {
|
||||||
|
let agentService = await AgentUtils.getAgentService();
|
||||||
|
let result = await agentService.getJobSchedules(this.ownerUri);
|
||||||
|
if (result && result.success) {
|
||||||
|
this.schedules = result.schedules;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async save() {
|
||||||
|
}
|
||||||
|
}
|
||||||
149
extensions/agent/client/src/dialogs/createAlertDialog.ts
Normal file
149
extensions/agent/client/src/dialogs/createAlertDialog.ts
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { CreateAlertData } from '../data/createAlertData';
|
||||||
|
|
||||||
|
export class CreateAlertDialog {
|
||||||
|
|
||||||
|
// Top level
|
||||||
|
private readonly DialogTitle: string = 'Create Alert';
|
||||||
|
private readonly OkButtonText: string = 'OK';
|
||||||
|
private readonly CancelButtonText: string = 'Cancel';
|
||||||
|
private readonly GeneralTabText: string = 'Response';
|
||||||
|
private readonly ResponseTabText: string = 'Steps';
|
||||||
|
private readonly OptionsTabText: string = 'Options';
|
||||||
|
private readonly HistoryTabText: string = 'History';
|
||||||
|
|
||||||
|
// General tab strings
|
||||||
|
private readonly NameTextBoxLabel: string = 'Name';
|
||||||
|
|
||||||
|
// Response tab strings
|
||||||
|
private readonly ExecuteJobTextBoxLabel: string = 'Execute Job';
|
||||||
|
|
||||||
|
// Options tab strings
|
||||||
|
private readonly AdditionalMessageTextBoxLabel: string = 'Additional notification message to send';
|
||||||
|
|
||||||
|
// History tab strings
|
||||||
|
private readonly ResetCountTextBoxLabel: string = 'Reset Count';
|
||||||
|
|
||||||
|
// UI Components
|
||||||
|
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||||
|
private generalTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
|
private responseTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
|
private optionsTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
|
private historyTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
|
private schedulesTable: sqlops.TableComponent;
|
||||||
|
|
||||||
|
// General tab controls
|
||||||
|
private nameTextBox: sqlops.InputBoxComponent;
|
||||||
|
|
||||||
|
// Response tab controls
|
||||||
|
private executeJobTextBox: sqlops.InputBoxComponent;
|
||||||
|
|
||||||
|
// Options tab controls
|
||||||
|
private additionalMessageTextBox: sqlops.InputBoxComponent;
|
||||||
|
|
||||||
|
// History tab controls
|
||||||
|
private resetCountTextBox: sqlops.InputBoxComponent;
|
||||||
|
|
||||||
|
private model: CreateAlertData;
|
||||||
|
|
||||||
|
private _onSuccess: vscode.EventEmitter<CreateAlertData> = new vscode.EventEmitter<CreateAlertData>();
|
||||||
|
public readonly onSuccess: vscode.Event<CreateAlertData> = this._onSuccess.event;
|
||||||
|
|
||||||
|
constructor(ownerUri: string) {
|
||||||
|
this.model = new CreateAlertData(ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async showDialog() {
|
||||||
|
await this.model.initialize();
|
||||||
|
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
||||||
|
this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText);
|
||||||
|
this.responseTab = sqlops.window.modelviewdialog.createTab(this.ResponseTabText);
|
||||||
|
this.optionsTab = sqlops.window.modelviewdialog.createTab(this.OptionsTabText);
|
||||||
|
this.historyTab = sqlops.window.modelviewdialog.createTab(this.HistoryTabText);
|
||||||
|
|
||||||
|
this.initializeGeneralTab();
|
||||||
|
this.initializeResponseTab();
|
||||||
|
this.initializeOptionsTab();
|
||||||
|
this.initializeHistoryTab();
|
||||||
|
|
||||||
|
this.dialog.content = [this.generalTab, this.responseTab, this.optionsTab, this.historyTab];
|
||||||
|
this.dialog.okButton.onClick(async () => await this.execute());
|
||||||
|
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||||
|
this.dialog.okButton.label = this.OkButtonText;
|
||||||
|
this.dialog.cancelButton.label = this.CancelButtonText;
|
||||||
|
|
||||||
|
sqlops.window.modelviewdialog.openDialog(this.dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeGeneralTab() {
|
||||||
|
this.generalTab.registerContent(async view => {
|
||||||
|
this.nameTextBox = view.modelBuilder.inputBox().component();
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.nameTextBox,
|
||||||
|
title: this.NameTextBoxLabel
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeResponseTab() {
|
||||||
|
this.responseTab.registerContent(async view => {
|
||||||
|
this.executeJobTextBox = view.modelBuilder.inputBox().component();
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.executeJobTextBox,
|
||||||
|
title: this.ExecuteJobTextBoxLabel
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeOptionsTab() {
|
||||||
|
this.optionsTab.registerContent(async view => {
|
||||||
|
this.additionalMessageTextBox = view.modelBuilder.inputBox().component();
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.additionalMessageTextBox,
|
||||||
|
title: this.AdditionalMessageTextBoxLabel
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeHistoryTab() {
|
||||||
|
this.historyTab.registerContent(async view => {
|
||||||
|
this.resetCountTextBox = view.modelBuilder.inputBox().component();
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.resetCountTextBox,
|
||||||
|
title: this.ResetCountTextBoxLabel
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async execute() {
|
||||||
|
this.updateModel();
|
||||||
|
await this.model.save();
|
||||||
|
this._onSuccess.fire(this.model);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateModel() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,12 +7,12 @@ import * as sqlops from 'sqlops';
|
|||||||
import { CreateJobData } from '../data/createJobData';
|
import { CreateJobData } from '../data/createJobData';
|
||||||
import { CreateStepDialog } from './createStepDialog';
|
import { CreateStepDialog } from './createStepDialog';
|
||||||
import { PickScheduleDialog } from './pickScheduleDialog';
|
import { PickScheduleDialog } from './pickScheduleDialog';
|
||||||
|
import { CreateAlertDialog } from './createAlertDialog';
|
||||||
|
|
||||||
export class CreateJobDialog {
|
export class CreateJobDialog {
|
||||||
|
|
||||||
// TODO: localize
|
// TODO: localize
|
||||||
// Top level
|
// Top level
|
||||||
//
|
|
||||||
private readonly DialogTitle: string = 'New Job';
|
private readonly DialogTitle: string = 'New Job';
|
||||||
private readonly OkButtonText: string = 'OK';
|
private readonly OkButtonText: string = 'OK';
|
||||||
private readonly CancelButtonText: string = 'Cancel';
|
private readonly CancelButtonText: string = 'Cancel';
|
||||||
@@ -23,7 +23,6 @@ export class CreateJobDialog {
|
|||||||
private readonly NotificationsTabText: string = 'Notifications';
|
private readonly NotificationsTabText: string = 'Notifications';
|
||||||
|
|
||||||
// General tab strings
|
// General tab strings
|
||||||
//
|
|
||||||
private readonly NameTextBoxLabel: string = 'Name';
|
private readonly NameTextBoxLabel: string = 'Name';
|
||||||
private readonly OwnerTextBoxLabel: string = 'Owner';
|
private readonly OwnerTextBoxLabel: string = 'Owner';
|
||||||
private readonly CategoryDropdownLabel: string = 'Category';
|
private readonly CategoryDropdownLabel: string = 'Category';
|
||||||
@@ -43,7 +42,6 @@ export class CreateJobDialog {
|
|||||||
private readonly DeleteStepButtonString: string = 'Delete';
|
private readonly DeleteStepButtonString: string = 'Delete';
|
||||||
|
|
||||||
// Notifications tab strings
|
// Notifications tab strings
|
||||||
//
|
|
||||||
private readonly NotificationsTabTopLabelString: string = 'Actions to perform when the job completes';
|
private readonly NotificationsTabTopLabelString: string = 'Actions to perform when the job completes';
|
||||||
private readonly EmailCheckBoxString: string = 'Email';
|
private readonly EmailCheckBoxString: string = 'Email';
|
||||||
private readonly PagerCheckBoxString: string = 'Page';
|
private readonly PagerCheckBoxString: string = 'Page';
|
||||||
@@ -51,10 +49,14 @@ export class CreateJobDialog {
|
|||||||
private readonly DeleteJobCheckBoxString: string = 'Automatically delete job';
|
private readonly DeleteJobCheckBoxString: string = 'Automatically delete job';
|
||||||
|
|
||||||
// Schedules tab strings
|
// Schedules tab strings
|
||||||
|
private readonly SchedulesTopLabelString: string = 'Schedules list';
|
||||||
private readonly PickScheduleButtonString: string = 'Pick Schedule';
|
private readonly PickScheduleButtonString: string = 'Pick Schedule';
|
||||||
|
|
||||||
|
// Alerts tab strings
|
||||||
|
private readonly AlertsTopLabelString: string = 'Alerts list';
|
||||||
|
private readonly NewAlertButtonString: string = 'New Alert';
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
//
|
|
||||||
private dialog: sqlops.window.modelviewdialog.Dialog;
|
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||||
private generalTab: sqlops.window.modelviewdialog.DialogTab;
|
private generalTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
private stepsTab: sqlops.window.modelviewdialog.DialogTab;
|
private stepsTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
@@ -63,7 +65,6 @@ export class CreateJobDialog {
|
|||||||
private notificationsTab: sqlops.window.modelviewdialog.DialogTab;
|
private notificationsTab: sqlops.window.modelviewdialog.DialogTab;
|
||||||
|
|
||||||
// General tab controls
|
// General tab controls
|
||||||
//
|
|
||||||
private nameTextBox: sqlops.InputBoxComponent;
|
private nameTextBox: sqlops.InputBoxComponent;
|
||||||
private ownerTextBox: sqlops.InputBoxComponent;
|
private ownerTextBox: sqlops.InputBoxComponent;
|
||||||
private categoryDropdown: sqlops.DropDownComponent;
|
private categoryDropdown: sqlops.DropDownComponent;
|
||||||
@@ -94,6 +95,10 @@ export class CreateJobDialog {
|
|||||||
private schedulesTable: sqlops.TableComponent;
|
private schedulesTable: sqlops.TableComponent;
|
||||||
private pickScheduleButton: sqlops.ButtonComponent;
|
private pickScheduleButton: sqlops.ButtonComponent;
|
||||||
|
|
||||||
|
// Alert tab controls
|
||||||
|
private alertsTable: sqlops.TableComponent;
|
||||||
|
private newAlertButton: sqlops.ButtonComponent;
|
||||||
|
|
||||||
private model: CreateJobData;
|
private model: CreateJobData;
|
||||||
|
|
||||||
constructor(ownerUri: string) {
|
constructor(ownerUri: string) {
|
||||||
@@ -225,6 +230,38 @@ export class CreateJobDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private initializeAlertsTab() {
|
private initializeAlertsTab() {
|
||||||
|
this.alertsTab.registerContent(async view => {
|
||||||
|
this.alertsTable = view.modelBuilder.table()
|
||||||
|
.withProperties({
|
||||||
|
columns: [
|
||||||
|
'Alert Name'
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
height: 600,
|
||||||
|
width: 400
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.newAlertButton = view.modelBuilder.button().withProperties({
|
||||||
|
label: this.NewAlertButtonString,
|
||||||
|
width: 80
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.newAlertButton.onDidClick((e)=>{
|
||||||
|
let alertDialog = new CreateAlertDialog(this.model.ownerUri);
|
||||||
|
alertDialog.onSuccess((dialogModel) => {
|
||||||
|
});
|
||||||
|
alertDialog.showDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.alertsTable,
|
||||||
|
title: this.AlertsTopLabelString,
|
||||||
|
actions: [this.newAlertButton]
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private initializeSchedulesTab() {
|
private initializeSchedulesTab() {
|
||||||
@@ -259,7 +296,7 @@ export class CreateJobDialog {
|
|||||||
let formModel = view.modelBuilder.formContainer()
|
let formModel = view.modelBuilder.formContainer()
|
||||||
.withFormItems([{
|
.withFormItems([{
|
||||||
component: this.schedulesTable,
|
component: this.schedulesTable,
|
||||||
title: this.JobStepsTopLabelString,
|
title: this.SchedulesTopLabelString,
|
||||||
actions: [this.pickScheduleButton]
|
actions: [this.pickScheduleButton]
|
||||||
}]).withLayout({ width: '100%' }).component();
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
|||||||
91
extensions/agent/client/src/dialogs/createScheduleDialog.ts
Normal file
91
extensions/agent/client/src/dialogs/createScheduleDialog.ts
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { CreateScheduleData } from '../data/createScheduleData';
|
||||||
|
|
||||||
|
export class CreateScheduleDialog {
|
||||||
|
|
||||||
|
// Top level
|
||||||
|
private readonly DialogTitle: string = 'New Schedule';
|
||||||
|
private readonly OkButtonText: string = 'OK';
|
||||||
|
private readonly CancelButtonText: string = 'Cancel';
|
||||||
|
|
||||||
|
// UI Components
|
||||||
|
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||||
|
private schedulesTable: sqlops.TableComponent;
|
||||||
|
|
||||||
|
private model: CreateScheduleData;
|
||||||
|
|
||||||
|
private _onSuccess: vscode.EventEmitter<CreateScheduleData> = new vscode.EventEmitter<CreateScheduleData>();
|
||||||
|
public readonly onSuccess: vscode.Event<CreateScheduleData> = this._onSuccess.event;
|
||||||
|
|
||||||
|
constructor(ownerUri: string) {
|
||||||
|
this.model = new CreateScheduleData(ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async showDialog() {
|
||||||
|
await this.model.initialize();
|
||||||
|
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
||||||
|
this.initializeContent();
|
||||||
|
this.dialog.okButton.onClick(async () => await this.execute());
|
||||||
|
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||||
|
this.dialog.okButton.label = this.OkButtonText;
|
||||||
|
this.dialog.cancelButton.label = this.CancelButtonText;
|
||||||
|
|
||||||
|
sqlops.window.modelviewdialog.openDialog(this.dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeContent() {
|
||||||
|
this.dialog.registerContent(async view => {
|
||||||
|
this.schedulesTable = view.modelBuilder.table()
|
||||||
|
.withProperties({
|
||||||
|
columns: [
|
||||||
|
'Schedule Name'
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
height: 600,
|
||||||
|
width: 400
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
let formModel = view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([{
|
||||||
|
component: this.schedulesTable,
|
||||||
|
title: 'Schedules'
|
||||||
|
}]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
|
await view.initializeModel(formModel);
|
||||||
|
|
||||||
|
if (this.model.schedules) {
|
||||||
|
let data: any[][] = [];
|
||||||
|
for (let i = 0; i < this.model.schedules.length; ++i) {
|
||||||
|
let schedule = this.model.schedules[i];
|
||||||
|
data[i] = [ schedule.name ];
|
||||||
|
}
|
||||||
|
this.schedulesTable.data = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async execute() {
|
||||||
|
this.updateModel();
|
||||||
|
await this.model.save();
|
||||||
|
this._onSuccess.fire(this.model);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateModel() {
|
||||||
|
let selectedRows = this.schedulesTable.selectedRows;
|
||||||
|
if (selectedRows && selectedRows.length > 0) {
|
||||||
|
let selectedRow = selectedRows[0];
|
||||||
|
this.model.selectedSchedule = this.model.schedules[selectedRow];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ export class PickScheduleDialog {
|
|||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
private dialog: sqlops.window.modelviewdialog.Dialog;
|
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||||
private scheduleTab: sqlops.window.modelviewdialog.DialogTab;
|
|
||||||
private schedulesTable: sqlops.TableComponent;
|
private schedulesTable: sqlops.TableComponent;
|
||||||
|
|
||||||
private model: PickScheduleData;
|
private model: PickScheduleData;
|
||||||
@@ -34,7 +33,6 @@ export class PickScheduleDialog {
|
|||||||
public async showDialog() {
|
public async showDialog() {
|
||||||
await this.model.initialize();
|
await this.model.initialize();
|
||||||
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
||||||
this.scheduleTab = sqlops.window.modelviewdialog.createTab(this.SchedulesTabText);
|
|
||||||
this.initializeContent();
|
this.initializeContent();
|
||||||
this.dialog.okButton.onClick(async () => await this.execute());
|
this.dialog.okButton.onClick(async () => await this.execute());
|
||||||
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||||
|
|||||||
@@ -6,12 +6,10 @@
|
|||||||
|
|
||||||
import vscode = require('vscode');
|
import vscode = require('vscode');
|
||||||
import { MainController } from './mainController';
|
import { MainController } from './mainController';
|
||||||
import { ApiWrapper } from './apiWrapper';
|
|
||||||
export let controller: MainController;
|
export let controller: MainController;
|
||||||
|
|
||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
let apiWrapper = new ApiWrapper();
|
controller = new MainController(context);
|
||||||
controller = new MainController(context, apiWrapper);
|
|
||||||
controller.activate();
|
controller.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { ApiWrapper } from './apiWrapper';
|
import { CreateAlertDialog } from './dialogs/createAlertDialog';
|
||||||
import { CreateJobDialog } from './dialogs/createJobDialog';
|
import { CreateJobDialog } from './dialogs/createJobDialog';
|
||||||
import { CreateStepDialog } from './dialogs/createStepDialog';
|
import { CreateStepDialog } from './dialogs/createStepDialog';
|
||||||
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
|
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
|
||||||
@@ -13,21 +13,16 @@ import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
|
|||||||
* The main controller class that initializes the extension
|
* The main controller class that initializes the extension
|
||||||
*/
|
*/
|
||||||
export class MainController {
|
export class MainController {
|
||||||
protected _apiWrapper: ApiWrapper;
|
|
||||||
protected _context: vscode.ExtensionContext;
|
protected _context: vscode.ExtensionContext;
|
||||||
|
|
||||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
public constructor(context: vscode.ExtensionContext, apiWrapper?: ApiWrapper) {
|
public constructor(context: vscode.ExtensionContext) {
|
||||||
this._apiWrapper = apiWrapper || new ApiWrapper();
|
|
||||||
this._context = context;
|
this._context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivates the extension
|
* Activates the extension
|
||||||
*/
|
*/
|
||||||
public deactivate(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public activate(): void {
|
public activate(): void {
|
||||||
vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => {
|
vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => {
|
||||||
let dialog = new CreateJobDialog(ownerUri);
|
let dialog = new CreateJobDialog(ownerUri);
|
||||||
@@ -41,9 +36,19 @@ export class MainController {
|
|||||||
let dialog = new PickScheduleDialog(ownerUri);
|
let dialog = new PickScheduleDialog(ownerUri);
|
||||||
dialog.showDialog();
|
dialog.showDialog();
|
||||||
});
|
});
|
||||||
}
|
vscode.commands.registerCommand('agent.openCreateAlertDialog', (ownerUri: string) => {
|
||||||
|
let dialog = new CreateAlertDialog(ownerUri);
|
||||||
|
dialog.showDialog();
|
||||||
|
});
|
||||||
|
vscode.commands.registerCommand('agent.openCreateOperatorDialog', (ownerUri: string) => {
|
||||||
|
});
|
||||||
|
vscode.commands.registerCommand('agent.openCreateProxyDialog', (ownerUri: string) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private updateJobStepDialog() {
|
/**
|
||||||
|
* Deactivates the extension
|
||||||
}
|
*/
|
||||||
|
public deactivate(): void {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||||
"version": "1.5.0-alpha.1",
|
"version": "1.5.0-alpha.2",
|
||||||
"downloadFileNames": {
|
"downloadFileNames": {
|
||||||
"Windows_86": "win-x86-netcoreapp2.1.zip",
|
"Windows_86": "win-x86-netcoreapp2.1.zip",
|
||||||
"Windows_64": "win-x64-netcoreapp2.1.zip",
|
"Windows_64": "win-x64-netcoreapp2.1.zip",
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ export class AgentServicesFeature extends SqlOpsFeature<undefined> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let updateJobSchedule= (ownerUri: string, originalScheduleName: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.UpdateAgentJobScheduleResult> => {
|
let updateJobSchedule = (ownerUri: string, originalScheduleName: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.UpdateAgentJobScheduleResult> => {
|
||||||
let params: contracts.UpdateAgentJobScheduleParams = {
|
let params: contracts.UpdateAgentJobScheduleParams = {
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
originalScheduleName: originalScheduleName,
|
originalScheduleName: originalScheduleName,
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ import { ControlHostContent } from 'sql/parts/dashboard/contents/controlHostCont
|
|||||||
import { DashboardControlHostContainer } from 'sql/parts/dashboard/containers/dashboardControlHostContainer.component';
|
import { DashboardControlHostContainer } from 'sql/parts/dashboard/containers/dashboardControlHostContainer.component';
|
||||||
import { JobsViewComponent } from 'sql/parts/jobManagement/views/jobsView.component';
|
import { JobsViewComponent } from 'sql/parts/jobManagement/views/jobsView.component';
|
||||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||||
|
import { AlertsViewComponent } from 'sql/parts/jobManagement/views/alertsView.component';
|
||||||
import { JobHistoryComponent } from 'sql/parts/jobManagement/views/jobHistory.component';
|
import { JobHistoryComponent } from 'sql/parts/jobManagement/views/jobHistory.component';
|
||||||
|
import { OperatorsViewComponent } from 'sql/parts/jobManagement/views/operatorsView.component';
|
||||||
|
import { ProxiesViewComponent } from 'sql/parts/jobManagement/views/proxiesView.component';
|
||||||
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
|
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
|
||||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
|
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
|
||||||
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component';
|
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component';
|
||||||
@@ -59,9 +62,8 @@ import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox.component';
|
|||||||
let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer,
|
let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer,
|
||||||
DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent,
|
DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent,
|
||||||
ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer,
|
ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer,
|
||||||
JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, DashboardModelViewContainer, ModelComponentWrapper, Checkbox,
|
JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, AlertsViewComponent, ProxiesViewComponent, OperatorsViewComponent,
|
||||||
SelectBox,
|
DashboardModelViewContainer, ModelComponentWrapper, Checkbox, SelectBox, InputBox,];
|
||||||
InputBox,];
|
|
||||||
|
|
||||||
/* Panel */
|
/* Panel */
|
||||||
import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';
|
import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';
|
||||||
|
|||||||
@@ -4,17 +4,42 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
-->
|
-->
|
||||||
|
<div id="agentViewDiv" class="fullsize">
|
||||||
<panel class="dashboard-panel" [options]="panelOpt">
|
<panel class="dashboard-panel" [options]="panelOpt">
|
||||||
<tab [title]="jobsComponentTitle" class="fullsize" [identifier]="jobsTabIdentifier"
|
<tab [title]="jobsComponentTitle" class="fullsize" [identifier]="jobsTabIdentifier"
|
||||||
[iconClass]="jobsIconClass">
|
[iconClass]="jobsIconClass">
|
||||||
<ng-template>
|
<ng-template>
|
||||||
<div id="jobsDiv" class="fullsize" *ngIf="showHistory === false">
|
<div id="jobsDiv" class="fullsize" *ngIf="showHistory === false">
|
||||||
<jobsview-component></jobsview-component>
|
<jobsview-component></jobsview-component>
|
||||||
</div>
|
</div>
|
||||||
<div id="historyDiv" class="fullsize" *ngIf="showHistory === true">
|
<div id="historyDiv" class="fullsize" *ngIf="showHistory === true">
|
||||||
<jobhistory-component></jobhistory-component>
|
<jobhistory-component></jobhistory-component>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</tab>
|
</tab>
|
||||||
</panel>
|
<tab [title]="alertsComponentTitle" class="fullsize" [identifier]="alertsTabIdentifier"
|
||||||
|
[iconClass]="alertsIconClass">
|
||||||
|
<ng-template>
|
||||||
|
<div id="alertsDiv" class="fullsize">
|
||||||
|
<jobalertsview-component></jobalertsview-component>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</tab>
|
||||||
|
<tab [title]="operatorsComponentTitle" class="fullsize" [identifier]="operatorsTabIdentifier"
|
||||||
|
[iconClass]="operatorsIconClass">
|
||||||
|
<ng-template>
|
||||||
|
<div id="operatorsDiv" class="fullsize">
|
||||||
|
<joboperatorsview-component></joboperatorsview-component>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</tab>
|
||||||
|
<tab [title]="proxiesComponentTitle" class="fullsize" [identifier]="proxiesTabIdentifier"
|
||||||
|
[iconClass]="proxiesIconClass">
|
||||||
|
<ng-template>
|
||||||
|
<div id="proxiesDiv" class="fullsize">
|
||||||
|
<jobproxiesview-component></jobproxiesview-component>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</tab>
|
||||||
|
</panel>
|
||||||
|
</div>
|
||||||
@@ -33,6 +33,10 @@ export class AgentViewComponent {
|
|||||||
|
|
||||||
// tslint:disable:no-unused-variable
|
// tslint:disable:no-unused-variable
|
||||||
private readonly jobsComponentTitle: string = nls.localize('jobview.Jobs', "Jobs");
|
private readonly jobsComponentTitle: string = nls.localize('jobview.Jobs', "Jobs");
|
||||||
|
private readonly alertsComponentTitle: string = nls.localize('jobview.Alerts', "Alerts");
|
||||||
|
private readonly proxiesComponentTitle: string = nls.localize('jobview.Proxies', "Proxies");
|
||||||
|
private readonly operatorsComponentTitle: string = nls.localize('jobview.Operators', "Operators");
|
||||||
|
|
||||||
private _showHistory: boolean = false;
|
private _showHistory: boolean = false;
|
||||||
private _jobId: string = null;
|
private _jobId: string = null;
|
||||||
private _agentJobInfo: AgentJobInfo = null;
|
private _agentJobInfo: AgentJobInfo = null;
|
||||||
@@ -40,6 +44,9 @@ export class AgentViewComponent {
|
|||||||
private _expanded: Map<string, string>;
|
private _expanded: Map<string, string>;
|
||||||
|
|
||||||
public jobsIconClass: string = 'jobsview-icon';
|
public jobsIconClass: string = 'jobsview-icon';
|
||||||
|
public alertsIconClass: string = 'alertsview-icon';
|
||||||
|
public proxiesIconClass: string = 'proxiesview-icon';
|
||||||
|
public operatorsIconClass: string = 'operatorsview-icon';
|
||||||
|
|
||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
private readonly panelOpt: IPanelOptions = {
|
private readonly panelOpt: IPanelOptions = {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Table } from 'sql/base/browser/ui/table/table';
|
|
||||||
import { JobCacheObject } from './jobManagementService';
|
import { JobCacheObject } from './jobManagementService';
|
||||||
|
|
||||||
export const SERVICE_ID = 'jobManagementService';
|
export const SERVICE_ID = 'jobManagementService';
|
||||||
@@ -21,6 +20,12 @@ export interface IJobManagementService {
|
|||||||
|
|
||||||
getJobs(connectionUri: string): Thenable<sqlops.AgentJobsResult>;
|
getJobs(connectionUri: string): Thenable<sqlops.AgentJobsResult>;
|
||||||
|
|
||||||
|
getAlerts(connectionUri: string): Thenable<sqlops.AgentAlertsResult>;
|
||||||
|
|
||||||
|
getOperators(connectionUri: string): Thenable<sqlops.AgentOperatorsResult>;
|
||||||
|
|
||||||
|
getProxies(connectionUri: string): Thenable<sqlops.AgentProxiesResult>;
|
||||||
|
|
||||||
getJobHistory(connectionUri: string, jobID: string): Thenable<sqlops.AgentJobHistoryResult>;
|
getJobHistory(connectionUri: string, jobID: string): Thenable<sqlops.AgentJobHistoryResult>;
|
||||||
|
|
||||||
jobAction(connectionUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus>;
|
jobAction(connectionUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus>;
|
||||||
|
|||||||
@@ -29,6 +29,25 @@ export class JobManagementService implements IJobManagementService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAlerts(connectionUri: string): Thenable<sqlops.AgentAlertsResult> {
|
||||||
|
return this._runAction(connectionUri, (runner) => {
|
||||||
|
return runner.getAlerts(connectionUri);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOperators(connectionUri: string): Thenable<sqlops.AgentOperatorsResult> {
|
||||||
|
return this._runAction(connectionUri, (runner) => {
|
||||||
|
return runner.getOperators(connectionUri);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getProxies(connectionUri: string): Thenable<sqlops.AgentProxiesResult> {
|
||||||
|
return this._runAction(connectionUri, (runner) => {
|
||||||
|
return runner.getProxies(connectionUri);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public getJobHistory(connectionUri: string, jobID: string): Thenable<sqlops.AgentJobHistoryResult> {
|
public getJobHistory(connectionUri: string, jobID: string): Thenable<sqlops.AgentJobHistoryResult> {
|
||||||
return this._runAction(connectionUri, (runner) => {
|
return this._runAction(connectionUri, (runner) => {
|
||||||
return runner.getJobHistory(connectionUri, jobID);
|
return runner.getJobHistory(connectionUri, jobID);
|
||||||
|
|||||||
1
src/sql/parts/jobManagement/common/media/alert.svg
Normal file
1
src/sql/parts/jobManagement/common/media/alert.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}</style></defs><title>blocker</title><polygon class="cls-1" points="0.99 3.99 -0.01 3.99 -0.01 0.03 3.98 0.03 3.98 1.03 0.99 1.03 0.99 3.99"/><polygon class="cls-1" points="16.01 3.99 15.01 3.99 15.01 1.03 12.02 1.03 12.02 0.03 16.01 0.03 16.01 3.99"/><polygon class="cls-1" points="16.01 15.97 12.02 15.97 12.02 14.97 15.01 14.97 15.01 12.01 16.01 12.01 16.01 15.97"/><polygon class="cls-1" points="4 15.97 0.01 15.97 0.01 12.01 1.01 12.01 1.01 14.97 4 14.97 4 15.97"/><path class="cls-1" d="M8.41,3.18A4.82,4.82,0,1,0,13.23,8,4.83,4.83,0,0,0,8.41,3.18Zm0,.74A4.08,4.08,0,0,1,12.49,8a4,4,0,0,1-.85,2.47L5.69,5A4,4,0,0,1,8.41,3.93Zm0,8.15A4.08,4.08,0,0,1,4.34,8a4,4,0,0,1,.85-2.47L11.14,11A4,4,0,0,1,8.41,12.07Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 847 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>blocker_inverse</title><polygon class="cls-1" points="0.99 3.99 -0.01 3.99 -0.01 0.03 3.98 0.03 3.98 1.03 0.99 1.03 0.99 3.99"/><polygon class="cls-1" points="16.01 3.99 15.01 3.99 15.01 1.03 12.02 1.03 12.02 0.03 16.01 0.03 16.01 3.99"/><polygon class="cls-1" points="16.01 15.97 12.02 15.97 12.02 14.97 15.01 14.97 15.01 12.01 16.01 12.01 16.01 15.97"/><polygon class="cls-1" points="4 15.97 0.01 15.97 0.01 12.01 1.01 12.01 1.01 14.97 4 14.97 4 15.97"/><path class="cls-1" d="M8.41,3.18A4.82,4.82,0,1,0,13.23,8,4.83,4.83,0,0,0,8.41,3.18Zm0,.74A4.08,4.08,0,0,1,12.49,8a4,4,0,0,1-.85,2.47L5.69,5A4,4,0,0,1,8.41,3.93Zm0,8.15A4.08,4.08,0,0,1,4.34,8a4,4,0,0,1,.85-2.47L11.14,11A4,4,0,0,1,8.41,12.07Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 852 B |
@@ -31,7 +31,7 @@ jobhistory-component {
|
|||||||
border-bottom: 3px solid #444444;
|
border-bottom: 3px solid #444444;
|
||||||
}
|
}
|
||||||
|
|
||||||
#jobsDiv .jobview-grid {
|
.jobview-grid {
|
||||||
height: 94.7%;
|
height: 94.7%;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -49,6 +49,18 @@ jobhistory-component {
|
|||||||
font-size: larger;
|
font-size: larger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vs-dark #agentViewDiv .slick-header-column {
|
||||||
|
background: #333333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#agentViewDiv .slick-header-column {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background: white !important;
|
||||||
|
border: 0px !important;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
|
||||||
.vs-dark #jobsDiv jobsview-component .jobview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
|
.vs-dark #jobsDiv jobsview-component .jobview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
|
||||||
background:#333333;
|
background:#333333;
|
||||||
}
|
}
|
||||||
@@ -107,14 +119,14 @@ jobhistory-component {
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#jobsDiv .jobview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row .slick-cell.l1.r1.error-row {
|
.jobview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row .slick-cell.l1.r1.error-row {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: orangered;
|
color: orangered;
|
||||||
}
|
}
|
||||||
|
|
||||||
#jobsDiv .jobview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row .slick-cell._detail_selector.error-row {
|
.jobview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row .slick-cell._detail_selector.error-row {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +190,30 @@ jobhistory-component {
|
|||||||
background-image: url('./job_inverse.svg');
|
background-image: url('./job_inverse.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alertsview-icon {
|
||||||
|
background-image: url('./alert.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.vs-dark .alertsview-icon {
|
||||||
|
background-image: url('./alert_inverse.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.proxiesview-icon {
|
||||||
|
background-image: url('./proxy.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.vs-dark .proxiesview-icon {
|
||||||
|
background-image: url('./proxy_inverse.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.operatorsview-icon {
|
||||||
|
background-image: url('./operator.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.vs-dark .operatorsview-icon {
|
||||||
|
background-image: url('./operator_inverse.svg');
|
||||||
|
}
|
||||||
|
|
||||||
agentview-component .jobview-grid .grid-canvas > .ui-widget-content.slick-row.even > .slick-cell,
|
agentview-component .jobview-grid .grid-canvas > .ui-widget-content.slick-row.even > .slick-cell,
|
||||||
agentview-component .jobview-grid .grid-canvas > .ui-widget-content.slick-row.odd > .slick-cell {
|
agentview-component .jobview-grid .grid-canvas > .ui-widget-content.slick-row.odd > .slick-cell {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -259,4 +295,23 @@ table.jobprevruns > tbody {
|
|||||||
|
|
||||||
.jobs-view-toolbar span{
|
.jobs-view-toolbar span{
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#alertsDiv .jobalertsview-grid {
|
||||||
|
height: 94.7%;
|
||||||
|
width : 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#operatorsDiv .joboperatorsview-grid {
|
||||||
|
height: 94.7%;
|
||||||
|
width : 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#proxiesDiv .jobproxiesview-grid {
|
||||||
|
height: 94.7%;
|
||||||
|
width : 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|||||||
1
src/sql/parts/jobManagement/common/media/operator.svg
Normal file
1
src/sql/parts/jobManagement/common/media/operator.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>security</title><path d="M6,8a4.88,4.88,0,0,0-1.33.18,5.11,5.11,0,0,0-1.2.5,5,5,0,0,0-1.79,1.79,5.11,5.11,0,0,0-.5,1.2A4.88,4.88,0,0,0,1,13H0a5.9,5.9,0,0,1,.28-1.79,6.12,6.12,0,0,1,2-2.94,5.33,5.33,0,0,1,1.58-.88,4.18,4.18,0,0,1-.79-.65,4,4,0,0,1-.59-.8A4.05,4.05,0,0,1,2.13,5a4,4,0,0,1,.18-2.57A4,4,0,0,1,4.44.31a4,4,0,0,1,3.12,0A4,4,0,0,1,9.69,2.44,4,4,0,0,1,9.87,5a4.05,4.05,0,0,1-.37.93,4,4,0,0,1-.59.8,4.18,4.18,0,0,1-.79.65,6.14,6.14,0,0,1,1,.5,5.73,5.73,0,0,1,.91.69l-.68.74a5,5,0,0,0-1.57-1A4.93,4.93,0,0,0,6,8ZM3,4a2.92,2.92,0,0,0,.23,1.17,3,3,0,0,0,1.6,1.6,3,3,0,0,0,2.33,0,3,3,0,0,0,1.6-1.6,3,3,0,0,0,0-2.33,3,3,0,0,0-1.6-1.6,3,3,0,0,0-2.33,0,3,3,0,0,0-1.6,1.6A2.92,2.92,0,0,0,3,4Zm12,8a2.45,2.45,0,0,1,0,1l1,.4-.38.93-1-.41a2.59,2.59,0,0,1-.67.67l.41,1-.93.38L13,15a2.45,2.45,0,0,1-1,0l-.4,1-.93-.38.41-1a2.59,2.59,0,0,1-.67-.67l-1,.41-.38-.93,1-.4a2.45,2.45,0,0,1,0-1l-1-.4.38-.93,1,.41a2.59,2.59,0,0,1,.67-.67l-.41-1,.93-.38.4,1a2.45,2.45,0,0,1,1,0l.4-1,.93.38-.41,1a2.59,2.59,0,0,1,.67.67l1-.41.38.93ZM12.5,14a1.47,1.47,0,0,0,.59-.12,1.49,1.49,0,0,0,.8-.8,1.52,1.52,0,0,0,0-1.17,1.49,1.49,0,0,0-.8-.8,1.52,1.52,0,0,0-1.17,0,1.49,1.49,0,0,0-.8.8,1.52,1.52,0,0,0,0,1.17,1.49,1.49,0,0,0,.8.8A1.47,1.47,0,0,0,12.5,14Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>security_inverse</title><path class="cls-1" d="M6,8a4.88,4.88,0,0,0-1.33.18,5.11,5.11,0,0,0-1.2.5,5,5,0,0,0-1.79,1.79,5.11,5.11,0,0,0-.5,1.2A4.88,4.88,0,0,0,1,13H0a5.9,5.9,0,0,1,.28-1.79,6.12,6.12,0,0,1,2-2.94,5.33,5.33,0,0,1,1.58-.88,4.18,4.18,0,0,1-.79-.65,4,4,0,0,1-.59-.8A4.05,4.05,0,0,1,2.13,5a4,4,0,0,1,.18-2.57A4,4,0,0,1,4.44.31a4,4,0,0,1,3.12,0A4,4,0,0,1,9.69,2.44,4,4,0,0,1,9.87,5a4.05,4.05,0,0,1-.37.93,4,4,0,0,1-.59.8,4.18,4.18,0,0,1-.79.65,6.14,6.14,0,0,1,1,.5,5.73,5.73,0,0,1,.91.69l-.68.74a5,5,0,0,0-1.57-1A4.93,4.93,0,0,0,6,8ZM3,4a2.92,2.92,0,0,0,.23,1.17,3,3,0,0,0,1.6,1.6,3,3,0,0,0,2.33,0,3,3,0,0,0,1.6-1.6,3,3,0,0,0,0-2.33,3,3,0,0,0-1.6-1.6,3,3,0,0,0-2.33,0,3,3,0,0,0-1.6,1.6A2.92,2.92,0,0,0,3,4Zm12,8a2.45,2.45,0,0,1,0,1l1,.4-.38.93-1-.41a2.59,2.59,0,0,1-.67.67l.41,1-.93.38L13,15a2.45,2.45,0,0,1-1,0l-.4,1-.93-.38.41-1a2.59,2.59,0,0,1-.67-.67l-1,.41-.38-.93,1-.4a2.45,2.45,0,0,1,0-1l-1-.4.38-.93,1,.41a2.59,2.59,0,0,1,.67-.67l-.41-1,.93-.38.4,1a2.45,2.45,0,0,1,1,0l.4-1,.93.38-.41,1a2.59,2.59,0,0,1,.67.67l1-.41.38.93ZM12.5,14a1.47,1.47,0,0,0,.59-.12,1.49,1.49,0,0,0,.8-.8,1.52,1.52,0,0,0,0-1.17,1.49,1.49,0,0,0-.8-.8,1.52,1.52,0,0,0-1.17,0,1.49,1.49,0,0,0-.8.8,1.52,1.52,0,0,0,0,1.17,1.49,1.49,0,0,0,.8.8A1.47,1.47,0,0,0,12.5,14Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/sql/parts/jobManagement/common/media/proxy.svg
Normal file
1
src/sql/parts/jobManagement/common/media/proxy.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#101e23;}.cls-2{fill:#4bb8d1;}.cls-3{fill:#0c1011;}</style></defs><title>health</title><path class="cls-1" d="M12.58,1.51A6.36,6.36,0,0,0,8,3.9,6.32,6.32,0,0,0,3.41,1.51,3.81,3.81,0,0,0,0,5.35,5.7,5.7,0,0,0,.64,7.88h.72l0-.08A5.18,5.18,0,0,1,.64,5.39c.07-1.25.87-3.14,2.8-3.23h.12A5.81,5.81,0,0,1,7.73,4.63L8,5.06l.27-.43a5.72,5.72,0,0,1,4.28-2.47c1.93.09,2.73,2,2.8,3.23a5.15,5.15,0,0,1-.64,2.34l0,0a2.38,2.38,0,0,1-.34.68,19.45,19.45,0,0,1-6.57,6.06,11.11,11.11,0,0,1-1.25-.81c-.34-.25-.66-.52-1-.8h0a22.83,22.83,0,0,1-2.76-3H2a18.68,18.68,0,0,0,5.76,5.29h0l0,0h0c3.49-1.63,7-5.73,7.49-7.18V8A5.85,5.85,0,0,0,16,5.35,3.81,3.81,0,0,0,12.58,1.51Z"/><path class="cls-1" d="M1.41,8l-.1-.15h0Z"/><path class="cls-1" d="M7.79,15.22v0h0Z"/><path class="cls-1" d="M7.76,15.23h0v0Z"/><path class="cls-1" d="M14.72,7.73l0,0a.13.13,0,0,0,0,0Z"/><path class="cls-2" d="M12.62,8.7v.12a.48.48,0,0,1-.48.48H8.66l0,.07L7.38,12.65h0A.72.72,0,0,1,6,12.53V9.44H6V6.6L5,9.05H5a.56.56,0,0,1-.52.37H.92V8.36H4.13l0-.07L5.41,5h0a.72.72,0,0,1,1.42.12V8.22h0v2.84L7.77,8.6h0a.56.56,0,0,1,.52-.37h3.84A.48.48,0,0,1,12.62,8.7Z"/><path class="cls-3" d="M12.62,8.7v.12a.48.48,0,0,1-.48.48H8.66l0,.07L7.38,12.65h0A.72.72,0,0,1,6,12.53V9.44H6V6.6L5,9.05H5a.56.56,0,0,1-.52.37H.92V8.36H4.13l0-.07L5.41,5h0a.72.72,0,0,1,1.42.12V8.22h0v2.84L7.77,8.6h0a.56.56,0,0,1,.52-.37h3.84A.48.48,0,0,1,12.62,8.7Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#101e23;}.cls-3{fill:#4bb8d1;}</style></defs><title>health_inverse</title><path class="cls-1" d="M12.58,1.51A6.36,6.36,0,0,0,8,3.9,6.32,6.32,0,0,0,3.41,1.51,3.81,3.81,0,0,0,0,5.35,5.7,5.7,0,0,0,.64,7.88h.72l0-.08A5.18,5.18,0,0,1,.64,5.39c.07-1.25.87-3.14,2.8-3.23h.12A5.81,5.81,0,0,1,7.73,4.63L8,5.06l.27-.43a5.72,5.72,0,0,1,4.28-2.47c1.93.09,2.73,2,2.8,3.23a5.15,5.15,0,0,1-.64,2.34l0,0a2.38,2.38,0,0,1-.34.68,19.45,19.45,0,0,1-6.57,6.06,11.11,11.11,0,0,1-1.25-.81c-.34-.25-.66-.52-1-.8h0a22.83,22.83,0,0,1-2.76-3H2a18.68,18.68,0,0,0,5.76,5.29h0l0,0h0c3.49-1.63,7-5.73,7.49-7.18V8A5.85,5.85,0,0,0,16,5.35,3.81,3.81,0,0,0,12.58,1.51Z"/><path class="cls-2" d="M1.41,8l-.1-.15h0Z"/><path class="cls-2" d="M7.79,15.22v0h0Z"/><path class="cls-2" d="M7.76,15.23h0v0Z"/><path class="cls-2" d="M14.72,7.73l0,0a.13.13,0,0,0,0,0Z"/><path class="cls-3" d="M12.62,8.7v.12a.48.48,0,0,1-.48.48H8.66l0,.07L7.38,12.65h0A.72.72,0,0,1,6,12.53V9.44H6V6.6L5,9.05H5a.56.56,0,0,1-.52.37H.92V8.36H4.13l0-.07L5.41,5h0a.72.72,0,0,1,1.42.12V8.22h0v2.84L7.77,8.6h0a.56.56,0,0,1,.52-.37h3.84A.48.48,0,0,1,12.62,8.7Z"/><path class="cls-1" d="M12.62,8.7v.12a.48.48,0,0,1-.48.48H8.66l0,.07L7.38,12.65h0A.72.72,0,0,1,6,12.53V9.44H6V6.6L5,9.05H5a.56.56,0,0,1-.52.37H.92V8.36H4.13l0-.07L5.41,5h0a.72.72,0,0,1,1.42.12V8.22h0v2.84L7.77,8.6h0a.56.56,0,0,1,.52-.37h3.84A.48.48,0,0,1,12.62,8.7Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
17
src/sql/parts/jobManagement/views/alertsView.component.html
Normal file
17
src/sql/parts/jobManagement/views/alertsView.component.html
Normal 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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
-->
|
||||||
|
<div class="job-heading-container">
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === false">Alerts</h1>
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === true">No Alerts Available</h1>
|
||||||
|
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="jobs-view-toolbar">
|
||||||
|
<div (click)="refreshJobs()" tabindex="0"><div class="small icon refresh"></div><span>{{RefreshText}}</span></div>
|
||||||
|
<div (click)="openCreateJobDialog()" tabindex="0"><div class="small icon new"></div><span>{{NewAlertText}}</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div #jobalertsgrid class="jobview-grid"></div>
|
||||||
160
src/sql/parts/jobManagement/views/alertsView.component.ts
Normal file
160
src/sql/parts/jobManagement/views/alertsView.component.ts
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickColorTheme';
|
||||||
|
import 'vs/css!sql/parts/grid/media/flexbox';
|
||||||
|
import 'vs/css!sql/parts/grid/media/styles';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slick.grid';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickGrid';
|
||||||
|
import 'vs/css!../common/media/jobs';
|
||||||
|
import 'vs/css!sql/media/icons/common-icons';
|
||||||
|
import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||||
|
|
||||||
|
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, AfterContentChecked } from '@angular/core';
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
import { Table } from 'sql/base/browser/ui/table/table';
|
||||||
|
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||||
|
import * as dom from 'vs/base/browser/dom';
|
||||||
|
import { IJobManagementService } from '../common/interfaces';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
|
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||||
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
|
export const VIEW_SELECTOR: string = 'jobalertsview-component';
|
||||||
|
export const ROW_HEIGHT: number = 45;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: VIEW_SELECTOR,
|
||||||
|
templateUrl: decodeURI(require.toUrl('./alertsView.component.html')),
|
||||||
|
providers: [{ provide: TabChild, useExisting: forwardRef(() => AlertsViewComponent) }],
|
||||||
|
})
|
||||||
|
export class AlertsViewComponent implements AfterContentChecked {
|
||||||
|
|
||||||
|
private columns: Array<Slick.Column<any>> = [
|
||||||
|
{ name: nls.localize('jobAlertColumns.name', 'Name'), field: 'name', width: 200, id: 'name' },
|
||||||
|
{ name: nls.localize('jobAlertColumns.lastOccurrenceDate', 'Last Occurrence'), field: 'lastOccurrenceDate', width: 200, id: 'lastOccurrenceDate' },
|
||||||
|
{ name: nls.localize('jobAlertColumns.enabled', 'Enabled'), field: 'enabled', width: 200, id: 'enabled' },
|
||||||
|
{ name: nls.localize('jobAlertColumns.databaseName', 'Database Name'), field: 'databaseName', width: 200, id: 'databaseName' },
|
||||||
|
{ name: nls.localize('jobAlertColumns.categoryName', 'Category Name'), field: 'categoryName', width: 200, id: 'categoryName' },
|
||||||
|
];
|
||||||
|
|
||||||
|
private options: Slick.GridOptions<any> = {
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: 45,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
editable: false
|
||||||
|
};
|
||||||
|
|
||||||
|
private dataView: any;
|
||||||
|
|
||||||
|
@ViewChild('jobalertsgrid') _gridEl: ElementRef;
|
||||||
|
private isVisible: boolean = false;
|
||||||
|
private isInitialized: boolean = false;
|
||||||
|
private isRefreshing: boolean = false;
|
||||||
|
private _table: Table<any>;
|
||||||
|
public alerts: sqlops.AgentAlertInfo[];
|
||||||
|
private _serverName: string;
|
||||||
|
private _isCloud: boolean;
|
||||||
|
private _showProgressWheel: boolean;
|
||||||
|
|
||||||
|
private NewAlertText: string = nls.localize('jobAlertToolbar-NewJob', "New Alert");
|
||||||
|
private RefreshText: string = nls.localize('jobAlertToolbar-Refresh', "Refresh");
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(forwardRef(() => CommonServiceInterface)) private _dashboardService: CommonServiceInterface,
|
||||||
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
|
||||||
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||||
|
@Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent,
|
||||||
|
@Inject(IJobManagementService) private _jobManagementService: IJobManagementService,
|
||||||
|
@Inject(IThemeService) private _themeService: IThemeService,
|
||||||
|
@Inject(ICommandService) private _commandService: ICommandService
|
||||||
|
) {
|
||||||
|
this._isCloud = this._dashboardService.connectionManagementService.connectionInfo.serverInfo.isCloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public layout() {
|
||||||
|
this._table.layout(new dom.Dimension(dom.getContentWidth(this._gridEl.nativeElement), dom.getContentHeight(this._gridEl.nativeElement)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentChecked() {
|
||||||
|
if (this.isVisible === false && this._gridEl.nativeElement.offsetParent !== null) {
|
||||||
|
this.isVisible = true;
|
||||||
|
if (!this.isInitialized) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isInitialized = true;
|
||||||
|
}
|
||||||
|
} else if (this.isVisible === true && this._agentViewComponent.refresh === true) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isRefreshing = true;
|
||||||
|
this._agentViewComponent.refresh = false;
|
||||||
|
} else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFirstVisible(cached?: boolean) {
|
||||||
|
let self = this;
|
||||||
|
let columns = this.columns.map((column) => {
|
||||||
|
column.rerenderOnResize = true;
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
let options = <Slick.GridOptions<any>>{
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: ROW_HEIGHT,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
forceFitColumns: true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dataView = new Slick.Data.DataView();
|
||||||
|
|
||||||
|
$(this._gridEl.nativeElement).empty();
|
||||||
|
this._table = new Table(this._gridEl.nativeElement, undefined, columns, this.options);
|
||||||
|
this._table.grid.setData(this.dataView, true);
|
||||||
|
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._jobManagementService.getAlerts(ownerUri).then((result) => {
|
||||||
|
if (result && result.alerts) {
|
||||||
|
self.alerts = result.alerts;
|
||||||
|
self.onAlertsAvailable(result.alerts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onAlertsAvailable(alerts: sqlops.AgentAlertInfo[]) {
|
||||||
|
let items: any = alerts.map((item) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
lastOccurrenceDate: item.lastOccurrenceDate,
|
||||||
|
enabled: item.isEnabled,
|
||||||
|
databaseName: item.databaseName,
|
||||||
|
categoryName: item.categoryName
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dataView.beginUpdate();
|
||||||
|
this.dataView.setItems(items);
|
||||||
|
this.dataView.endUpdate();
|
||||||
|
this._table.autosizeColumns();
|
||||||
|
this._table.resizeCanvas();
|
||||||
|
|
||||||
|
this._showProgressWheel = false;
|
||||||
|
this._cd.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private openCreateJobDialog() {
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._commandService.executeCommand('agent.openCreateAlertDialog', ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private refreshJobs() {
|
||||||
|
this._agentViewComponent.refresh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@ export class JobsViewComponent implements AfterContentChecked {
|
|||||||
private filterValueMap: { [columnName: string]: string[]; } = {};
|
private filterValueMap: { [columnName: string]: string[]; } = {};
|
||||||
private sortingStylingMap: { [columnName: string]: any; } = {};
|
private sortingStylingMap: { [columnName: string]: any; } = {};
|
||||||
|
|
||||||
private NewJobText: string = nls.localize("jobsToolbar-NewJob", "New job");
|
private NewJobText: string = nls.localize("jobsToolbar-NewJob", "New Job");
|
||||||
private RefreshText: string = nls.localize("jobsToolbar-Refresh", "Refresh");
|
private RefreshText: string = nls.localize("jobsToolbar-Refresh", "Refresh");
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -145,13 +145,13 @@ export class JobsViewComponent implements AfterContentChecked {
|
|||||||
this.onFirstVisible(false);
|
this.onFirstVisible(false);
|
||||||
this.isRefreshing = true;
|
this.isRefreshing = true;
|
||||||
this._agentViewComponent.refresh = false;
|
this._agentViewComponent.refresh = false;
|
||||||
} else if (this.isVisible === true && this._agentViewComponent.refresh === false) {
|
} /*else if (this.isVisible === true && this._agentViewComponent.refresh === false) {
|
||||||
if (!this.isRefreshing) {
|
if (!this.isRefreshing) {
|
||||||
this._showProgressWheel = true;
|
this._showProgressWheel = true;
|
||||||
this.onFirstVisible(true);
|
this.onFirstVisible(true);
|
||||||
}
|
}
|
||||||
this.isRefreshing = false;
|
this.isRefreshing = false;
|
||||||
} else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
|
}*/ else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
|
||||||
this.isVisible = false;
|
this.isVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +346,11 @@ export class JobsViewComponent implements AfterContentChecked {
|
|||||||
currentTarget.title = currentTarget.innerText;
|
currentTarget.title = currentTarget.innerText;
|
||||||
});
|
});
|
||||||
this._showProgressWheel = false;
|
this._showProgressWheel = false;
|
||||||
this._cd.detectChanges();
|
|
||||||
|
if (this.isVisible) {
|
||||||
|
this._cd.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
$(window).resize(() => {
|
$(window).resize(() => {
|
||||||
let jobsViewToolbar = $('jobsview-component .jobs-view-toolbar').get(0);
|
let jobsViewToolbar = $('jobsview-component .jobs-view-toolbar').get(0);
|
||||||
@@ -827,7 +831,7 @@ export class JobsViewComponent implements AfterContentChecked {
|
|||||||
|
|
||||||
private openCreateJobDialog() {
|
private openCreateJobDialog() {
|
||||||
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
this._commandService.executeCommand("agent.openCreateJobDialog", ownerUri);
|
this._commandService.executeCommand('agent.openCreateJobDialog', ownerUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private refreshJobs() {
|
private refreshJobs() {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
-->
|
||||||
|
<div class="job-heading-container">
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === false">Operators</h1>
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === true">No Operators Available</h1>
|
||||||
|
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="jobs-view-toolbar">
|
||||||
|
<div (click)="refreshJobs()" tabindex="0"><div class="small icon refresh"></div><span>{{RefreshText}}</span></div>
|
||||||
|
<div (click)="openCreateOperatorDialog()" tabindex="0"><div class="small icon new"></div><span>{{NewOperatorText}}</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div #operatorsgrid class="joboperatorsview-grid"></div>
|
||||||
157
src/sql/parts/jobManagement/views/operatorsView.component.ts
Normal file
157
src/sql/parts/jobManagement/views/operatorsView.component.ts
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickColorTheme';
|
||||||
|
import 'vs/css!sql/parts/grid/media/flexbox';
|
||||||
|
import 'vs/css!sql/parts/grid/media/styles';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slick.grid';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickGrid';
|
||||||
|
import 'vs/css!../common/media/jobs';
|
||||||
|
import 'vs/css!sql/media/icons/common-icons';
|
||||||
|
import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||||
|
|
||||||
|
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, AfterContentChecked } from '@angular/core';
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
import { Table } from 'sql/base/browser/ui/table/table';
|
||||||
|
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||||
|
import * as dom from 'vs/base/browser/dom';
|
||||||
|
import { IJobManagementService } from '../common/interfaces';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
|
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||||
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
|
export const VIEW_SELECTOR: string = 'joboperatorsview-component';
|
||||||
|
export const ROW_HEIGHT: number = 45;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: VIEW_SELECTOR,
|
||||||
|
templateUrl: decodeURI(require.toUrl('./operatorsView.component.html')),
|
||||||
|
providers: [{ provide: TabChild, useExisting: forwardRef(() => OperatorsViewComponent) }],
|
||||||
|
})
|
||||||
|
|
||||||
|
export class OperatorsViewComponent implements AfterContentChecked {
|
||||||
|
|
||||||
|
private columns: Array<Slick.Column<any>> = [
|
||||||
|
{ name: nls.localize('jobOperatorsView.name', 'Name'), field: 'name', width: 200, id: 'name' },
|
||||||
|
{ name: nls.localize('jobOperatorsView.emailAddress', 'Email Address'), field: 'emailAddress', width: 200, id: 'emailAddress' },
|
||||||
|
{ name: nls.localize('jobOperatorsView.enabled', 'Enabled'), field: 'enabled', width: 200, id: 'enabled' },
|
||||||
|
];
|
||||||
|
|
||||||
|
private options: Slick.GridOptions<any> = {
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: 45,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
editable: false
|
||||||
|
};
|
||||||
|
|
||||||
|
private dataView: any;
|
||||||
|
|
||||||
|
@ViewChild('operatorsgrid') _gridEl: ElementRef;
|
||||||
|
private isVisible: boolean = false;
|
||||||
|
private isInitialized: boolean = false;
|
||||||
|
private isRefreshing: boolean = false;
|
||||||
|
private _table: Table<any>;
|
||||||
|
public operators: sqlops.AgentOperatorInfo[];
|
||||||
|
private _serverName: string;
|
||||||
|
private _isCloud: boolean;
|
||||||
|
private _showProgressWheel: boolean;
|
||||||
|
|
||||||
|
private NewOperatorText: string = nls.localize('jobOperatorToolbar-NewItem', "New Operator");
|
||||||
|
private RefreshText: string = nls.localize('jobOperatorToolbar-Refresh', "Refresh");
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(forwardRef(() => CommonServiceInterface)) private _dashboardService: CommonServiceInterface,
|
||||||
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
|
||||||
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||||
|
@Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent,
|
||||||
|
@Inject(IJobManagementService) private _jobManagementService: IJobManagementService,
|
||||||
|
@Inject(IThemeService) private _themeService: IThemeService,
|
||||||
|
@Inject(ICommandService) private _commandService: ICommandService
|
||||||
|
) {
|
||||||
|
this._isCloud = this._dashboardService.connectionManagementService.connectionInfo.serverInfo.isCloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public layout() {
|
||||||
|
this._table.layout(new dom.Dimension(dom.getContentWidth(this._gridEl.nativeElement), dom.getContentHeight(this._gridEl.nativeElement)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentChecked() {
|
||||||
|
if (this.isVisible === false && this._gridEl.nativeElement.offsetParent !== null) {
|
||||||
|
this.isVisible = true;
|
||||||
|
if (!this.isInitialized) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isInitialized = true;
|
||||||
|
}
|
||||||
|
} else if (this.isVisible === true && this._agentViewComponent.refresh === true) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isRefreshing = true;
|
||||||
|
this._agentViewComponent.refresh = false;
|
||||||
|
} else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFirstVisible(cached?: boolean) {
|
||||||
|
let self = this;
|
||||||
|
let columns = this.columns.map((column) => {
|
||||||
|
column.rerenderOnResize = true;
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
let options = <Slick.GridOptions<any>>{
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: ROW_HEIGHT,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
forceFitColumns: true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dataView = new Slick.Data.DataView();
|
||||||
|
|
||||||
|
$(this._gridEl.nativeElement).empty();
|
||||||
|
this._table = new Table(this._gridEl.nativeElement, undefined, columns, this.options);
|
||||||
|
this._table.grid.setData(this.dataView, true);
|
||||||
|
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._jobManagementService.getOperators(ownerUri).then((result) => {
|
||||||
|
if (result && result.operators) {
|
||||||
|
self.operators = result.operators;
|
||||||
|
self.onOperatorsAvailable(result.operators);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onOperatorsAvailable(operators: sqlops.AgentOperatorInfo[]) {
|
||||||
|
let items: any = operators.map((item) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
emailAddress: item.emailAddress,
|
||||||
|
enabled: item.enabled
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dataView.beginUpdate();
|
||||||
|
this.dataView.setItems(items);
|
||||||
|
this.dataView.endUpdate();
|
||||||
|
this._table.autosizeColumns();
|
||||||
|
this._table.resizeCanvas();
|
||||||
|
|
||||||
|
this._showProgressWheel = false;
|
||||||
|
this._cd.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private openCreateOperatorDialog() {
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._commandService.executeCommand('agent.openCreateOperatorDialog', ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private refreshJobs() {
|
||||||
|
this._agentViewComponent.refresh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/sql/parts/jobManagement/views/proxiesView.component.html
Normal file
17
src/sql/parts/jobManagement/views/proxiesView.component.html
Normal 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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
-->
|
||||||
|
<div class="job-heading-container">
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === false">Proxies</h1>
|
||||||
|
<h1 class="job-heading" *ngIf="_isCloud === true">No Proxies Available</h1>
|
||||||
|
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="jobs-view-toolbar">
|
||||||
|
<div (click)="refreshJobs()" tabindex="0"><div class="small icon refresh"></div><span>{{RefreshText}}</span></div>
|
||||||
|
<div (click)="openCreateProxyDialog()" tabindex="0"><div class="small icon new"></div><span>{{NewProxyText}}</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div #proxiesgrid class="jobproxiesview-grid"></div>
|
||||||
155
src/sql/parts/jobManagement/views/proxiesView.component.ts
Normal file
155
src/sql/parts/jobManagement/views/proxiesView.component.ts
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickColorTheme';
|
||||||
|
import 'vs/css!sql/parts/grid/media/flexbox';
|
||||||
|
import 'vs/css!sql/parts/grid/media/styles';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slick.grid';
|
||||||
|
import 'vs/css!sql/parts/grid/media/slickGrid';
|
||||||
|
import 'vs/css!../common/media/jobs';
|
||||||
|
import 'vs/css!sql/media/icons/common-icons';
|
||||||
|
import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||||
|
|
||||||
|
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, AfterContentChecked } from '@angular/core';
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
import { Table } from 'sql/base/browser/ui/table/table';
|
||||||
|
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||||
|
import * as dom from 'vs/base/browser/dom';
|
||||||
|
import { IJobManagementService } from '../common/interfaces';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
|
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||||
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
|
export const VIEW_SELECTOR: string = 'jobproxiesview-component';
|
||||||
|
export const ROW_HEIGHT: number = 45;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: VIEW_SELECTOR,
|
||||||
|
templateUrl: decodeURI(require.toUrl('./proxiesView.component.html')),
|
||||||
|
providers: [{ provide: TabChild, useExisting: forwardRef(() => ProxiesViewComponent) }],
|
||||||
|
})
|
||||||
|
|
||||||
|
export class ProxiesViewComponent implements AfterContentChecked {
|
||||||
|
|
||||||
|
private columns: Array<Slick.Column<any>> = [
|
||||||
|
{ name: nls.localize('jobProxiesView.accountName', 'Account Name'), field: 'accountName', width: 200, id: 'accountName' },
|
||||||
|
{ name: nls.localize('jobProxiesView.credentialName', 'Credential Name'), field: 'credentialName', width: 200, id: 'credentialName' },
|
||||||
|
];
|
||||||
|
|
||||||
|
private options: Slick.GridOptions<any> = {
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: 45,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
editable: false
|
||||||
|
};
|
||||||
|
|
||||||
|
private dataView: any;
|
||||||
|
|
||||||
|
@ViewChild('proxiesgrid') _gridEl: ElementRef;
|
||||||
|
private isVisible: boolean = false;
|
||||||
|
private isInitialized: boolean = false;
|
||||||
|
private isRefreshing: boolean = false;
|
||||||
|
private _table: Table<any>;
|
||||||
|
public proxies: sqlops.AgentProxyInfo[];
|
||||||
|
private _serverName: string;
|
||||||
|
private _isCloud: boolean;
|
||||||
|
private _showProgressWheel: boolean;
|
||||||
|
|
||||||
|
private NewProxyText: string = nls.localize('jobProxyToolbar-NewItem', "New Proxy");
|
||||||
|
private RefreshText: string = nls.localize('jobProxyToolbar-Refresh', "Refresh");
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(forwardRef(() => CommonServiceInterface)) private _dashboardService: CommonServiceInterface,
|
||||||
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
|
||||||
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||||
|
@Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent,
|
||||||
|
@Inject(IJobManagementService) private _jobManagementService: IJobManagementService,
|
||||||
|
@Inject(IThemeService) private _themeService: IThemeService,
|
||||||
|
@Inject(ICommandService) private _commandService: ICommandService
|
||||||
|
) {
|
||||||
|
this._isCloud = this._dashboardService.connectionManagementService.connectionInfo.serverInfo.isCloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public layout() {
|
||||||
|
this._table.layout(new dom.Dimension(dom.getContentWidth(this._gridEl.nativeElement), dom.getContentHeight(this._gridEl.nativeElement)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentChecked() {
|
||||||
|
if (this.isVisible === false && this._gridEl.nativeElement.offsetParent !== null) {
|
||||||
|
this.isVisible = true;
|
||||||
|
if (!this.isInitialized) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isInitialized = true;
|
||||||
|
}
|
||||||
|
} else if (this.isVisible === true && this._agentViewComponent.refresh === true) {
|
||||||
|
this._showProgressWheel = true;
|
||||||
|
this.onFirstVisible(false);
|
||||||
|
this.isRefreshing = true;
|
||||||
|
this._agentViewComponent.refresh = false;
|
||||||
|
} else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFirstVisible(cached?: boolean) {
|
||||||
|
let self = this;
|
||||||
|
let columns = this.columns.map((column) => {
|
||||||
|
column.rerenderOnResize = true;
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
let options = <Slick.GridOptions<any>>{
|
||||||
|
syncColumnCellResize: true,
|
||||||
|
enableColumnReorder: false,
|
||||||
|
rowHeight: ROW_HEIGHT,
|
||||||
|
enableCellNavigation: true,
|
||||||
|
forceFitColumns: true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dataView = new Slick.Data.DataView();
|
||||||
|
|
||||||
|
$(this._gridEl.nativeElement).empty();
|
||||||
|
this._table = new Table(this._gridEl.nativeElement, undefined, columns, this.options);
|
||||||
|
this._table.grid.setData(this.dataView, true);
|
||||||
|
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._jobManagementService.getProxies(ownerUri).then((result) => {
|
||||||
|
if (result && result.proxies) {
|
||||||
|
self.proxies = result.proxies;
|
||||||
|
self.onProxiesAvailable(result.proxies);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onProxiesAvailable(proxies: sqlops.AgentProxyInfo[]) {
|
||||||
|
let items: any = proxies.map((item) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
accountName: item.accountName,
|
||||||
|
credentialName: item.credentialName
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dataView.beginUpdate();
|
||||||
|
this.dataView.setItems(items);
|
||||||
|
this.dataView.endUpdate();
|
||||||
|
this._table.autosizeColumns();
|
||||||
|
this._table.resizeCanvas();
|
||||||
|
|
||||||
|
this._showProgressWheel = false;
|
||||||
|
this._cd.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private openCreateProxyDialog() {
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._commandService.executeCommand('agent.openCreateProxyDialog', ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private refreshJobs() {
|
||||||
|
this._agentViewComponent.refresh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/sql/sqlops.d.ts
vendored
7
src/sql/sqlops.d.ts
vendored
@@ -1211,6 +1211,7 @@ declare module 'sqlops' {
|
|||||||
|
|
||||||
export interface AgentAlertInfo {
|
export interface AgentAlertInfo {
|
||||||
id: number;
|
id: number;
|
||||||
|
name: string;
|
||||||
delayBetweenResponses: number;
|
delayBetweenResponses: number;
|
||||||
eventDescriptionKeyword: string;
|
eventDescriptionKeyword: string;
|
||||||
eventSource: string;
|
eventSource: string;
|
||||||
@@ -1327,15 +1328,15 @@ declare module 'sqlops' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentProxiesResult extends ResultStatus {
|
export interface AgentProxiesResult extends ResultStatus {
|
||||||
operators: AgentOperatorInfo[];
|
proxies: AgentProxyInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateAgentProxyResult extends ResultStatus {
|
export interface CreateAgentProxyResult extends ResultStatus {
|
||||||
operator: AgentOperatorInfo;
|
proxy: AgentProxyInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateAgentProxyResult extends ResultStatus {
|
export interface UpdateAgentProxyResult extends ResultStatus {
|
||||||
operator: AgentOperatorInfo;
|
proxy: AgentProxyInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentJobSchedulesResult extends ResultStatus {
|
export interface AgentJobSchedulesResult extends ResultStatus {
|
||||||
|
|||||||
@@ -554,4 +554,25 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape {
|
|||||||
public $jobAction(handle: number, ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {
|
public $jobAction(handle: number, ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {
|
||||||
return this._resolveProvider<sqlops.AgentServicesProvider>(handle).jobAction(ownerUri, jobName, action);
|
return this._resolveProvider<sqlops.AgentServicesProvider>(handle).jobAction(ownerUri, jobName, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Alerts list
|
||||||
|
*/
|
||||||
|
$getAlerts(handle: number, ownerUri: string): Thenable<sqlops.AgentAlertsResult> {
|
||||||
|
return this._resolveProvider<sqlops.AgentServicesProvider>(handle).getAlerts(ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Oeprators list
|
||||||
|
*/
|
||||||
|
$getOperators(handle: number, ownerUri: string): Thenable<sqlops.AgentOperatorsResult> {
|
||||||
|
return this._resolveProvider<sqlops.AgentServicesProvider>(handle).getOperators(ownerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Proxies list
|
||||||
|
*/
|
||||||
|
$getProxies(handle: number, ownerUri: string): Thenable<sqlops.AgentProxiesResult> {
|
||||||
|
return this._resolveProvider<sqlops.AgentServicesProvider>(handle).getProxies(ownerUri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,6 +344,15 @@ export class MainThreadDataProtocol implements MainThreadDataProtocolShape {
|
|||||||
},
|
},
|
||||||
jobAction(connectionUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {
|
jobAction(connectionUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {
|
||||||
return self._proxy.$jobAction(handle, connectionUri, jobName, action);
|
return self._proxy.$jobAction(handle, connectionUri, jobName, action);
|
||||||
|
},
|
||||||
|
getAlerts(connectionUri: string): Thenable<sqlops.AgentAlertsResult> {
|
||||||
|
return self._proxy.$getAlerts(handle, connectionUri);
|
||||||
|
},
|
||||||
|
getOperators(connectionUri: string): Thenable<sqlops.AgentOperatorsResult> {
|
||||||
|
return self._proxy.$getOperators(handle, connectionUri);
|
||||||
|
},
|
||||||
|
getProxies(connectionUri: string): Thenable<sqlops.AgentProxiesResult> {
|
||||||
|
return self._proxy.$getProxies(handle, connectionUri);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,21 @@ export abstract class ExtHostDataProtocolShape {
|
|||||||
* Run an action on a Job
|
* Run an action on a Job
|
||||||
*/
|
*/
|
||||||
$jobAction(handle: number, ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> { throw ni(); }
|
$jobAction(handle: number, ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> { throw ni(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Alerts list
|
||||||
|
*/
|
||||||
|
$getAlerts(handle: number, connectionUri: string): Thenable<sqlops.AgentAlertsResult> { throw ni(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Oeprators list
|
||||||
|
*/
|
||||||
|
$getOperators(handle: number, connectionUri: string): Thenable<sqlops.AgentOperatorsResult> { throw ni(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Agent Proxies list
|
||||||
|
*/
|
||||||
|
$getProxies(handle: number, connectionUri: string): Thenable<sqlops.AgentProxiesResult> { throw ni(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user