Task contribution (#742)

* work in progress

* set up necessary code. need to work on getting it working

* formatting

* work in progress

* work in progress

* formatting

* work in progress

* work in progress

* work in progress

* formatting

* needs a lot of work regarding how we do actions vs how extensions do actions

* formatting

* use connection profile for actions

* change action to be
This commit is contained in:
Anthony Dresser
2018-02-27 11:40:13 -08:00
committed by GitHub
parent 5adab4fafb
commit 3432dac261
23 changed files with 518 additions and 323 deletions

View File

@@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as types from 'vs/base/common/types';
import { TPromise } from 'vs/base/common/winjs.base';
import * as platform from 'vs/platform/registry/common/platform';
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
import { Action } from 'vs/base/common/actions';
import { IConstructorSignature3, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import * as nls from 'vs/nls';
import { ILocalizedString, IMenuItem, MenuRegistry, ICommandAction } from 'vs/platform/actions/common/actions';
import Event from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { LinkedList } from 'vs/base/common/linkedList';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
export interface ITaskOptions {
id: string;
title: string;
iconClass: string;
description?: ITaskHandlerDescription;
}
export abstract class Task {
public readonly id: string;
public readonly title: string;
public readonly iconClass: string;
private readonly _description: ITaskHandlerDescription;
constructor(opts: ITaskOptions) {
this.id = opts.id;
this.title = opts.title;
this.iconClass = opts.iconClass;
this._description = opts.description;
}
private toITask(): ITask {
return {
id: this.id,
handler: (accessor, profile, args) => this.runTask(accessor, profile, args),
description: this._description
};
}
private toCommandAction(): ICommandAction {
return {
iconClass: this.iconClass,
id: this.id,
title: this.title
};
}
public registerTask(): IDisposable {
MenuRegistry.addCommand(this.toCommandAction());
return TaskRegistry.registerTask(this.toITask());
}
public abstract runTask(accessor: ServicesAccessor, profile: IConnectionProfile, args: any): void | TPromise<void>;
}
export interface ITaskHandlerDescription {
description: string;
args: { name: string; description?: string; constraint?: types.TypeConstraint; }[];
returns?: string;
}
export interface ITaskEvent {
taskId: string;
}
export interface ITaskAction {
id: string;
title: string | ILocalizedString;
category?: string | ILocalizedString;
iconClass?: string;
iconPath?: string;
}
export interface ITaskHandler {
(accessor: ServicesAccessor, profile: IConnectionProfile, ...args: any[]): void;
}
export interface ITask {
id: string;
handler: ITaskHandler;
precondition?: ContextKeyExpr;
description?: ITaskHandlerDescription;
}
export interface ITaskRegistry {
registerTask(id: string, command: ITaskHandler): IDisposable;
registerTask(command: ITask): IDisposable;
getTasks(): string[];
}
export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
private _tasks = new Array<string>();
registerTask(idOrTask: string | ITask, handler?: ITaskHandler): IDisposable {
let disposable: IDisposable;
let id: string;
if (types.isString(idOrTask)) {
disposable = CommandsRegistry.registerCommand(idOrTask, handler);
id = idOrTask;
} else {
disposable = CommandsRegistry.registerCommand(idOrTask);
id = idOrTask.id;
}
this._tasks.push(id);
return {
dispose: () => {
let index = this._tasks.indexOf(id);
if (index >= 0) {
this._tasks = this._tasks.splice(index, 1);
}
disposable.dispose();
}
};
}
getTasks(): string[] {
return this._tasks;
}
};

View File

@@ -1,95 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as platform from 'vs/platform/registry/common/platform';
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
import { Action } from 'vs/base/common/actions';
import { IConstructorSignature3 } from 'vs/platform/instantiation/common/instantiation';
import * as nls from 'vs/nls';
export type TaskIdentifier = string;
export interface ActionICtor extends IConstructorSignature3<string, string, string, TaskAction> {
ID: string;
LABEL: string;
ICON: string;
}
export class TaskAction extends Action {
constructor(id: string, label: string, private _icon: string) {
super(id, label);
}
get icon(): string {
return this._icon;
}
}
export const Extensions = {
TaskContribution: 'workbench.contributions.tasks'
};
export interface ITaskRegistry {
/**
* Returns a map of action ids to their contructors;
*/
idToCtorMap: { [id: string]: ActionICtor };
/**
* Returns array of registered ids
*/
ids: Array<string>;
/**
* Schemas of the tasks registered
*/
taskSchemas: IJSONSchemaMap;
/**
* Registers an action as a task which can be ran given the schema as an input
* @param id id of the task
* @param description desciption of the task
* @param schema schema of expected input
* @param ctor contructor of the action
*/
registerTask(id: string, description: string, schema: IJSONSchema, ctor: ActionICtor): TaskIdentifier;
}
class TaskRegistry implements ITaskRegistry {
private _idCtorMap: { [id: string]: ActionICtor } = {};
private _taskSchema: IJSONSchema = { type: 'object', description: nls.localize('schema.taskSchema', 'Task actions specific for sql'), properties: {}, additionalProperties: false };
get idToCtorMap(): { [id: string]: ActionICtor } {
return this._idCtorMap;
}
get ids(): Array<string> {
return Object.keys(this._idCtorMap);
}
get taskSchemas(): IJSONSchemaMap {
return this._taskSchema.properties;
}
/**
* Registers an action as a task which can be ran given the schema as an input
* @param id id of the task
* @param description desciption of the task
* @param schema schema of expected input
* @param ctor contructor of the action
*/
registerTask(id: string, description: string, schema: IJSONSchema, ctor: ActionICtor): TaskIdentifier {
this._idCtorMap[id] = ctor;
this._taskSchema.properties[id] = schema;
return id;
}
}
const taskRegistry = new TaskRegistry();
platform.Registry.add(Extensions.TaskContribution, taskRegistry);
export function registerTask(id: string, description: string, schema: IJSONSchema, ctor: ActionICtor): TaskIdentifier {
return taskRegistry.registerTask(id, description, schema, ctor);
}