Agent : New Step dialog (#1834)

* added file browser tree to API and dialog

* added callbacks for selected files

* added file browser to step dialog

* remove commented code

* fixed file name bug
This commit is contained in:
Aditya Bist
2018-07-03 13:07:02 -07:00
committed by GitHub
parent bf7c1306b1
commit 6f402ac79f
7 changed files with 260 additions and 12 deletions

View File

@@ -23,7 +23,7 @@ import { ITree } from 'vs/base/parts/tree/browser/tree';
/**
* Implements tree view for file browser
*/
export class FileBrowserTreeView {
export class FileBrowserTreeView implements IDisposable {
private _tree: ITree;
private _toDispose: IDisposable[] = [];

View File

@@ -19,6 +19,7 @@ import WebViewComponent from './webview.component';
import TableComponent from './table.component';
import TextComponent from './text.component';
import LoadingComponent from './loadingComponent.component';
import FileBrowserTreeComponent from './fileBrowserTree.component';
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
@@ -70,3 +71,6 @@ registerComponentType(TABLE_COMPONENT, ModelComponentTypes.Table, TableComponent
export const LOADING_COMPONENT = 'loading-component';
registerComponentType(LOADING_COMPONENT, ModelComponentTypes.LoadingComponent, LoadingComponent);
export const FILEBROWSERTREE_COMPONENT = 'filebrowsertree-component';
registerComponentType(FILEBROWSERTREE_COMPONENT, ModelComponentTypes.FileBrowserTree, FileBrowserTreeComponent);

View File

@@ -0,0 +1,136 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef, ViewChild, ElementRef, OnDestroy, AfterViewInit
} from '@angular/core';
import * as sqlops from 'sqlops';
import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { FileBrowserViewModel } from '../fileBrowser/fileBrowserViewModel';
import { FileNode } from 'sql/parts/fileBrowser/common/fileNode';
import { FileBrowserTreeView } from '../fileBrowser/fileBrowserTreeView';
@Component({
selector: 'modelview-fileBrowserTree',
template: `
<div #fileBrowserTree style="width:420px;height:700px"></div>
`
})
export default class FileBrowserTreeComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit {
@Input() descriptor: IComponentDescriptor;
@Input() modelStore: IModelStore;
private _treeView: FileBrowserTreeView;
private _viewModel: FileBrowserViewModel;
private _fileFilters: [{label: string, filters: string[]}] = [
{ label: 'All Files', filters: ['*'] }
];
@ViewChild('fileBrowserTree', { read: ElementRef }) private _treeContainer: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
super(changeRef);
}
ngOnInit(): void {
this.baseInit();
}
ngAfterViewInit(): void {
this._viewModel = this._instantiationService.createInstance(FileBrowserViewModel);
this._viewModel.onAddFileTree(args => this.handleOnAddFileTree(args.rootNode, args.selectedNode, args.expandedNodes));
this._viewModel.onPathValidate(args => this.handleOnValidate(args.succeeded, args.message));
}
public initialize() {
this._viewModel.initialize(this.ownerUri, '', this._fileFilters, 'Backup');
this._treeView = this._instantiationService.createInstance(FileBrowserTreeView);
this._treeView.setOnClickedCallback((arg) => {
this.onClicked(arg);
});
this._treeView.setOnDoubleClickedCallback((arg) => this.onDoubleClicked(arg));
this._register(this._treeView);
this._viewModel.openFileBrowser(0, false);
}
private onClicked(selectedNode: FileNode) {
this._onEventEmitter.fire({
eventType: ComponentEventType.onDidChange,
args: { fullPath: selectedNode.fullPath, isFile: selectedNode.isFile }
});
}
private onDoubleClicked(selectedNode: FileNode) {
if (selectedNode.isFile === true) {
}
}
private handleOnAddFileTree(rootNode: FileNode, selectedNode: FileNode, expandedNodes: FileNode[]) {
this.updateFileTree(rootNode, selectedNode, expandedNodes);
}
private updateFileTree(rootNode: FileNode, selectedNode: FileNode, expandedNodes: FileNode[]): void {
this._treeView.renderBody(this._treeContainer.nativeElement, rootNode, selectedNode, expandedNodes);
this._treeView.setVisible(true);
this.layoutTree();
this._changeRef.detectChanges();
}
private handleOnValidate(succeeded: boolean, errorMessage: string) {
if (succeeded === false) {
if (errorMessage === '') {
errorMessage = 'The provided path is invalid.';
}
}
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
// TODO: tree validation?
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
/// IComponent implementation
public layout(): void {
this._changeRef.detectChanges();
}
public setLayout(): void {
// TODO allow configuring the look and feel
this.layout();
}
private layoutTree(): void {
this._treeView.layout(700);
}
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
this.validate();
if (this.ownerUri) {
this.initialize();
}
}
// CSS-bound properties
public get ownerUri(): string {
return this.getPropertyOrDefault<sqlops.FileBrowserTreeProperties, string>((props) => props.ownerUri, '');
}
public set ownerUri(newValue: string) {
this.setPropertyFromUI<sqlops.FileBrowserTreeProperties, string>((props, value) => props.ownerUri = value, newValue);
}
}

View File

@@ -35,6 +35,7 @@ declare module 'sqlops' {
groupContainer(): GroupBuilder;
toolbarContainer(): ToolbarBuilder;
loadingComponent(): LoadingComponentBuilder;
fileBrowserTree(): ComponentBuilder<FileBrowserTreeComponent>;
}
export interface ComponentBuilder<T extends Component> {
@@ -362,6 +363,10 @@ declare module 'sqlops' {
selectedRows?: number[];
}
export interface FileBrowserTreeProperties extends ComponentProperties {
ownerUri: string;
}
export interface CheckBoxProperties {
checked?: boolean;
label?: string;
@@ -471,6 +476,10 @@ declare module 'sqlops' {
onRowSelected: vscode.Event<any>;
}
export interface FileBrowserTreeComponent extends Component, FileBrowserTreeProperties {
onDidChange: vscode.Event<any>;
}
export interface WebViewComponent extends Component {
html: string;
message: any;

View File

@@ -144,7 +144,8 @@ export enum ModelComponentTypes {
Form,
Group,
Toolbar,
LoadingComponent
LoadingComponent,
FileBrowserTree
}
export interface IComponentShape {

View File

@@ -158,6 +158,13 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
return builder;
}
fileBrowserTree(): sqlops.ComponentBuilder<sqlops.FileBrowserTreeComponent> {
let id = this.getNextComponentId();
let builder: ComponentBuilderImpl<sqlops.FileBrowserTreeComponent> = this.getComponentBuilder(new FileBrowserTreeComponentWrapper(this._proxy, this._handle, id), id);
this._componentBuilders.set(id, builder);
return builder;
}
getComponentBuilder<T extends sqlops.Component>(component: ComponentWrapper, id: string): ComponentBuilderImpl<T> {
let componentBuilder: ComponentBuilderImpl<T> = new ComponentBuilderImpl<T>(component);
this._componentBuilders.set(id, componentBuilder);
@@ -960,6 +967,28 @@ class LoadingComponentWrapper extends ComponentWrapper implements sqlops.Loading
}
}
class FileBrowserTreeComponentWrapper extends ComponentWrapper implements sqlops.FileBrowserTreeComponent {
constructor(proxy: MainThreadModelViewShape, handle: number, id: string) {
super(proxy, handle, ModelComponentTypes.FileBrowserTree, id);
this.properties = {};
this._emitterMap.set(ComponentEventType.onDidChange, new Emitter<any>());
}
public get ownerUri(): string {
return this.properties['ownerUri'];
}
public set ownerUri(value: string) {
this.setProperty('ownerUri', value);
}
public get onDidChange(): vscode.Event<any> {
let emitter = this._emitterMap.get(ComponentEventType.onDidChange);
return emitter && emitter.event;
}
}
class ModelViewImpl implements sqlops.ModelView {
public onClosedEmitter = new Emitter<any>();