'How to build VS Code TreeView with custom JSON?

I'd like to build a TreeView based on a JSON file / REST Call and have an icon for each type of my objects. I have only three types of objects: Server, Host and Group. For each type I'd like to have a custom icon and configuration.menu similar to what I found here dynamic context menu.

I'm new to VS Code extensions building. I've tried to modify the constructor(){this.data ...} to get the json file and tinkered with the class class TreeItem extends vscode.TreeItem , however I'm not yet fully grasping the behavior I need of the class and code I need to change.

My current code:

import * as vscode from 'vscode';
import * as json from 'jsonc-parser';
import * as path from 'path';


export class CtmInfraProvider implements vscode.TreeDataProvider<TreeItem> {
  onDidChangeTreeData?: vscode.Event<TreeItem | null | undefined> | undefined;

  data: TreeItem[];

  constructor() {
    this.data = [new TreeItem('Agents', [
      new TreeItem(
        'datacenter', [new TreeItem('xyz.domain.name'), new TreeItem('xyz.domain.name'), new TreeItem('xyz.domain.name')])
    ]),
    new TreeItem('Groups', [
      new TreeItem(
        'abcd', [new TreeItem('xyz.domain.name'), new TreeItem('abc.domain.name'), new TreeItem('123.domain.name')]),
      new TreeItem(
        'wxyz', [new TreeItem('efg.domain.name'), new TreeItem('456.domain.name')])
    ])

    ];
  }

  getTreeItem(element: TreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
    return element;
  }

  getChildren(element?: TreeItem | undefined): vscode.ProviderResult<TreeItem[]> {
    if (element === undefined) {
      return this.data;
    }
    return element.children;
  }

}

class TreeItem extends vscode.TreeItem {

  constructor(
    public readonly label: string,
    public children?: TreeItem[],
    public readonly command?: vscode.Command,
    public iconPath?: { light: string, dark: string }
  ) {
    super(
      label,
      children === undefined ? vscode.TreeItemCollapsibleState.None :
        vscode.TreeItemCollapsibleState.Expanded);
    this.children = children;
    // this.type = type;
    this.tooltip = `Agent Details:\n - Datacenter: demo\n - OS: Linux \n - Version: 20.22.04.00\n - Status: Available`;
    // this.description = 'Hello Desc';
  }

  setConfiguredIcon(): void {
    let newLightIcon: any;
    let newDarkIcon: any;

    newLightIcon = path.join(__filename, '..', '..', 'resources', 'light', 'dna.svg');
    newDarkIcon = path.join(__filename, '..', '..', 'resources', 'dark', 'dna.svg');

    if (this.iconPath === undefined) {
      this.iconPath = {
        light: newLightIcon,
        dark: newDarkIcon
      };
    }
    else {
      this.iconPath = {
        light: newLightIcon,
        dark: newDarkIcon
      };
    }
  }

}

The desired result, missing icon and menu: TreeView based on hard-coded json

Here is a copy of the json file I'm looking at. If there is a better format, the json file can be adjusted anytime.

{
    "inventory": {
        "servers": [
            {
                "server": "abcd",
                "host": "abcd.domain.name",
                "nodes": [
                    {
                        "nodeid": "xyz.domain.name",
                        "operating_system": "Microsoft Windows Server 2016  (Build 14393)",
                        "status": "Available",
                        "version": "20.22.04.00"
                    },
                    {
                        "nodeid": "xyz.domain.name",
                        "operating_system": "Microsoft Windows Server 2016  (Build 14393)",
                        "status": "Available",
                        "version": "20.22.04.00"
                    },
                    {
                        "nodeid": "xyz.domain.name",
                        "operating_system": "Microsoft Windows Server 2016  (Build 14393)",
                        "status": "Available",
                        "version": "20.22.04.00"
                    }
                ],
                "groups": [
                    {
                        "groupid": "abcd",
                        "nodes": "xyz.domain.name,abc.domain.name,123.domain.name"
                    },
                    {
                        "groupid": "wxyz",
                        "nodes": "efg.domain.name,456.domain.name"
                    }
                ]
            },
            {
                "server": "1234",
                "host": "1234.domain.name",
                "nodes": null
            }
        ]
    }
}

Thank for your help.



Solution 1:[1]

I've managed to get the vscode.treeview populated with my json data.

custom treeview the source code will be open sourced and hosted on git soon. The code is quite large to accommodate for all the different objects. Now I have to figured out how to update the treeview when the refresh button is clicked and how to invoke a custom command on a treeview item. I will create new questions for this to better track it.

Regards.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Orchestrator