mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Initial work on Arc tree view (#11008)
* Initial work on Arc tree view * finish my thoughts
This commit is contained in:
@@ -78,7 +78,7 @@ export class MiaaConnectionStringsPage extends DashboardPage {
|
||||
|
||||
const ip = this._instanceRegistration.externalIp;
|
||||
const port = this._instanceRegistration.externalPort;
|
||||
const username = this._miaaModel.connectionProfile.userName;
|
||||
const username = this._miaaModel.username;
|
||||
|
||||
const pairs: KeyValue[] = [
|
||||
new InputKeyValue('ADO.NET', `Server=tcp:${ip},${port};Persist Security Info=False;User ID=${username};Password={your_password_here};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;`),
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as loc from '../../../localizedConstants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
import { IconPathHelper, cssStyles, ResourceType } from '../../../constants';
|
||||
import { ControllerModel, Registration } from '../../../models/controllerModel';
|
||||
import { getAzurecoreApi, promptForResourceDeletion, getErrorText } from '../../../common/utils';
|
||||
import { getAzurecoreApi, promptForResourceDeletion, getDatabaseStateDisplayText } from '../../../common/utils';
|
||||
import { MiaaModel, DatabaseModel } from '../../../models/miaaModel';
|
||||
import { HybridSqlNsNameGetResponse } from '../../../controller/generated/v1/model/hybridSqlNsNameGetResponse';
|
||||
import { EndpointModel } from '../../../controller/generated/v1/api';
|
||||
@@ -39,7 +39,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
|
||||
constructor(modelView: azdata.ModelView, private _controllerModel: ControllerModel, private _miaaModel: MiaaModel) {
|
||||
super(modelView);
|
||||
this._instanceProperties.miaaAdmin = this._miaaModel.connectionProfile.userName;
|
||||
this._instanceProperties.miaaAdmin = this._miaaModel.username || this._instanceProperties.miaaAdmin;
|
||||
this._controllerModel.onRegistrationsUpdated((_: Registration[]) => {
|
||||
this.eventuallyRunOnInitialized(() => {
|
||||
this.handleRegistrationsUpdated().catch(e => console.log(e));
|
||||
@@ -184,7 +184,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
vscode.window.showInformationMessage(loc.resourceDeleted(this._miaaModel.name));
|
||||
}
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._miaaModel.name, getErrorText(error)));
|
||||
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._miaaModel.name, error));
|
||||
} finally {
|
||||
deleteButton.enabled = true;
|
||||
}
|
||||
@@ -253,7 +253,10 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
}
|
||||
|
||||
private handleDatabasesUpdated(databases: DatabaseModel[]): void {
|
||||
this._databasesTable.data = databases.map(d => [d.name, d.status]);
|
||||
// If we were able to get the databases it means we have a good connection so update the username too
|
||||
this._instanceProperties.miaaAdmin = this._miaaModel.username || this._instanceProperties.miaaAdmin;
|
||||
this.refreshDisplayedProperties();
|
||||
this._databasesTable.data = databases.map(d => [d.name, getDatabaseStateDisplayText(d.status)]);
|
||||
this._databasesTableLoading.loading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ import { PostgresDiagnoseAndSolveProblemsPage } from './postgresDiagnoseAndSolve
|
||||
import { PostgresSupportRequestPage } from './postgresSupportRequestPage';
|
||||
|
||||
export class PostgresDashboard extends Dashboard {
|
||||
constructor(title: string, private _context: vscode.ExtensionContext, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
|
||||
super(title);
|
||||
constructor(private _context: vscode.ExtensionContext, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
|
||||
super(loc.postgresDashboard);
|
||||
}
|
||||
|
||||
protected async registerTabs(modelView: azdata.ModelView): Promise<(azdata.DashboardTab | azdata.DashboardTabGroup)[]> {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { DuskyObjectModelsDatabase, DuskyObjectModelsDatabaseServiceArcPayload,
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
import { ControllerModel } from '../../../models/controllerModel';
|
||||
import { PostgresModel, PodRole } from '../../../models/postgresModel';
|
||||
import { promptForResourceDeletion, getErrorText } from '../../../common/utils';
|
||||
import { promptForResourceDeletion } from '../../../common/utils';
|
||||
|
||||
export class PostgresOverviewPage extends DashboardPage {
|
||||
private propertiesLoading?: azdata.LoadingComponent;
|
||||
@@ -226,7 +226,7 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
vscode.window.showInformationMessage(loc.resourceDeleted(this._postgresModel.fullName));
|
||||
}
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._postgresModel.fullName, getErrorText(error)));
|
||||
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._postgresModel.fullName, error));
|
||||
} finally {
|
||||
deleteButton.enabled = true;
|
||||
}
|
||||
|
||||
59
extensions/arc/src/ui/tree/controllerTreeDataProvider.ts
Normal file
59
extensions/arc/src/ui/tree/controllerTreeDataProvider.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
56
extensions/arc/src/ui/tree/controllerTreeNode.ts
Normal file
56
extensions/arc/src/ui/tree/controllerTreeNode.ts
Normal 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)
|
||||
}
|
||||
}
|
||||
18
extensions/arc/src/ui/tree/loadingTreeNode.ts
Normal file
18
extensions/arc/src/ui/tree/loadingTreeNode.ts
Normal 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');
|
||||
}
|
||||
}
|
||||
28
extensions/arc/src/ui/tree/miaaTreeNode.ts
Normal file
28
extensions/arc/src/ui/tree/miaaTreeNode.ts
Normal 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()]);
|
||||
}
|
||||
}
|
||||
28
extensions/arc/src/ui/tree/postgresTreeNode.ts
Normal file
28
extensions/arc/src/ui/tree/postgresTreeNode.ts
Normal 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()]);
|
||||
}
|
||||
}
|
||||
25
extensions/arc/src/ui/tree/treeNode.ts
Normal file
25
extensions/arc/src/ui/tree/treeNode.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user