Skip to content

Commit

Permalink
refactor: move account related functions to separate files (#11870)
Browse files Browse the repository at this point in the history
* refactor: move account related functions to separate files

* test: fix ut

* test: add ut
  • Loading branch information
yiqing-zhao authored Jun 21, 2024
1 parent d90b957 commit 9347223
Show file tree
Hide file tree
Showing 8 changed files with 445 additions and 362 deletions.
39 changes: 34 additions & 5 deletions packages/vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ import { checkProjectTypeAndSendTelemetry, isM365Project } from "./utils/project
import { ReleaseNote } from "./utils/releaseNote";
import { ExtensionSurvey } from "./utils/survey";
import { getSettingsVersion, projectVersionCheck } from "./utils/telemetryUtils";
import { showError } from "./error/common";
import { TreeViewCommand } from "./treeview/treeViewCommand";
import { signOutM365, signOutAzure } from "./utils/accountUtils";
import { cmpAccountsHandler, createAccountHandler } from "./handlers/accountHandlers";

export async function activate(context: vscode.ExtensionContext) {
process.env[FeatureFlags.ChatParticipant] = (
Expand Down Expand Up @@ -214,7 +218,7 @@ export async function activate(context: vscode.ExtensionContext) {
export async function deactivate() {
await ExtTelemetry.cacheTelemetryEventAsync(TelemetryEvent.Deactivate);
await ExtTelemetry.dispose();
handlers.cmdHdlDisposeTreeView();
TreeViewManagerInstance.dispose();
await disableRunIcon();
}

Expand All @@ -224,7 +228,7 @@ function activateTeamsFxRegistration(context: vscode.ExtensionContext) {
registerTreeViewCommandsInHelper(context);
registerTeamsFxCommands(context);
registerMenuCommands(context);
handlers.registerAccountMenuCommands(context);
registerAccountMenuCommands(context);

TreeViewManagerInstance.registerTreeViews(context);
accountTreeViewProviderInstance.subscribeToStatusChanges({
Expand Down Expand Up @@ -292,7 +296,7 @@ function registerActivateCommands(context: vscode.ExtensionContext) {

// user can manage account in non-teamsfx project
const cmpAccountsCmd = vscode.commands.registerCommand("fx-extension.cmpAccounts", (...args) =>
Correlator.run(handlers.cmpAccountsHandler, args)
Correlator.run(cmpAccountsHandler, args)
);
context.subscriptions.push(cmpAccountsCmd);

Expand Down Expand Up @@ -662,8 +666,7 @@ function registerMenuCommands(context: vscode.ExtensionContext) {

const createAccountCmd = vscode.commands.registerCommand(
"fx-extension.createAccount",
(...args) =>
Correlator.run(handlers.createAccountHandler, [TelemetryTriggerFrom.ViewTitleNavigation])
(...args) => Correlator.run(createAccountHandler, [TelemetryTriggerFrom.ViewTitleNavigation])
);
context.subscriptions.push(createAccountCmd);

Expand Down Expand Up @@ -900,6 +903,32 @@ function registerOfficeDevMenuCommands(context: vscode.ExtensionContext) {
context.subscriptions.push(reportIssueCmd);
}

function registerAccountMenuCommands(context: vscode.ExtensionContext) {
// Register SignOut tree view command
context.subscriptions.push(
vscode.commands.registerCommand("fx-extension.signOut", async (node: TreeViewCommand) => {
try {
switch (node.contextValue) {
case "signedinM365": {
await Correlator.run(async () => {
await signOutM365(true);
});
break;
}
case "signedinAzure": {
await Correlator.run(async () => {
await signOutAzure(true);
});
break;
}
}
} catch (e) {
void showError(e as FxError);
}
})
);
}

async function initializeContextKey(context: vscode.ExtensionContext, isTeamsFxProject: boolean) {
await vscode.commands.executeCommand("setContext", "fx-extension.isSPFx", isSPFxProject);

Expand Down
207 changes: 1 addition & 206 deletions packages/vscode-extension/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import * as fs from "fs-extra";
import * as path from "path";
import * as util from "util";
import * as vscode from "vscode";
import { ExtensionContext, QuickPickItem, Uri, commands, env, window, workspace } from "vscode";
import { Uri, commands, env, window, workspace } from "vscode";
import azureAccountManager from "./commonlib/azureLogin";
import VsCodeLogInstance from "./commonlib/log";
import M365TokenInstance from "./commonlib/m365Login";
Expand Down Expand Up @@ -104,8 +104,6 @@ import { AzureAccountNode } from "./treeview/account/azureNode";
import { AccountItemStatus } from "./treeview/account/common";
import { M365AccountNode } from "./treeview/account/m365Node";
import envTreeProviderInstance from "./treeview/environmentTreeViewProvider";
import { TreeViewCommand } from "./treeview/treeViewCommand";
import TreeViewManagerInstance from "./treeview/treeViewManager";
import { getAppName } from "./utils/appDefinitionUtils";
import {
checkCoreNotEmpty,
Expand Down Expand Up @@ -453,46 +451,6 @@ export async function preDebugCheckHandler(): Promise<string | undefined> {
}
}

export async function createAccountHandler(args: any[]): Promise<void> {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.CreateAccountStart, getTriggerFromProperty(args));
const m365Option: OptionItem = {
id: "createAccountM365",
label: `$(add) ${localize("teamstoolkit.commands.createAccount.m365")}`,
description: localize("teamstoolkit.commands.createAccount.requireSubscription"),
};
const azureOption: OptionItem = {
id: "createAccountAzure",
label: `$(add) ${localize("teamstoolkit.commands.createAccount.azure")}`,
description: localize("teamstoolkit.commands.createAccount.free"),
};
const option: SingleSelectConfig = {
name: "CreateAccounts",
title: localize("teamstoolkit.commands.createAccount.title"),
options: [m365Option, azureOption],
};
const result = await VS_CODE_UI.selectOption(option);
if (result.isOk()) {
if (result.value.result === m365Option.id) {
await VS_CODE_UI.openUrl("https://developer.microsoft.com/microsoft-365/dev-program");
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.CreateAccount, {
[TelemetryProperty.AccountType]: AccountType.M365,
...getTriggerFromProperty(args),
});
} else if (result.value.result === azureOption.id) {
await VS_CODE_UI.openUrl("https://azure.microsoft.com/en-us/free/");
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.CreateAccount, {
[TelemetryProperty.AccountType]: AccountType.Azure,
...getTriggerFromProperty(args),
});
}
} else {
ExtTelemetry.sendTelemetryErrorEvent(TelemetryEvent.CreateAccount, result.error, {
...getTriggerFromProperty(args),
});
}
return;
}

export async function openBuildIntelligentAppsWalkthroughHandler(
...args: unknown[]
): Promise<Result<unknown, FxError>> {
Expand Down Expand Up @@ -1074,125 +1032,6 @@ export function saveTextDocumentHandler(document: vscode.TextDocumentWillSaveEve
}
}

export function registerAccountMenuCommands(context: ExtensionContext) {
// Register SignOut tree view command
context.subscriptions.push(
commands.registerCommand("fx-extension.signOut", async (node: TreeViewCommand) => {
try {
switch (node.contextValue) {
case "signedinM365": {
await Correlator.run(async () => {
await signOutM365(true);
});
break;
}
case "signedinAzure": {
await Correlator.run(async () => {
await signOutAzure(true);
});
break;
}
}
} catch (e) {
void showError(e as FxError);
}
})
);
}

export function cmdHdlDisposeTreeView() {
TreeViewManagerInstance.dispose();
}

export async function cmpAccountsHandler(args: any[]) {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.ManageAccount, getTriggerFromProperty(args));
const signInAzureOption: VscQuickPickItem = {
id: "signInAzure",
label: localize("teamstoolkit.handlers.signInAzure"),
function: () => signInAzure(),
};

const signOutAzureOption: VscQuickPickItem = {
id: "signOutAzure",
label: localize("teamstoolkit.handlers.signOutOfAzure"),
function: async () =>
await Correlator.run(async () => {
await signOutAzure(false);
}),
};

const signInM365Option: VscQuickPickItem = {
id: "signinM365",
label: localize("teamstoolkit.handlers.signIn365"),
function: () => signInM365(),
};

const signOutM365Option: VscQuickPickItem = {
id: "signOutM365",
label: localize("teamstoolkit.handlers.signOutOfM365"),
function: async () =>
await Correlator.run(async () => {
await signOutM365(false);
}),
};

const createAccountsOption: VscQuickPickItem = {
id: "createAccounts",
label: `$(add) ${localize("teamstoolkit.commands.createAccount.title")}`,
function: async () => {
await Correlator.run(() => createAccountHandler([]));
},
};

//TODO: hide subscription list until core or api expose the get subscription list API
// let selectSubscriptionOption: VscQuickPickItem = {
// id: "selectSubscription",
// label: "Specify an Azure Subscription",
// function: () => selectSubscription(),
// detail: "4 subscriptions discovered"
// };

const quickPick = window.createQuickPick();

const quickItemOptionArray: VscQuickPickItem[] = [];

const m365AccountRes = await M365TokenInstance.getStatus({ scopes: AppStudioScopes });
const m365Account = m365AccountRes.isOk() ? m365AccountRes.value : undefined;
if (m365Account && m365Account.status === "SignedIn") {
const accountInfo = m365Account.accountInfo;
const email = (accountInfo as any).upn ? (accountInfo as any).upn : undefined;
if (email !== undefined) {
signOutM365Option.label = signOutM365Option.label.concat(email);
}
quickItemOptionArray.push(signOutM365Option);
} else {
quickItemOptionArray.push(signInM365Option);
}

const azureAccount = await azureAccountManager.getStatus();
if (azureAccount.status === "SignedIn") {
const accountInfo = azureAccount.accountInfo;
const email = (accountInfo as any).email || (accountInfo as any).upn;
if (email !== undefined) {
signOutAzureOption.label = signOutAzureOption.label.concat(email);
}
quickItemOptionArray.push(signOutAzureOption);
} else {
quickItemOptionArray.push(signInAzureOption);
}

quickItemOptionArray.push(createAccountsOption);
quickPick.items = quickItemOptionArray;
quickPick.onDidChangeSelection((selection) => {
if (selection[0]) {
(selection[0] as VscQuickPickItem).function().catch(console.error);
quickPick.hide();
}
});
quickPick.onDidHide(() => quickPick.dispose());
quickPick.show();
}

export async function decryptSecret(cipher: string, selection: vscode.Range): Promise<void> {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.EditSecretStart, {
[TelemetryProperty.TriggerFrom]: TelemetryTriggerFrom.Other,
Expand Down Expand Up @@ -1488,50 +1327,6 @@ export function editAadManifestTemplate(args: any[]) {
}
}

export async function signOutAzure(isFromTreeView: boolean) {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.SignOutStart, {
[TelemetryProperty.TriggerFrom]: isFromTreeView
? TelemetryTriggerFrom.TreeView
: TelemetryTriggerFrom.CommandPalette,
[TelemetryProperty.AccountType]: AccountType.Azure,
});
await vscode.window.showInformationMessage(
localize("teamstoolkit.commands.azureAccount.signOutHelp")
);
}

export async function signOutM365(isFromTreeView: boolean) {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.SignOutStart, {
[TelemetryProperty.TriggerFrom]: isFromTreeView
? TelemetryTriggerFrom.TreeView
: TelemetryTriggerFrom.CommandPalette,
[TelemetryProperty.AccountType]: AccountType.M365,
});
let result = false;
result = await M365TokenInstance.signout();
if (result) {
accountTreeViewProviderInstance.m365AccountNode.setSignedOut();
await envTreeProviderInstance.refreshRemoteEnvWarning();
}
}

export async function signInAzure() {
await vscode.commands.executeCommand("fx-extension.signinAzure");
}

export async function signInM365() {
await vscode.commands.executeCommand("fx-extension.signinM365");
}

export interface VscQuickPickItem extends QuickPickItem {
/**
* Current id of the option item.
*/
id: string;

function: () => Promise<void>;
}

export async function migrateTeamsTabAppHandler(): Promise<Result<null, FxError>> {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.MigrateTeamsTabAppStart);
const selection = await VS_CODE_UI.showMessage(
Expand Down
Loading

0 comments on commit 9347223

Please sign in to comment.