mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-15 01:25:36 -05:00
* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c * remove files we don't want * fix hygiene * update distro * update distro * fix hygiene * fix strict nulls * distro * distro * fix tests * fix tests * add another edit * fix viewlet icon * fix azure dialog * fix some padding * fix more padding issues
172 lines
6.0 KiB
TypeScript
172 lines
6.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* 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!./media/treeComponent';
|
|
|
|
import {
|
|
Component, Input, Inject, ChangeDetectorRef, forwardRef,
|
|
ViewChild, ElementRef, OnDestroy, AfterViewInit
|
|
} from '@angular/core';
|
|
|
|
import * as azdata from 'azdata';
|
|
|
|
import { ComponentBase } from 'sql/workbench/browser/modelComponents/componentBase';
|
|
import { IComponent, IComponentDescriptor, IModelStore } from 'sql/workbench/browser/modelComponents/interfaces';
|
|
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
|
|
import { TreeComponentRenderer } from 'sql/workbench/browser/modelComponents/treeComponentRenderer';
|
|
import { TreeComponentDataSource } from 'sql/workbench/browser/modelComponents/treeDataSource';
|
|
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
|
import { DefaultFilter, DefaultAccessibilityProvider, DefaultController } from 'vs/base/parts/tree/browser/treeDefaults';
|
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
|
import { ITreeComponentItem } from 'sql/workbench/common/views';
|
|
import { TreeViewDataProvider } from 'sql/workbench/browser/modelComponents/treeViewDataProvider';
|
|
import * as DOM from 'vs/base/browser/dom';
|
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
|
import { KeyCode } from 'vs/base/common/keyCodes';
|
|
import { values } from 'vs/base/common/collections';
|
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|
|
|
class Root implements ITreeComponentItem {
|
|
label = {
|
|
label: 'root'
|
|
};
|
|
handle = '0';
|
|
parentHandle = null;
|
|
collapsibleState = 2;
|
|
children = void 0;
|
|
options = undefined;
|
|
}
|
|
|
|
@Component({
|
|
selector: 'modelview-tree',
|
|
template: `
|
|
<div #input style="width: 100%;height:100%"></div>
|
|
`
|
|
})
|
|
export default class TreeComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit {
|
|
@Input() descriptor: IComponentDescriptor;
|
|
@Input() modelStore: IModelStore;
|
|
private _tree: Tree;
|
|
private _treeRenderer: TreeComponentRenderer;
|
|
private _dataProvider: TreeViewDataProvider;
|
|
|
|
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
|
constructor(
|
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
|
@Inject(IThemeService) private themeService: IThemeService,
|
|
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
|
) {
|
|
super(changeRef, el);
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.baseInit();
|
|
|
|
}
|
|
|
|
ngAfterViewInit(): void {
|
|
if (this._inputContainer) {
|
|
this.createTreeControl();
|
|
}
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.baseDestroy();
|
|
}
|
|
|
|
public setDataProvider(handle: number, componentId: string, context: any): any {
|
|
this._dataProvider = new TreeViewDataProvider(handle, componentId, context);
|
|
this.createTreeControl();
|
|
}
|
|
|
|
public refreshDataProvider(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem }): void {
|
|
if (this._dataProvider) {
|
|
this._dataProvider.getItemsToRefresh(itemsToRefreshByHandle);
|
|
}
|
|
|
|
if (this._tree) {
|
|
for (const item of values(itemsToRefreshByHandle)) {
|
|
this._tree.refresh(<ITreeComponentItem>item);
|
|
}
|
|
}
|
|
}
|
|
|
|
private createTreeControl(): void {
|
|
if (!this._tree && this._dataProvider) {
|
|
const dataSource = this._instantiationService.createInstance(TreeComponentDataSource, this._dataProvider);
|
|
const renderer = new TreeComponentRenderer(this._dataProvider, this.themeService, { withCheckbox: this.withCheckbox });
|
|
this._treeRenderer = renderer;
|
|
const controller = new DefaultController();
|
|
const filter = new DefaultFilter();
|
|
const sorter = undefined;
|
|
const dnd = undefined;
|
|
const accessibilityProvider = new DefaultAccessibilityProvider();
|
|
|
|
this._tree = new Tree(this._inputContainer.nativeElement,
|
|
{ dataSource, renderer, controller, dnd, filter, sorter, accessibilityProvider },
|
|
{
|
|
indentPixels: 10,
|
|
twistiePixels: 20,
|
|
ariaLabel: 'Tree Node'
|
|
});
|
|
this._tree.setInput(new Root());
|
|
this._tree.domFocus();
|
|
this._register(this._tree);
|
|
this._register(attachListStyler(this._tree, this.themeService));
|
|
this._register(this._tree.onDidChangeSelection(e => {
|
|
this._dataProvider.onNodeSelected(e.selection);
|
|
}));
|
|
this.onkeydown(this._inputContainer.nativeElement, (e: StandardKeyboardEvent) => {
|
|
// Enter on a tree will select the currently selected item as the default behavior
|
|
// but if not stopped here then will propagate up.
|
|
// This might have unintended effects such as a dialog closing.
|
|
if (e.keyCode === KeyCode.Enter) {
|
|
this._tree.toggleExpansion(this._tree.getFocus());
|
|
DOM.EventHelper.stop(e, true);
|
|
}
|
|
});
|
|
this._tree.refresh();
|
|
this.layout();
|
|
}
|
|
}
|
|
|
|
/// IComponent implementation
|
|
|
|
public layout(): void {
|
|
if (this._tree) {
|
|
this.layoutTree();
|
|
this._tree.refresh();
|
|
}
|
|
super.layout();
|
|
}
|
|
|
|
private layoutTree(): void {
|
|
let width: number = this.convertSizeToNumber(this.width);
|
|
let height: number = this.convertSizeToNumber(this.height);
|
|
this._tree.layout(
|
|
height && height > 0 ? height : DOM.getContentHeight(this._inputContainer.nativeElement),
|
|
width && width > 0 ? width : DOM.getContentWidth(this._inputContainer.nativeElement));
|
|
}
|
|
|
|
public setLayout(layout: any): void {
|
|
// TODO allow configuring the look and feel
|
|
|
|
this.layout();
|
|
}
|
|
|
|
public setProperties(properties: { [key: string]: any; }): void {
|
|
super.setProperties(properties);
|
|
this._treeRenderer.options.withCheckbox = this.withCheckbox;
|
|
}
|
|
|
|
public get withCheckbox(): boolean {
|
|
return this.getPropertyOrDefault<azdata.TreeProperties, boolean>((props) => props.withCheckbox, false);
|
|
}
|
|
|
|
public set withCheckbox(newValue: boolean) {
|
|
this.setPropertyFromUI<azdata.TreeProperties, boolean>((properties, value) => { properties.withCheckbox = value; }, newValue);
|
|
}
|
|
}
|