rhamt-vscode-extension
Version:
RHAMT VSCode extension
157 lines (132 loc) • 5.46 kB
text/typescript
import * as path from 'path';
import { Disposable, Event, EventEmitter, TreeDataProvider, TreeItem } from 'vscode';
import { IRhamtNode } from './index';
import { localize } from './localize';
import { RhamtParentNode } from './RhamtParentNode';
import { LoadMoreTreeItem } from './LoadMoreTreeItem';
import { RhamtNode } from './RhamtNode';
import { RhamtModelService } from 'raas-core';
import { ConfigurationProvider } from './ConfigurationProvider';
import { ConfigurationNode } from './ConfigurationNode';
export class RhamtTreeDataProvider implements TreeDataProvider<IRhamtNode>, Disposable {
private _onDidChangeTreeDataEmitter: EventEmitter<IRhamtNode> = new EventEmitter<IRhamtNode>();
private _onNodeCreateEmitter: EventEmitter<IRhamtNode> = new EventEmitter<IRhamtNode>();
private readonly _loadMoreCommandId: string;
private _disposables: Disposable[] = [];
constructor(private modelService: RhamtModelService, loadMoreCommandId: string) {
this._loadMoreCommandId = loadMoreCommandId;
this._disposables.push(this.modelService.onModelLoaded((m) => {
this.refresh(undefined, false);
}));
}
public dispose(): void {
for (const disposable of this._disposables) {
disposable.dispose();
}
}
public get onDidChangeTreeData(): Event<IRhamtNode> {
return this._onDidChangeTreeDataEmitter.event;
}
public get onNodeCreate(): Event<IRhamtNode> {
return this._onNodeCreateEmitter.event;
}
public getTreeItem(node: RhamtNode): TreeItem {
return {
label: node.label,
id: node.id,
collapsibleState: undefined,
contextValue: node.treeItem.contextValue,
iconPath: node.iconPath,
command: node.treeItem.commandId ? {
command: node.treeItem.commandId,
title: '',
arguments: [node]
} : undefined
};
}
public async getChildren(node?: RhamtParentNode): Promise<IRhamtNode[]> {
try {
return this.doGetChildren(node);
} catch (error) {
return Promise.resolve([new RhamtNode(node, {
label: localize('errorNode', 'Error: {0}', error),
contextValue: 'rhamtextensionui.error'
})]);
}
}
private async doGetChildren(node?: RhamtParentNode): Promise<IRhamtNode[]> {
let result: IRhamtNode[];
if (node) {
const cachedChildren: RhamtNode[] = await node.getCachedChildren();
const hasMoreChildren: boolean = node.treeItem.hasMoreChildren();
result = node.creatingNodes.concat(cachedChildren);
if (hasMoreChildren) {
result = result.concat(new RhamtNode(node, new LoadMoreTreeItem(this._loadMoreCommandId)));
}
} else {
result = await this.populateRootNodes();
}
return result;
}
public async refresh(node?: IRhamtNode, clearCache: boolean = true): Promise<void> {
if (clearCache && node) {
if (node.treeItem.refreshLabel) {
await node.treeItem.refreshLabel(node);
}
if (node instanceof RhamtParentNode) {
node.clearCache();
}
}
this._onDidChangeTreeDataEmitter.fire(node);
}
public async loadMore(node: IRhamtNode): Promise<void> {
if (node.parent instanceof RhamtParentNode) {
await node.parent.loadMoreChildren();
this._onDidChangeTreeDataEmitter.fire(node.parent);
}
}
public async findNode(id: string): Promise<IRhamtNode | undefined> {
let nodes: IRhamtNode[] = await this.getChildren();
let foundAncestor: boolean;
do {
foundAncestor = false;
for (const node of nodes) {
if (node.id === id) {
return node;
} else if (id.startsWith(`${node.id}/`) && node instanceof RhamtParentNode) {
nodes = await node.getCachedChildren();
foundAncestor = true;
break;
}
}
} while (foundAncestor);
return undefined;
}
private async populateRootNodes(): Promise<IRhamtNode[]> {
let nodes: IRhamtNode[];
if (this.modelService.loaded) {
nodes = this.modelService.model.getConfigurations().map(config => {
return new ConfigurationNode(this,
new ConfigurationProvider(config),
config.id,
config.name,
this._onNodeCreateEmitter
);
});
}
else {
nodes = [new RhamtNode(undefined, {
label: localize('loadingNode', 'Loading...'),
contextValue: 'rhamtCommandNode',
iconPath: {
light: path.join(__filename, '..', '..', '..', 'resources', 'light', 'Loading.svg'),
dark: path.join(__filename, '..', '..', '..', 'resources', 'dark', 'Loading.svg')
}
})];
(async () => setTimeout(() => {
this.modelService.init(path.join(__filename, '..', '..', '..', 'data', 'model.json')).catch(e => console.log(e));
}, 500))();
}
return nodes;
}
}