From 5ae6885e944ada44079126973d694afdec8ffac6 Mon Sep 17 00:00:00 2001 From: Steve Roberts Date: Mon, 20 Aug 2018 20:54:31 -0700 Subject: [PATCH] Some refactoring/standardization on tree nodes --- src/lambda/explorer/blueprintNode.ts | 12 ++-- src/lambda/explorer/blueprintsLanguageNode.ts | 24 +++---- src/lambda/explorer/functionNode.ts | 12 ++-- src/lambda/explorer/functionsNode.ts | 22 +++++-- src/lambda/explorer/guideNode.ts | 14 ++-- src/lambda/explorer/guidesNode.ts | 16 ++--- src/lambda/explorer/projectBlueprintsNode.ts | 12 ++-- src/lambda/lambdaProvider.ts | 15 +++-- src/shared/IAWSTreeProvider.ts | 14 ++++ src/shared/awsTreeNodeBase.ts | 43 ++++++++++++ src/shared/extensionGlobals.ts | 2 +- src/shared/nodes.ts | 65 ------------------- src/shared/quickPickNode.ts | 15 +++++ 13 files changed, 142 insertions(+), 124 deletions(-) create mode 100644 src/shared/IAWSTreeProvider.ts create mode 100644 src/shared/awsTreeNodeBase.ts delete mode 100644 src/shared/nodes.ts create mode 100644 src/shared/quickPickNode.ts diff --git a/src/lambda/explorer/blueprintNode.ts b/src/lambda/explorer/blueprintNode.ts index f8328170e7f..387408d7b4f 100644 --- a/src/lambda/explorer/blueprintNode.ts +++ b/src/lambda/explorer/blueprintNode.ts @@ -1,11 +1,11 @@ 'use strict'; -import * as path from 'path'; -import { ExplorerNodeBase } from '../../shared/nodes'; import { TreeItem, Uri, ThemeIcon } from 'vscode'; +import * as path from 'path'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import { Blueprint } from '../models/blueprint'; -export class BlueprintNode extends ExplorerNodeBase implements TreeItem { +export class BlueprintNode extends AWSTreeNodeBase implements TreeItem { public static contextValue: string = 'awsLambdaBlueprint'; public contextValue: string = BlueprintNode.contextValue; @@ -25,11 +25,11 @@ export class BlueprintNode extends ExplorerNodeBase implements TreeItem { }; } - public getChildren(): BlueprintNode[] { - return []; + public getChildren(): Thenable { + return new Promise(resolve => resolve([])); } - public getTreeItem(): BlueprintNode | Promise { + public getTreeItem(): TreeItem { return this; } } diff --git a/src/lambda/explorer/blueprintsLanguageNode.ts b/src/lambda/explorer/blueprintsLanguageNode.ts index 7131788a432..d850d1f861d 100644 --- a/src/lambda/explorer/blueprintsLanguageNode.ts +++ b/src/lambda/explorer/blueprintsLanguageNode.ts @@ -1,28 +1,30 @@ 'use strict'; -import * as vscode from 'vscode'; -import { ExplorerNodeBase } from '../../shared/nodes'; +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import { BlueprintNode } from './blueprintNode'; import { BlueprintsCollection } from '../models/blueprintsCollection'; import { Blueprint } from '../models/blueprint'; -export class BlueprintsLanguageNode extends ExplorerNodeBase { +export class BlueprintsLanguageNode extends AWSTreeNodeBase { constructor(public readonly language: string, public readonly blueprintsCollection: BlueprintsCollection) { super(); } - public getChildren(): BlueprintNode[] { - let blueprints: BlueprintNode[] = []; - this.blueprintsCollection.filterBlueprintsForLanguage(this.language).forEach((b: Blueprint) => { - blueprints.push(new BlueprintNode(b)); - }); + public getChildren(): Thenable { + return new Promise(resolve => { + let blueprints: BlueprintNode[] = []; + this.blueprintsCollection.filterBlueprintsForLanguage(this.language).forEach((b: Blueprint) => { + blueprints.push(new BlueprintNode(b)); + }); - return blueprints; + resolve(blueprints); + }); } - public getTreeItem(): vscode.TreeItem | Promise { - const item = new vscode.TreeItem(this.language, vscode.TreeItemCollapsibleState.Collapsed); + public getTreeItem(): TreeItem { + const item = new TreeItem(this.language, TreeItemCollapsibleState.Collapsed); item.tooltip = `Project blueprints for creating new projects targeting AWS Lambda in ${this.language}`; return item; diff --git a/src/lambda/explorer/functionNode.ts b/src/lambda/explorer/functionNode.ts index 72981c7385b..d1718b427b6 100644 --- a/src/lambda/explorer/functionNode.ts +++ b/src/lambda/explorer/functionNode.ts @@ -1,11 +1,11 @@ 'use strict'; +import { TreeItem, Uri, ThemeIcon } from 'vscode'; import * as path from 'path'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import Lambda = require('aws-sdk/clients/lambda'); -import { ExplorerNodeBase } from '../../shared/nodes'; -import { TreeItem, Uri, ThemeIcon } from 'vscode'; -export class FunctionNode extends ExplorerNodeBase implements TreeItem { +export class FunctionNode extends AWSTreeNodeBase implements TreeItem { public static contextValue: string = 'awsLambdaFn'; public contextValue: string = FunctionNode.contextValue; @@ -26,11 +26,11 @@ export class FunctionNode extends ExplorerNodeBase implements TreeItem { }; } - public getChildren(): FunctionNode[] { - return []; + public getChildren(): Thenable { + return new Promise(resolve => resolve([])); } - public getTreeItem(): FunctionNode | Promise { + public getTreeItem(): TreeItem { return this; } } diff --git a/src/lambda/explorer/functionsNode.ts b/src/lambda/explorer/functionsNode.ts index 903d3e997f7..c21cba68011 100644 --- a/src/lambda/explorer/functionsNode.ts +++ b/src/lambda/explorer/functionsNode.ts @@ -1,24 +1,32 @@ 'use strict'; -import * as vscode from 'vscode'; -import { ExplorerNodeBase } from '../../shared/nodes'; +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; +import { FunctionNode } from './functionNode'; import { ext } from '../../shared/extensionGlobals'; import Lambda = require('aws-sdk/clients/lambda'); import { listLambdas } from '../utils'; -export class FunctionsNode extends ExplorerNodeBase { +export class FunctionsNode extends AWSTreeNodeBase { public static contextValue: string = 'awsLambdaFns'; public readonly contextValue: string = FunctionsNode.contextValue; public readonly label: string = 'Lambda Functions'; - public async getChildren(): Promise { - return await listLambdas(await ext.sdkClientBuilder.createAndConfigureSdkClient(Lambda, undefined)); + public getChildren(): Thenable { + return new Promise(resolve => { + this.queryDeployedLambdaFunctions().then((result) => resolve(result)); + }); } - public getTreeItem(): vscode.TreeItem | Promise { - const item = new vscode.TreeItem('Functions', vscode.TreeItemCollapsibleState.Collapsed); + public getTreeItem(): TreeItem { + const item = new TreeItem('Functions', TreeItemCollapsibleState.Collapsed); item.tooltip = 'My deployed Lambda functions'; return item; } + + private async queryDeployedLambdaFunctions() : Promise { + const client = await ext.sdkClientBuilder.createAndConfigureSdkClient(Lambda, undefined); + return await listLambdas(client); + } } diff --git a/src/lambda/explorer/guideNode.ts b/src/lambda/explorer/guideNode.ts index 409f39c3ced..2b56bd1c4da 100644 --- a/src/lambda/explorer/guideNode.ts +++ b/src/lambda/explorer/guideNode.ts @@ -1,11 +1,11 @@ 'use strict'; -import * as vscode from 'vscode'; +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import * as path from 'path'; -import { ExplorerNodeBase } from '../../shared/nodes'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import { URL } from 'url'; -export class GuideNode extends ExplorerNodeBase { +export class GuideNode extends AWSTreeNodeBase { public static contextValue: string = 'awsLambdaGuide'; public contextValue: string = GuideNode.contextValue; @@ -17,12 +17,12 @@ export class GuideNode extends ExplorerNodeBase { super(); } - public getChildren(): ExplorerNodeBase[] | Promise { - return []; + public getChildren(): Thenable { + return new Promise(resolve => resolve([])); } - public getTreeItem(): vscode.TreeItem | Promise { - const item = new vscode.TreeItem(`${this.guideName}`, vscode.TreeItemCollapsibleState.Collapsed); + public getTreeItem(): TreeItem { + const item = new TreeItem(`${this.guideName}`, TreeItemCollapsibleState.Collapsed); item.tooltip = `${this.guideUri}`; item.iconPath = { light: path.join(__filename, '..', '..', '..', 'resources', 'light', 'lambda_function.svg'), diff --git a/src/lambda/explorer/guidesNode.ts b/src/lambda/explorer/guidesNode.ts index cafe57c1eb5..c22093eda51 100644 --- a/src/lambda/explorer/guidesNode.ts +++ b/src/lambda/explorer/guidesNode.ts @@ -1,23 +1,23 @@ 'use strict'; -import * as vscode from 'vscode'; -import { ExplorerNodeBase } from '../../shared/nodes'; +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import { GuideNode } from './guideNode'; import { URL } from 'url'; -export class GuidesNode extends ExplorerNodeBase { +export class GuidesNode extends AWSTreeNodeBase { - rootNodes: ExplorerNodeBase[] = [ + rootNodes: AWSTreeNodeBase[] = [ new GuideNode('Developer Guide', new URL('https://docs.aws.amazon.com/lambda/latest/dg/welcome.html')), new GuideNode('API Reference', new URL('https://docs.aws.amazon.com/lambda/latest/dg/API_Reference.html')) ]; - public getChildren(): ExplorerNodeBase[] | Promise { - return this.rootNodes; + public getChildren(): Thenable { + return new Promise(resolve => resolve(this.rootNodes)); } - public getTreeItem(): vscode.TreeItem | Promise { - const item = new vscode.TreeItem('Reference Guides', vscode.TreeItemCollapsibleState.Collapsed); + public getTreeItem(): TreeItem { + const item = new TreeItem('Reference Guides', TreeItemCollapsibleState.Collapsed); item.tooltip = 'Reference materials for working with AWS Lambda'; return item; diff --git a/src/lambda/explorer/projectBlueprintsNode.ts b/src/lambda/explorer/projectBlueprintsNode.ts index 07b17d2f0e1..1c5dd17d385 100644 --- a/src/lambda/explorer/projectBlueprintsNode.ts +++ b/src/lambda/explorer/projectBlueprintsNode.ts @@ -1,15 +1,15 @@ 'use strict'; -import * as vscode from 'vscode'; -import { ExplorerNodeBase } from '../../shared/nodes'; +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; import { BlueprintsCollection } from '../models/blueprintsCollection'; import { BlueprintsLanguageNode } from './blueprintsLanguageNode'; -export class ProjectBlueprintsNode extends ExplorerNodeBase { +export class ProjectBlueprintsNode extends AWSTreeNodeBase { private allBlueprints: BlueprintsCollection = new BlueprintsCollection(); - public async getChildren(): Promise { + public async getChildren(): Promise { await this.allBlueprints.loadAllBlueprints(); // to date we do VS blueprints only @@ -22,8 +22,8 @@ export class ProjectBlueprintsNode extends ExplorerNodeBase { return languageNodes; } - public getTreeItem(): vscode.TreeItem | Promise { - const item = new vscode.TreeItem('Project Blueprints', vscode.TreeItemCollapsibleState.Collapsed); + public getTreeItem(): TreeItem { + const item = new TreeItem('Project Blueprints', TreeItemCollapsibleState.Collapsed); item.tooltip = 'Blueprints for creating new projects targeting AWS Lambda'; return item; diff --git a/src/lambda/lambdaProvider.ts b/src/lambda/lambdaProvider.ts index 0ae311ef6a6..86398ba05cb 100644 --- a/src/lambda/lambdaProvider.ts +++ b/src/lambda/lambdaProvider.ts @@ -1,7 +1,8 @@ 'use strict'; import * as vscode from 'vscode'; -import { ExplorerNodeBase, IRefreshableAWSTreeProvider } from '../shared/nodes'; +import { AWSTreeNodeBase } from '../shared/awsTreeNodeBase'; +import { IRefreshableAWSTreeProvider } from '../shared/IAWSTreeProvider'; import { FunctionsNode } from './explorer/functionsNode'; import { GuidesNode } from './explorer/guidesNode'; import { ProjectBlueprintsNode } from './explorer/projectBlueprintsNode'; @@ -14,7 +15,7 @@ import { getLambdaConfig } from './commands/getLambdaConfig'; import { AWSContext } from '../shared/awsContext'; import { ext } from '../shared/extensionGlobals'; -export class LambdaProvider implements vscode.TreeDataProvider, IRefreshableAWSTreeProvider { +export class LambdaProvider implements vscode.TreeDataProvider, IRefreshableAWSTreeProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; @@ -30,25 +31,25 @@ export class LambdaProvider implements vscode.TreeDataProvider ext.treesToRefreshOnContextChange.push(this); } - rootNodes: ExplorerNodeBase[] = [ + rootNodes: AWSTreeNodeBase[] = [ new FunctionsNode(), new GuidesNode(), new ProjectBlueprintsNode() ]; - getTreeItem(element: any): vscode.TreeItem | Thenable { + getTreeItem(element: AWSTreeNodeBase): vscode.TreeItem { return element.getTreeItem(); } - getChildren(element?: any): vscode.ProviderResult { + getChildren(element?: AWSTreeNodeBase): Thenable { if (element) { return element.getChildren(); } - return this.rootNodes; + return new Promise(resolve => resolve(this.rootNodes)); } - refresh(context: AWSContext) { + refresh(context?: AWSContext) { this._onDidChangeTreeData.fire(); } diff --git a/src/shared/IAWSTreeProvider.ts b/src/shared/IAWSTreeProvider.ts new file mode 100644 index 00000000000..b31e3eb4741 --- /dev/null +++ b/src/shared/IAWSTreeProvider.ts @@ -0,0 +1,14 @@ +'use strict'; + +import { AWSContext } from "./awsContext"; + +export interface IAWSTreeProvider { + viewProviderId: string; + + initialize(): void; +} + +export interface IRefreshableAWSTreeProvider extends IAWSTreeProvider { + refresh(newContext?: AWSContext): void; +} + diff --git a/src/shared/awsTreeNodeBase.ts b/src/shared/awsTreeNodeBase.ts new file mode 100644 index 00000000000..c61036b1758 --- /dev/null +++ b/src/shared/awsTreeNodeBase.ts @@ -0,0 +1,43 @@ +'use strict'; + +import { Command, Disposable, TreeItem } from 'vscode'; +import { AWSContext } from './awsContext'; + +export abstract class AWSTreeNodeBase extends Disposable { + + public readonly supportsPaging: boolean = false; + + protected children: AWSTreeNodeBase[] | undefined; + protected disposable: Disposable | undefined; + + constructor() { + super(() => this.dispose()); + } + + dispose() { + if (this.disposable !== undefined) { + this.disposable.dispose(); + this.disposable = undefined; + } + + this.resetChildren(); + } + + public abstract getTreeItem(): TreeItem; + + public abstract getChildren(): Thenable; + + public getCommand(): Command | undefined { + return undefined; + } + + public refresh(newContext: AWSContext): void { } + + public resetChildren(): void { + if (this.children !== undefined) { + this.children.forEach(c => c.dispose()); + this.children = undefined; + } + } +} + diff --git a/src/shared/extensionGlobals.ts b/src/shared/extensionGlobals.ts index 02f4ddd18fd..b6966cb9eb1 100644 --- a/src/shared/extensionGlobals.ts +++ b/src/shared/extensionGlobals.ts @@ -3,7 +3,7 @@ import { ExtensionContext, OutputChannel } from 'vscode'; import { AWSClientBuilder } from './awsClientBuilder'; import { AWSContext } from './awsContext'; -import { IRefreshableAWSTreeProvider } from './nodes'; +import { IRefreshableAWSTreeProvider } from './IAWSTreeprovider'; import { AWSStatusBar } from './statusBar'; /** diff --git a/src/shared/nodes.ts b/src/shared/nodes.ts deleted file mode 100644 index 3fcadddaca3..00000000000 --- a/src/shared/nodes.ts +++ /dev/null @@ -1,65 +0,0 @@ -'use strict'; - -import * as vscode from 'vscode'; -import { Command, Disposable, TreeItem } from 'vscode'; -import { AWSContext } from './awsContext'; - -export interface IAWSTreeProvider { - viewProviderId: string; - - initialize(): void; -} - -export interface IRefreshableAWSTreeProvider extends IAWSTreeProvider { - refresh(newContext: AWSContext): void; -} - -export abstract class ExplorerNodeBase extends Disposable { - - public readonly supportsPaging: boolean = false; - - protected children: ExplorerNodeBase[] | undefined; - protected disposable: Disposable | undefined; - // protected readonly id: number; - - constructor() { - super(() => this.dispose()); - } - - dispose() { - if (this.disposable !== undefined) { - this.disposable.dispose(); - this.disposable = undefined; - } - - this.resetChildren(); - } - - public abstract getChildren(): ExplorerNodeBase[] | Promise; - public abstract getTreeItem(): TreeItem | Promise; - - public getCommand(): Command | undefined { - return undefined; - } - - public refresh(newContext: AWSContext): void { } - - public resetChildren(): void { - if (this.children !== undefined) { - this.children.forEach(c => c.dispose()); - this.children = undefined; - } - } -} - -export class QuickPickNode implements vscode.QuickPickItem { - label: string; - description?: string | undefined; - detail?: string | undefined; - picked?: boolean | undefined; - constructor( - readonly id: string - ) { - this.label = id; - } -} \ No newline at end of file diff --git a/src/shared/quickPickNode.ts b/src/shared/quickPickNode.ts new file mode 100644 index 00000000000..1762334bd36 --- /dev/null +++ b/src/shared/quickPickNode.ts @@ -0,0 +1,15 @@ +'use strict'; + +import {QuickPickItem} from 'vscode'; + +export class QuickPickNode implements QuickPickItem { + label: string; + description?: string | undefined; + detail?: string | undefined; + picked?: boolean | undefined; + constructor( + readonly id: string + ) { + this.label = id; + } +} \ No newline at end of file