Initial work on Arc tree view (#11008)

* Initial work on Arc tree view

* finish my thoughts
This commit is contained in:
Charles Gagnon
2020-06-18 16:50:31 -07:00
committed by GitHub
parent 935733d23c
commit 88fce764d3
23 changed files with 464 additions and 77 deletions

View File

@@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ControllerTreeNode } from './controllerTreeNode';
import { TreeNode } from './treeNode';
import { LoadingControllerNode as LoadingTreeNode } from './loadingTreeNode';
import { ControllerModel } from '../../models/controllerModel';
/**
* The TreeDataProvider for the Azure Arc view, which displays a list of registered
* controllers and the resources under them.
*/
export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNode> {
private _onDidChangeTreeData: vscode.EventEmitter<TreeNode | undefined> = new vscode.EventEmitter<TreeNode | undefined>();
readonly onDidChangeTreeData: vscode.Event<TreeNode | undefined> = this._onDidChangeTreeData.event;
private _loading: boolean = true;
private _loadingNode = new LoadingTreeNode();
private _controllerNodes: ControllerTreeNode[] = [];
constructor(private _context: vscode.ExtensionContext) {
// TODO:
setTimeout(() => {
this._loading = false;
this._onDidChangeTreeData.fire(undefined);
}, 5000);
}
public async getChildren(element?: TreeNode): Promise<TreeNode[]> {
if (this._loading) {
return [this._loadingNode];
}
if (element) {
return element.getChildren();
} else {
return this._controllerNodes;
}
}
public getTreeItem(element: TreeNode): TreeNode | Thenable<TreeNode> {
return element;
}
public addController(model: ControllerModel): void {
this._controllerNodes.push(new ControllerTreeNode(model, this._context));
this._onDidChangeTreeData.fire(undefined);
}
public removeController(controllerNode: ControllerTreeNode): void {
this._controllerNodes = this._controllerNodes.filter(node => node !== controllerNode);
this._onDidChangeTreeData.fire(undefined);
}
}

View File

@@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { TreeNode } from './treeNode';
import { MiaaTreeNode } from './miaaTreeNode';
import { ResourceType } from '../../constants';
import { PostgresTreeNode } from './postgresTreeNode';
import { ControllerModel, Registration } from '../../models/controllerModel';
import { ControllerDashboard } from '../dashboards/controller/controllerDashboard';
import { PostgresModel } from '../../models/postgresModel';
import { parseInstanceName } from '../../common/utils';
import { MiaaModel } from '../../models/miaaModel';
/**
* The TreeNode for displaying an Azure Arc Controller
*/
export class ControllerTreeNode extends TreeNode {
private _children: TreeNode[] = [];
constructor(private _model: ControllerModel, private _context: vscode.ExtensionContext) {
super(_model.controllerUrl, vscode.TreeItemCollapsibleState.Collapsed, ResourceType.dataControllers);
_model.onRegistrationsUpdated(registrations => this.refreshChildren(registrations));
_model.refresh().catch(err => console.log(`Error refreshing Arc Controller model for tree node : ${err}`));
}
public async getChildren(): Promise<TreeNode[]> {
return this._children;
}
public async openDashboard(): Promise<void> {
const controllerDashboard = new ControllerDashboard(this._model);
await controllerDashboard.showDashboard();
}
private refreshChildren(registrations: Registration[]): void {
this._children = <TreeNode[]>registrations.map(registration => {
if (!registration.instanceNamespace || !registration.instanceName) {
console.warn('Registration is missing required namespace and name values, skipping');
return undefined;
}
switch (registration.instanceType) {
case ResourceType.postgresInstances:
const postgresModel = new PostgresModel(this._model.controllerUrl, this._model.auth, registration.instanceNamespace, parseInstanceName(registration.instanceName));
return new PostgresTreeNode(postgresModel, this._model, this._context);
case ResourceType.sqlManagedInstances:
const miaaModel = new MiaaModel(this._model.controllerUrl, this._model.auth, registration.instanceNamespace, parseInstanceName(registration.instanceName));
return new MiaaTreeNode(miaaModel, this._model);
}
return undefined;
}).filter(item => item); // filter out invalid nodes (controllers or ones without required properties)
}
}

View File

@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as loc from '../../localizedConstants';
import { TreeNode } from './treeNode';
/**
* A placeholder TreeNode to display while we're loading the initial set of stored nodes
*/
export class LoadingControllerNode extends TreeNode {
constructor() {
super(loc.loading, vscode.TreeItemCollapsibleState.None, 'loading');
}
}

View File

@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ResourceType } from '../../constants';
import { TreeNode } from './treeNode';
import { MiaaModel } from '../../models/miaaModel';
import { ControllerModel } from '../../models/controllerModel';
import { MiaaDashboard } from '../dashboards/miaa/miaaDashboard';
/**
* The TreeNode for displaying a SQL Managed Instance on Azure Arc
*/
export class MiaaTreeNode extends TreeNode {
constructor(private _model: MiaaModel, private _controllerModel: ControllerModel) {
super(_model.name, vscode.TreeItemCollapsibleState.None, ResourceType.sqlManagedInstances);
}
public async openDashboard(): Promise<void> {
const miaaDashboard = new MiaaDashboard(this._controllerModel, this._model);
await Promise.all([
miaaDashboard.showDashboard(),
this._model.refresh()]);
}
}

View File

@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ResourceType } from '../../constants';
import { TreeNode } from './treeNode';
import { PostgresModel } from '../../models/postgresModel';
import { ControllerModel } from '../../models/controllerModel';
import { PostgresDashboard } from '../dashboards/postgres/postgresDashboard';
/**
* The TreeNode for displaying an Postgres Server group
*/
export class PostgresTreeNode extends TreeNode {
constructor(private _model: PostgresModel, private _controllerModel: ControllerModel, private _context: vscode.ExtensionContext) {
super(_model.name, vscode.TreeItemCollapsibleState.None, ResourceType.postgresInstances);
}
public async openDashboard(): Promise<void> {
const postgresDashboard = new PostgresDashboard(this._context, this._controllerModel, this._model);
await Promise.all([
postgresDashboard.showDashboard(),
this._model.refresh()]);
}
}

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { getResourceTypeIcon } from '../../common/utils';
/**
* The base class for a TreeNode to be displayed in the TreeView
*/
export abstract class TreeNode extends vscode.TreeItem {
constructor(label: string, collapsibleState: vscode.TreeItemCollapsibleState, private resourceType?: string) {
super(label, collapsibleState);
}
public async getChildren(): Promise<TreeNode[]> {
return [];
}
public async openDashboard(): Promise<void> { }
iconPath = getResourceTypeIcon(this.resourceType);
contextValue = this.resourceType;
}