diff --git a/src/commands/registerCommands.ts b/src/commands/registerCommands.ts index a1573c44..450899a5 100644 --- a/src/commands/registerCommands.ts +++ b/src/commands/registerCommands.ts @@ -5,7 +5,7 @@ import { signInToTenant } from '@microsoft/vscode-azext-azureauth'; import { AzExtTreeItem, IActionContext, isAzExtTreeItem, openUrl, registerCommand, registerErrorHandler, registerReportIssueCommand } from '@microsoft/vscode-azext-utils'; -import { commands } from 'vscode'; +import { AuthenticationSessionAccountInformation, commands } from 'vscode'; import { uploadFileToCloudShell } from '../cloudConsole/uploadFileToCloudShell'; import { ext } from '../extensionVariables'; import { BranchDataItemWrapper } from '../tree/BranchDataItemWrapper'; @@ -70,8 +70,8 @@ export function registerCommands(): void { ext.actions.refreshTenantTree(node); }); - registerCommand('azureTenant.signInToTenant', async (_context, node: TenantTreeItem) => { - await (await ext.subscriptionProviderFactory()).signIn(node.tenantId); + registerCommand('azureTenant.signInToTenant', async (_context, node: TenantTreeItem, account?: AuthenticationSessionAccountInformation) => { + await (await ext.subscriptionProviderFactory()).signIn(node.tenantId, account); ext.actions.refreshTenantTree(node); }); diff --git a/src/tree/GenericItem.ts b/src/tree/GenericItem.ts index 38368921..ea027a62 100644 --- a/src/tree/GenericItem.ts +++ b/src/tree/GenericItem.ts @@ -15,6 +15,20 @@ export interface GenericItemOptions { readonly iconPath?: TreeItemIconPath; readonly description?: string; readonly collapsibleState?: vscode.TreeItemCollapsibleState; + readonly checkboxState?: vscode.TreeItemCheckboxState | { + /** + * The {@link TreeItemCheckboxState} of the tree item + */ + readonly state: vscode.TreeItemCheckboxState; + /** + * A tooltip for the checkbox + */ + readonly tooltip?: string; + /** + * Accessibility information used when screen readers interact with this checkbox + */ + readonly accessibilityInformation?: vscode.AccessibilityInformation; + }; } export class GenericItem implements ResourceGroupsItem { @@ -41,6 +55,7 @@ export class GenericItem implements ResourceGroupsItem { treeItem.description = this.options?.description; treeItem.contextValue = this.options?.contextValue; treeItem.iconPath = this.options?.iconPath; + treeItem.checkboxState = this.options?.checkboxState; return treeItem; } diff --git a/src/tree/tenants/TenantResourceTreeDataProvider.ts b/src/tree/tenants/TenantResourceTreeDataProvider.ts index 4024c65c..5463aba7 100644 --- a/src/tree/tenants/TenantResourceTreeDataProvider.ts +++ b/src/tree/tenants/TenantResourceTreeDataProvider.ts @@ -56,7 +56,7 @@ export class TenantResourceTreeDataProvider extends ResourceTreeDataProviderBase const tenantItems: ResourceGroupsItem[] = []; for await (const tenant of tenants) { const isSignedIn = await subscriptionProvider.isSignedIn(nonNullProp(tenant, 'tenantId'), account); - tenantItems.push(new TenantTreeItem(nonNullProp(tenant, 'displayName'), nonNullProp(tenant, 'tenantId'), nonNullProp(account, 'id'), { + tenantItems.push(new TenantTreeItem(nonNullProp(tenant, 'displayName'), nonNullProp(tenant, 'tenantId'), account, { contextValue: isSignedIn ? 'tenantName' : 'tenantNameNotSignedIn', checkboxState: (!(isSignedIn) || this.checkUnselectedTenants(nonNullProp(tenant, 'tenantId'))) ? vscode.TreeItemCheckboxState.Unchecked : vscode.TreeItemCheckboxState.Checked, // Make sure tenants which are not signed in are unchecked @@ -68,7 +68,8 @@ export class TenantResourceTreeDataProvider extends ResourceTreeDataProviderBase children: tenantItems, iconPath: new vscode.ThemeIcon('account'), contextValue: 'accountName', - collapsibleState: vscode.TreeItemCollapsibleState.Expanded + collapsibleState: vscode.TreeItemCollapsibleState.Expanded, + checkboxState: vscode.TreeItemCheckboxState.Checked, })); } } diff --git a/src/tree/tenants/TenantTreeItem.ts b/src/tree/tenants/TenantTreeItem.ts index fa5459fd..19417899 100644 --- a/src/tree/tenants/TenantTreeItem.ts +++ b/src/tree/tenants/TenantTreeItem.ts @@ -12,11 +12,11 @@ export interface TenantItemOptions extends GenericItemOptions { } export class TenantTreeItem implements ResourceGroupsItem { - constructor(public readonly label: string, public tenantId: string, public account: string, private readonly options?: TenantItemOptions) { + constructor(public readonly label: string, public tenantId: string, public readonly account: vscode.AuthenticationSessionAccountInformation, private readonly options?: TenantItemOptions) { } readonly id: string = this.tenantId; - readonly accountId: string = this.account + readonly accountId = this.account.id; getChildren(): vscode.ProviderResult { return this.options?.children; diff --git a/src/tree/tenants/registerTenantTree.ts b/src/tree/tenants/registerTenantTree.ts index 75c76943..74a702f1 100644 --- a/src/tree/tenants/registerTenantTree.ts +++ b/src/tree/tenants/registerTenantTree.ts @@ -51,20 +51,25 @@ export function registerTenantTree(context: vscode.ExtensionContext, options: Re } async function updateTenantsSetting(_context: IActionContext, tenants: vscode.TreeCheckboxChangeEvent) { - const unselectedTenants = ext.context.globalState.get('unselectedTenants') || []; + const state = ext.context.globalState.get('unselectedTenants'); + const unselectedTenants = new Set(state ?? []); - for (const item of tenants.items) { - if (item[1] === vscode.TreeItemCheckboxState.Unchecked) { - unselectedTenants.push(`${item[0].id}/${item[0].accountId}`); - } else if (item[1] === vscode.TreeItemCheckboxState.Checked) { - const treeItem = await item[0].getTreeItem(); + for (const [tenantTreeItem, state] of tenants.items) { + if (state === vscode.TreeItemCheckboxState.Unchecked) { + unselectedTenants.add(getKeyForTenant(tenantTreeItem)); + } else if (state === vscode.TreeItemCheckboxState.Checked) { + const treeItem = await tenantTreeItem.getTreeItem(); if (treeItem?.contextValue === 'tenantNameNotSignedIn') { - await vscode.commands.executeCommand('azureTenant.signInToTenant', item[0]); + await vscode.commands.executeCommand('azureTenant.signInToTenant', tenantTreeItem,); ext.actions.refreshTenantTree(); } - unselectedTenants.splice(unselectedTenants.indexOf(item[0].id), 1); + unselectedTenants.delete(getKeyForTenant(tenantTreeItem)); } } - await ext.context.globalState.update('unselectedTenants', unselectedTenants); + await ext.context.globalState.update('unselectedTenants', Array.from(unselectedTenants)); +} + +export function getKeyForTenant(tenant: { id: string, accountId: string }): string { + return `${tenant.id}/${tenant.accountId}`; }