mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -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 { CreateStepDialog } from './createStepDialog';
|
||||
import { PickScheduleDialog } from './pickScheduleDialog';
|
||||
import { CreateAlertDialog } from './createAlertDialog';
|
||||
|
||||
export class CreateJobDialog {
|
||||
|
||||
// TODO: localize
|
||||
// Top level
|
||||
//
|
||||
private readonly DialogTitle: string = 'New Job';
|
||||
private readonly OkButtonText: string = 'OK';
|
||||
private readonly CancelButtonText: string = 'Cancel';
|
||||
@@ -23,7 +23,6 @@ export class CreateJobDialog {
|
||||
private readonly NotificationsTabText: string = 'Notifications';
|
||||
|
||||
// General tab strings
|
||||
//
|
||||
private readonly NameTextBoxLabel: string = 'Name';
|
||||
private readonly OwnerTextBoxLabel: string = 'Owner';
|
||||
private readonly CategoryDropdownLabel: string = 'Category';
|
||||
@@ -43,7 +42,6 @@ export class CreateJobDialog {
|
||||
private readonly DeleteStepButtonString: string = 'Delete';
|
||||
|
||||
// Notifications tab strings
|
||||
//
|
||||
private readonly NotificationsTabTopLabelString: string = 'Actions to perform when the job completes';
|
||||
private readonly EmailCheckBoxString: string = 'Email';
|
||||
private readonly PagerCheckBoxString: string = 'Page';
|
||||
@@ -51,10 +49,14 @@ export class CreateJobDialog {
|
||||
private readonly DeleteJobCheckBoxString: string = 'Automatically delete job';
|
||||
|
||||
// Schedules tab strings
|
||||
private readonly SchedulesTopLabelString: string = 'Schedules list';
|
||||
private readonly PickScheduleButtonString: string = 'Pick Schedule';
|
||||
|
||||
// Alerts tab strings
|
||||
private readonly AlertsTopLabelString: string = 'Alerts list';
|
||||
private readonly NewAlertButtonString: string = 'New Alert';
|
||||
|
||||
// UI Components
|
||||
//
|
||||
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||
private generalTab: sqlops.window.modelviewdialog.DialogTab;
|
||||
private stepsTab: sqlops.window.modelviewdialog.DialogTab;
|
||||
@@ -63,7 +65,6 @@ export class CreateJobDialog {
|
||||
private notificationsTab: sqlops.window.modelviewdialog.DialogTab;
|
||||
|
||||
// General tab controls
|
||||
//
|
||||
private nameTextBox: sqlops.InputBoxComponent;
|
||||
private ownerTextBox: sqlops.InputBoxComponent;
|
||||
private categoryDropdown: sqlops.DropDownComponent;
|
||||
@@ -94,6 +95,10 @@ export class CreateJobDialog {
|
||||
private schedulesTable: sqlops.TableComponent;
|
||||
private pickScheduleButton: sqlops.ButtonComponent;
|
||||
|
||||
// Alert tab controls
|
||||
private alertsTable: sqlops.TableComponent;
|
||||
private newAlertButton: sqlops.ButtonComponent;
|
||||
|
||||
private model: CreateJobData;
|
||||
|
||||
constructor(ownerUri: string) {
|
||||
@@ -225,6 +230,38 @@ export class CreateJobDialog {
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -259,7 +296,7 @@ export class CreateJobDialog {
|
||||
let formModel = view.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
component: this.schedulesTable,
|
||||
title: this.JobStepsTopLabelString,
|
||||
title: this.SchedulesTopLabelString,
|
||||
actions: [this.pickScheduleButton]
|
||||
}]).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
|
||||
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||
private scheduleTab: sqlops.window.modelviewdialog.DialogTab;
|
||||
private schedulesTable: sqlops.TableComponent;
|
||||
|
||||
private model: PickScheduleData;
|
||||
@@ -34,7 +33,6 @@ export class PickScheduleDialog {
|
||||
public async showDialog() {
|
||||
await this.model.initialize();
|
||||
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
||||
this.scheduleTab = sqlops.window.modelviewdialog.createTab(this.SchedulesTabText);
|
||||
this.initializeContent();
|
||||
this.dialog.okButton.onClick(async () => await this.execute());
|
||||
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||
|
||||
@@ -6,12 +6,10 @@
|
||||
|
||||
import vscode = require('vscode');
|
||||
import { MainController } from './mainController';
|
||||
import { ApiWrapper } from './apiWrapper';
|
||||
export let controller: MainController;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
let apiWrapper = new ApiWrapper();
|
||||
controller = new MainController(context, apiWrapper);
|
||||
controller = new MainController(context);
|
||||
controller.activate();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import * as vscode from 'vscode';
|
||||
import { ApiWrapper } from './apiWrapper';
|
||||
import { CreateAlertDialog } from './dialogs/createAlertDialog';
|
||||
import { CreateJobDialog } from './dialogs/createJobDialog';
|
||||
import { CreateStepDialog } from './dialogs/createStepDialog';
|
||||
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
|
||||
@@ -13,21 +13,16 @@ import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
|
||||
* The main controller class that initializes the extension
|
||||
*/
|
||||
export class MainController {
|
||||
protected _apiWrapper: ApiWrapper;
|
||||
protected _context: vscode.ExtensionContext;
|
||||
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
public constructor(context: vscode.ExtensionContext, apiWrapper?: ApiWrapper) {
|
||||
this._apiWrapper = apiWrapper || new ApiWrapper();
|
||||
public constructor(context: vscode.ExtensionContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivates the extension
|
||||
* Activates the extension
|
||||
*/
|
||||
public deactivate(): void {
|
||||
}
|
||||
|
||||
public activate(): void {
|
||||
vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => {
|
||||
let dialog = new CreateJobDialog(ownerUri);
|
||||
@@ -41,9 +36,19 @@ export class MainController {
|
||||
let dialog = new PickScheduleDialog(ownerUri);
|
||||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user