diff --git a/extensions/agent/client/src/data/createJobData.ts b/extensions/agent/client/src/data/createJobData.ts index 5d200fa348..f804a66f1a 100644 --- a/extensions/agent/client/src/data/createJobData.ts +++ b/extensions/agent/client/src/data/createJobData.ts @@ -6,7 +6,6 @@ import * as sqlops from 'sqlops'; import { AgentUtils } from '../agentUtils'; -import { runInThisContext } from 'vm'; export class CreateJobData { @@ -66,21 +65,16 @@ export class CreateJobData { public async initialize() { this._agentService = await AgentUtils.getAgentService(); + let jobDefaults = await this._agentService.getJobDefaults(this.ownerUri); + if (jobDefaults && jobDefaults.success) { + this._jobCategories = jobDefaults.categories.map((cat) => { + return cat.name; + }); - // TODO: fetch real data using agent service - // + this._defaultOwner = jobDefaults.owner; - this._jobCategories = [ - '[Uncategorized (Local)]', - 'Jobs from MSX' - ]; - - // await this._agentService.getOperators(this.ownerUri).then(result => { - // this._operators = result.operators.map(o => o.name); - // }); - - this._operators = ['', 'alanren']; - this._defaultOwner = 'REDMOND\\alanren'; + this._operators = ['', this._defaultOwner]; + } this._jobCompletionActionConditions = [{ displayName: this.JobCompletionActionCondition_OnSuccess, @@ -92,6 +86,8 @@ export class CreateJobData { displayName: this.JobCompletionActionCondition_Always, name: sqlops.JobCompletionActionCondition.Always.toString() }]; + + this.jobSchedules = []; } public async save() { @@ -140,8 +136,15 @@ export class CreateJobData { } return { - valid: validationErrors.length > 0, + valid: validationErrors.length === 0, errorMessages: validationErrors + }; + } + + public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) { + let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name); + if (!existingSchedule) { + this.jobSchedules.push(schedule); } } } \ No newline at end of file diff --git a/extensions/agent/client/src/data/pickScheduleData.ts b/extensions/agent/client/src/data/pickScheduleData.ts new file mode 100644 index 0000000000..9c4f45c55b --- /dev/null +++ b/extensions/agent/client/src/data/pickScheduleData.ts @@ -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 PickScheduleData { + 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() { + } +} diff --git a/extensions/agent/client/src/dialogs/createJobDialog.ts b/extensions/agent/client/src/dialogs/createJobDialog.ts index dc84092dad..c53de2c596 100644 --- a/extensions/agent/client/src/dialogs/createJobDialog.ts +++ b/extensions/agent/client/src/dialogs/createJobDialog.ts @@ -6,6 +6,7 @@ import * as sqlops from 'sqlops'; import { CreateJobData } from '../data/createJobData'; import { CreateStepDialog } from './createStepDialog'; +import { PickScheduleDialog } from './pickScheduleDialog'; export class CreateJobDialog { @@ -13,7 +14,7 @@ export class CreateJobDialog { // Top level // private readonly DialogTitle: string = 'New Job'; - private readonly OkButtonText: string = 'Ok'; + private readonly OkButtonText: string = 'OK'; private readonly CancelButtonText: string = 'Cancel'; private readonly GeneralTabText: string = 'General'; private readonly StepsTabText: string = 'Steps'; @@ -49,6 +50,9 @@ export class CreateJobDialog { private readonly EventLogCheckBoxString: string = 'Write to the Windows Application event log'; private readonly DeleteJobCheckBoxString: string = 'Automatically delete job'; + // Schedules tab strings + private readonly PickScheduleButtonString: string = 'Pick Schedule'; + // UI Components // private dialog: sqlops.window.modelviewdialog.Dialog; @@ -74,7 +78,6 @@ export class CreateJobDialog { private deleteStepButton: sqlops.ButtonComponent; // Notifications tab controls - // private notificationsTabTopLabel: sqlops.TextComponent; private emailCheckBox: sqlops.CheckBoxComponent; private emailOperatorDropdown: sqlops.DropDownComponent; @@ -87,6 +90,10 @@ export class CreateJobDialog { private deleteJobCheckBox: sqlops.CheckBoxComponent; private deleteJobConditionDropdown: sqlops.DropDownComponent; + // Schedule tab controls + private schedulesTable: sqlops.TableComponent; + private pickScheduleButton: sqlops.ButtonComponent; + private model: CreateJobData; constructor(ownerUri: string) { @@ -221,6 +228,56 @@ export class CreateJobDialog { } private initializeSchedulesTab() { + this.schedulesTab.registerContent(async view => { + this.schedulesTable = view.modelBuilder.table() + .withProperties({ + columns: [ + 'Schedule Name' + ], + data: [], + height: 600, + width: 400 + }).component(); + + this.pickScheduleButton = view.modelBuilder.button().withProperties({ + label: this.PickScheduleButtonString, + width: 80 + }).component(); + + this.pickScheduleButton.onDidClick((e)=>{ + let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri); + pickScheduleDialog.onSuccess((dialogModel) => { + let selectedSchedule = dialogModel.selectedSchedule; + if (selectedSchedule) { + this.model.addJobSchedule(selectedSchedule); + this.populateScheduleTable(); + } + }); + pickScheduleDialog.showDialog(); + }); + + let formModel = view.modelBuilder.formContainer() + .withFormItems([{ + component: this.schedulesTable, + title: this.JobStepsTopLabelString, + actions: [this.pickScheduleButton] + }]).withLayout({ width: '100%' }).component(); + + await view.initializeModel(formModel); + + this.populateScheduleTable(); + }); + } + + private populateScheduleTable() { + if (this.model.jobSchedules) { + let data: any[][] = []; + for (let i = 0; i < this.model.jobSchedules.length; ++i) { + let schedule = this.model.jobSchedules[i]; + data[i] = [ schedule.name ]; + } + this.schedulesTable.data = data; + } } private initializeNotificationsTab() { diff --git a/extensions/agent/client/src/dialogs/pickScheduleDialog.ts b/extensions/agent/client/src/dialogs/pickScheduleDialog.ts new file mode 100644 index 0000000000..c070ea9153 --- /dev/null +++ b/extensions/agent/client/src/dialogs/pickScheduleDialog.ts @@ -0,0 +1,94 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { PickScheduleData } from '../data/pickScheduleData'; + +export class PickScheduleDialog { + + // TODO: localize + // Top level + private readonly DialogTitle: string = 'Job Schedules'; + private readonly OkButtonText: string = 'OK'; + private readonly CancelButtonText: string = 'Cancel'; + private readonly SchedulesTabText: string = 'Schedules'; + + // UI Components + private dialog: sqlops.window.modelviewdialog.Dialog; + private scheduleTab: sqlops.window.modelviewdialog.DialogTab; + private schedulesTable: sqlops.TableComponent; + + private model: PickScheduleData; + + private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); + public readonly onSuccess: vscode.Event = this._onSuccess.event; + + constructor(ownerUri: string) { + this.model = new PickScheduleData(ownerUri); + } + + 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()); + 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]; + } + } +} \ No newline at end of file diff --git a/extensions/agent/client/src/mainController.ts b/extensions/agent/client/src/mainController.ts index 2e91d7c835..6009c2cb8e 100644 --- a/extensions/agent/client/src/mainController.ts +++ b/extensions/agent/client/src/mainController.ts @@ -7,6 +7,7 @@ import * as vscode from 'vscode'; import { ApiWrapper } from './apiWrapper'; import { CreateJobDialog } from './dialogs/createJobDialog'; import { CreateStepDialog } from './dialogs/createStepDialog'; +import { PickScheduleDialog } from './dialogs/pickScheduleDialog'; /** * The main controller class that initializes the extension @@ -19,8 +20,6 @@ export class MainController { public constructor(context: vscode.ExtensionContext, apiWrapper?: ApiWrapper) { this._apiWrapper = apiWrapper || new ApiWrapper(); this._context = context; - - console.log('Got: ' + apiWrapper); } /** @@ -30,10 +29,6 @@ export class MainController { } public activate(): void { - this._apiWrapper.registerWebviewProvider('data-management-agent', webview => { - webview.html = '

SQL Agent

'; - }); - vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => { let dialog = new CreateJobDialog(ownerUri); dialog.showDialog(); @@ -41,7 +36,11 @@ export class MainController { vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, jobId: string, server: string, stepId: number) => { let dialog = new CreateStepDialog(ownerUri, jobId, server, stepId); dialog.openNewStepDialog(); - }); + }); + vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string) => { + let dialog = new PickScheduleDialog(ownerUri); + dialog.showDialog(); + }); } private updateJobStepDialog() { diff --git a/extensions/mssql/src/contracts.ts b/extensions/mssql/src/contracts.ts index de9f5cc9b7..1fd0fa1a2a 100644 --- a/extensions/mssql/src/contracts.ts +++ b/extensions/mssql/src/contracts.ts @@ -64,6 +64,10 @@ export interface DeleteAgentJobParams { job: sqlops.AgentJobInfo; } +export interface AgentJobDefaultsParams { + ownerUri: string; +} + // Job Step management parameters export interface CreateAgentJobStepParams { ownerUri: string; @@ -144,6 +148,27 @@ export interface DeleteAgentProxyParams { proxy: sqlops.AgentProxyInfo; } +// Job Schedule management parameters +export interface AgentJobScheduleParams { + ownerUri: string; +} + +export interface CreateAgentJobScheduleParams { + ownerUri: string; + schedule: sqlops.AgentJobScheduleInfo; +} + +export interface UpdateAgentJobScheduleParams { + ownerUri: string; + originalScheduleName: string; + schedule: sqlops.AgentJobScheduleInfo; +} + +export interface DeleteAgentJobScheduleParams { + ownerUri: string; + schedule: sqlops.AgentJobScheduleInfo; +} + // Agent Job management requests export namespace AgentJobsRequest { export const type = new RequestType('agent/jobs'); @@ -169,6 +194,10 @@ export namespace DeleteAgentJobRequest { export const type = new RequestType('agent/deletejob'); } +export namespace AgentJobDefaultsRequest { + export const type = new RequestType('agent/jobdefaults'); +} + // Job Step requests export namespace CreateAgentJobStepRequest { export const type = new RequestType('agent/createjobstep'); @@ -233,4 +262,21 @@ export namespace DeleteAgentProxyRequest { export const type = new RequestType('agent/deleteproxy'); } +// Job Schedules requests +export namespace AgentJobSchedulesRequest { + export const type = new RequestType('agent/schedules'); +} + +export namespace CreateAgentJobScheduleRequest { + export const type = new RequestType('agent/createschedule'); +} + +export namespace UpdateAgentJobScheduleRequest { + export const type = new RequestType('agent/updateschedule'); +} + +export namespace DeleteAgentJobScheduleRequest { + export const type = new RequestType('agent/deleteschedule'); +} + // ------------------------------- < Agent Management > ------------------------------------ diff --git a/extensions/mssql/src/features.ts b/extensions/mssql/src/features.ts index 6039f44e2d..aa166b9781 100644 --- a/extensions/mssql/src/features.ts +++ b/extensions/mssql/src/features.ts @@ -135,6 +135,20 @@ export class AgentServicesFeature extends SqlOpsFeature { ); }; + let getJobDefaults = (ownerUri: string): Thenable => { + let params: contracts.AgentJobDefaultsParams = { + ownerUri: ownerUri + }; + let requestType = contracts.AgentJobDefaultsRequest.type; + return client.sendRequest(requestType, params).then( + r => r, + e => { + client.logFailedRequest(requestType, e); + return Promise.resolve(undefined); + } + ); + }; + // Job Step management methods let createJobStep = (ownerUri: string, stepInfo: sqlops.AgentJobStepInfo): Thenable => { let params: contracts.CreateAgentJobStepParams = { @@ -365,6 +379,67 @@ export class AgentServicesFeature extends SqlOpsFeature { ); }; + // Job Schedule management methods + let getJobSchedules = (ownerUri: string): Thenable => { + let params: contracts.AgentJobScheduleParams = { + ownerUri: ownerUri + }; + let requestType = contracts.AgentJobSchedulesRequest.type; + return client.sendRequest(requestType, params).then( + r => r, + e => { + client.logFailedRequest(requestType, e); + return Promise.resolve(undefined); + } + ); + }; + + let createJobSchedule = (ownerUri: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable => { + let params: contracts.CreateAgentJobScheduleParams = { + ownerUri: ownerUri, + schedule: scheduleInfo + }; + let requestType = contracts.CreateAgentJobScheduleRequest.type; + return client.sendRequest(requestType, params).then( + r => r, + e => { + client.logFailedRequest(requestType, e); + return Promise.resolve(undefined); + } + ); + }; + + let updateJobSchedule= (ownerUri: string, originalScheduleName: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable => { + let params: contracts.UpdateAgentJobScheduleParams = { + ownerUri: ownerUri, + originalScheduleName: originalScheduleName, + schedule: scheduleInfo + }; + let requestType = contracts.UpdateAgentJobScheduleRequest.type; + return client.sendRequest(requestType, params).then( + r => r, + e => { + client.logFailedRequest(requestType, e); + return Promise.resolve(undefined); + } + ); + }; + + let deleteJobSchedule = (ownerUri: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable => { + let params: contracts.DeleteAgentJobScheduleParams = { + ownerUri: ownerUri, + schedule: scheduleInfo + }; + let requestType = contracts.DeleteAgentJobScheduleRequest.type; + return client.sendRequest(requestType, params).then( + r => r, + e => { + client.logFailedRequest(requestType, e); + return Promise.resolve(undefined); + } + ); + }; + return sqlops.dataprotocol.registerAgentServicesProvider({ providerId: client.providerId, getJobs, @@ -373,6 +448,7 @@ export class AgentServicesFeature extends SqlOpsFeature { createJob, updateJob, deleteJob, + getJobDefaults, createJobStep, updateJobStep, deleteJobStep, @@ -387,7 +463,11 @@ export class AgentServicesFeature extends SqlOpsFeature { getProxies, createProxy, updateProxy, - deleteProxy + deleteProxy, + getJobSchedules, + createJobSchedule, + updateJobSchedule, + deleteJobSchedule }); } } diff --git a/extensions/mssql/yarn.lock b/extensions/mssql/yarn.lock index 1de7af00d8..6d444b3365 100644 --- a/extensions/mssql/yarn.lock +++ b/extensions/mssql/yarn.lock @@ -49,8 +49,9 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -"dataprotocol-client@file:../../../sqlops-dataprotocolclient": - version "0.1.7" +"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.1.9": + version "0.1.9" + resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/a1a79895cb79658b75d78aa5cfd745855019148d" dependencies: vscode-languageclient "3.5.0" diff --git a/src/sql/sqlops.d.ts b/src/sql/sqlops.d.ts index 5813f096a4..e1fa291f33 100644 --- a/src/sql/sqlops.d.ts +++ b/src/sql/sqlops.d.ts @@ -1060,13 +1060,40 @@ declare module 'sqlops' { wmiEvent = 4 } - export enum JobCompletionActionCondition{ + export enum JobCompletionActionCondition { Never = 0, OnSuccess = 1, OnFailure = 2, Always = 3 } + export enum FrequencyTypes { + Unknown , + OneTime = 1 << 1, + Daily = 1 << 2, + Weekly = 1 << 3, + Monthly = 1 << 4, + MonthlyRelative = 1 << 5, + AutoStart = 1 << 6, + OnIdle = 1 << 7 + } + + export enum FrequencySubDayTypes { + Unknown = 0, + Once = 1, + Second = 2, + Minute = 4, + Hour = 8 + } + + export enum FrequencyRelativeIntervals { + First = 1, + Second = 2, + Third = 4, + Fourth = 8, + Last = 16 + } + export interface AgentJobInfo { name: string; owner: string; @@ -1097,7 +1124,23 @@ declare module 'sqlops' { } export interface AgentJobScheduleInfo { - + id: number; + name: string; + jobName: string; + isEnabled: boolean; + frequencyTypes: FrequencyTypes; + frequencySubDayTypes: FrequencySubDayTypes; + frequencySubDayInterval: number; + frequencyRelativeIntervals; FrequencyRelativeIntervals; + frequencyRecurrenceFactor: number; + frequencyInterval: number; + dateCreated: string; + activeStartTimeOfDay: string; + activeStartDate: string; + activeEndTimeOfDay: string; + jobCount: number; + activeEndDate: string; + scheduleUid: string; } export interface AgentJobStep { @@ -1232,6 +1275,17 @@ declare module 'sqlops' { job: AgentJobInfo; } + export interface AgentJobCategory + { + id: string; + name: string; + } + + export interface AgentJobDefaultsResult extends ResultStatus { + owner: string; + categories: AgentJobCategory[]; + } + export interface CreateAgentJobStepResult extends ResultStatus { step: AgentJobStepInfo; } @@ -1284,6 +1338,18 @@ declare module 'sqlops' { operator: AgentOperatorInfo; } + export interface AgentJobSchedulesResult extends ResultStatus { + schedules: AgentJobScheduleInfo[]; + } + + export interface CreateAgentJobScheduleResult extends ResultStatus { + schedule: AgentJobScheduleInfo; + } + + export interface UpdateAgentJobScheduleResult extends ResultStatus { + schedule: AgentJobScheduleInfo; + } + export interface AgentServicesProvider extends DataProvider { // Job management methods getJobs(ownerUri: string): Thenable; @@ -1292,6 +1358,7 @@ declare module 'sqlops' { createJob(ownerUri: string, jobInfo: AgentJobInfo): Thenable; updateJob(ownerUri: string, originalJobName: string, jobInfo: AgentJobInfo): Thenable; deleteJob(ownerUri: string, jobInfo: AgentJobInfo): Thenable; + getJobDefaults(ownerUri: string): Thenable; // Job Step management methods createJobStep(ownerUri: string, jobInfo: AgentJobStepInfo): Thenable; @@ -1315,6 +1382,13 @@ declare module 'sqlops' { createProxy(ownerUri: string, proxyInfo: AgentProxyInfo): Thenable; updateProxy(ownerUri: string, originalProxyName: string, proxyInfo: AgentProxyInfo): Thenable; deleteProxy(ownerUri: string, proxyInfo: AgentProxyInfo): Thenable; + + + // Job Schedule management methods + getJobSchedules(ownerUri: string): Thenable; + createJobSchedule(ownerUri: string, scheduleInfo: AgentJobScheduleInfo): Thenable; + updateJobSchedule(ownerUri: string, originalScheduleName: string, scheduleInfo: AgentJobScheduleInfo): Thenable; + deleteJobSchedule(ownerUri: string, scheduleInfo: AgentJobScheduleInfo): Thenable; } // Task service interfaces ---------------------------------------------------------------------------- diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index 4a405c69f1..30efdc1e93 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -63,8 +63,7 @@ export enum ScriptOperation { Alter = 6 } -export enum WeekDays -{ +export enum WeekDays { sunday = 1, monday = 2, tuesday = 4, @@ -77,8 +76,7 @@ export enum WeekDays everyDay = 127 } -export enum NotifyMethods -{ +export enum NotifyMethods { none = 0, notifyEmail = 1, pager = 2, @@ -86,21 +84,47 @@ export enum NotifyMethods notifyAll = 7 } -export enum JobCompletionActionCondition{ +export enum JobCompletionActionCondition { Never = 0, OnSuccess = 1, OnFailure = 2, Always = 3 } -export enum AlertType -{ +export enum AlertType { sqlServerEvent = 1, sqlServerPerformanceCondition = 2, nonSqlServerEvent = 3, wmiEvent = 4 } +export enum FrequencyTypes { + Unknown , + OneTime = 1 << 1, + Daily = 1 << 2, + Weekly = 1 << 3, + Monthly = 1 << 4, + MonthlyRelative = 1 << 5, + AutoStart = 1 << 6, + OnIdle = 1 << 7 +} + +export enum FrequencySubDayTypes { + Unknown = 0, + Once = 1, + Second = 2, + Minute = 4, + Hour = 8 +} + +export enum FrequencyRelativeIntervals { + First = 1, + Second = 2, + Third = 4, + Fourth = 8, + Last = 16 +} + export enum ModelComponentTypes { NavContainer, FlexContainer, diff --git a/src/sql/workbench/api/node/sqlExtHost.api.impl.ts b/src/sql/workbench/api/node/sqlExtHost.api.impl.ts index aae675f306..742907a9a8 100644 --- a/src/sql/workbench/api/node/sqlExtHost.api.impl.ts +++ b/src/sql/workbench/api/node/sqlExtHost.api.impl.ts @@ -386,6 +386,9 @@ export function createApiFactory( NotifyMethods: sqlExtHostTypes.NotifyMethods, JobCompletionActionCondition: sqlExtHostTypes.JobCompletionActionCondition, AlertType: sqlExtHostTypes.AlertType, + FrequencyTypes: sqlExtHostTypes.FrequencyTypes, + FrequencySubDayTypes: sqlExtHostTypes.FrequencySubDayTypes, + FrequencyRelativeIntervals: sqlExtHostTypes.FrequencyRelativeIntervals, window, tasks, dashboard,