Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/commands/pipelineCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vscode from 'vscode';
import type { AdoClient } from '../api/adoClient';
import type { ConfigManager } from '../config/configManager';
import type { PipelineRunNode } from '../providers/pipelinesProvider';
import { PipelineRunDetailsPanel } from '../views/pipelineRunDetailsPanel';
import { loadPipelineRunDetailsPanel } from '../views/lazyPanels';
import { showErrorMessage, showInformationMessage } from '../utils/notifications';
import { pipelineRunUrl } from '../utils/pipelineUrls';

Expand All @@ -17,6 +17,7 @@ export async function viewPipelineRunDetails(
return;
}

const { PipelineRunDetailsPanel } = await loadPipelineRunDetailsPanel();
await PipelineRunDetailsPanel.show(context, client, config, node.build.id, {
organization: node.organization,
project: node.project
Expand Down
3 changes: 2 additions & 1 deletion src/commands/pullRequestCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import type {
import type { AdoClient, GitPullRequest, PullRequestReviewVote } from '../api/adoClient';
import { PullRequestReviewVotes } from '../api/adoClient';
import type { ConfigManager } from '../config/configManager';
import { PrDetailsPanel } from '../views/prDetailsPanel';
import type { PrCommentController } from '../views/prCommentController';
import type { PrDiffCache } from '../views/prContentProvider';
import { loadPrDetailsPanel } from '../views/lazyPanels';
import { parseAdoRemoteUrl } from '../utils/repoContext';
import { showErrorMessage, showInformationMessage, showWarningMessage } from '../utils/notifications';

Expand Down Expand Up @@ -102,6 +102,7 @@ export async function viewPullRequestDetails(
client: AdoClient,
config: ConfigManager
): Promise<void> {
const { PrDetailsPanel } = await loadPrDetailsPanel();
await PrDetailsPanel.show(context, client, config, node.pr, {
organization: node.organization,
project: node.project
Expand Down
23 changes: 14 additions & 9 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import {
import { PipelinesProvider, type PipelineRunNode, type PipelineStepLogNode } from './providers/pipelinesProvider';
import { BacklogProvider, SprintProvider, BoardProvider } from './providers/planningProviders';
import { WorkItemIconResolver } from './providers/workItemIconResolver';
import { PlanningPanel } from './views/planningPanel';
import { PrCommentController, type CommentReply } from './views/prCommentController';
import { PrDiffCache, PrDiffContentProvider, PR_DIFF_SCHEME } from './views/prContentProvider';
import { PrDetailsPanel } from './views/prDetailsPanel';
import { PipelineLogContentProvider, PIPELINE_LOG_SCHEME } from './views/pipelineLogContentProvider';
import { NotificationService } from './notifications/notificationService';
import { PrCommentHandler } from './notifications/handlers/prCommentHandler';
Expand Down Expand Up @@ -68,12 +66,17 @@ import {
} from './commands/pipelineCommands';
import { McpServerManager } from './mcp/mcpServerManager';
import { TodoCodeActionProvider } from './views/todoCodeActionProvider';
import { PipelineRunDetailsPanel } from './views/pipelineRunDetailsPanel';
import { AdoCompletionProvider } from './providers/completionProvider';
import { installNotificationMirroring, showErrorMessage, showInformationMessage, showOutputChannel, showWarningMessage } from './utils/notifications';
import { WorkItemHoverProvider, PullRequestHoverProvider } from './providers/hoverProvider';
import { adoErrorFingerprint, classifyAdoAuthError } from './utils/adoErrors';
import type { AuthRecoveryResult } from './utils/authRecovery';
import {
loadPlanningPanel,
loadedPlanningPanel,
loadedPrDetailsPanel,
loadPipelineRunDetailsPanel
} from './views/lazyPanels';

export async function activate(context: vscode.ExtensionContext): Promise<void> {
installNotificationMirroring();
Expand Down Expand Up @@ -465,21 +468,21 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
context.subscriptions.push(
vscode.commands.registerCommand('adoext.openBacklogView', async () => {
if (!(await ensureSignedIn())) { return; }
await PlanningPanel.show(context, 'backlog', client, config, refreshAllViews);
await (await loadPlanningPanel()).PlanningPanel.show(context, 'backlog', client, config, refreshAllViews);
})
);

context.subscriptions.push(
vscode.commands.registerCommand('adoext.openBoardView', async () => {
if (!(await ensureSignedIn())) { return; }
await PlanningPanel.show(context, 'board', client, config, refreshAllViews);
await (await loadPlanningPanel()).PlanningPanel.show(context, 'board', client, config, refreshAllViews);
})
);

context.subscriptions.push(
vscode.commands.registerCommand('adoext.openSprintView', async () => {
if (!(await ensureSignedIn())) { return; }
await PlanningPanel.show(context, 'sprint', client, config, refreshAllViews);
await (await loadPlanningPanel()).PlanningPanel.show(context, 'sprint', client, config, refreshAllViews);
})
);

Expand Down Expand Up @@ -826,7 +829,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
async () => {
await toggleResolvedPullRequestThreads(config);
pullRequestProvider.refresh();
await PrDetailsPanel.refreshAllOpenPanels();
const prMod = loadedPrDetailsPanel();
if (prMod) { await (await prMod).PrDetailsPanel.refreshAllOpenPanels(); }
}
)
);
Expand Down Expand Up @@ -897,7 +901,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
if (!(await ensureSignedIn())) { return; }
const newId = await rerunPipelineRun(node, client, config);
if (typeof newId === 'number' && newId > 0) {
await PipelineRunDetailsPanel.show(context, client, config, newId, {
await (await loadPipelineRunDetailsPanel()).PipelineRunDetailsPanel.show(context, client, config, newId, {
organization: node?.organization,
project: node?.project
});
Expand Down Expand Up @@ -1163,7 +1167,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
}
refreshAllViews();
if (e.affectsConfiguration('adoext.planningAssignedFilter')) {
void PlanningPanel.refreshOpenPanels();
const planningMod = loadedPlanningPanel();
if (planningMod) { void planningMod.then(m => m.PlanningPanel.refreshOpenPanels()); }
}
if (
e.affectsConfiguration('adoext.notifyOnNewPullRequestComments') ||
Expand Down
21 changes: 21 additions & 0 deletions src/views/lazyPanels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Shared lazy loaders for heavy webview panel modules.
// Caching the import promise here ensures all callers (extension.ts and
// command modules) observe the same loaded-or-not state, which matters for
// static refresh methods that must no-op when the module was never opened.
//
// `loadX()` triggers (or reuses) the import.
// `loadedX()` returns the cached import promise iff loadX() was ever called,
// otherwise undefined - used to skip work on modules that were never opened.

let _planning: Promise<typeof import('./planningPanel')> | undefined;
export const loadPlanningPanel = () => (_planning ??= import('./planningPanel'));
export const loadedPlanningPanel = () => _planning;

let _prDetails: Promise<typeof import('./prDetailsPanel')> | undefined;
export const loadPrDetailsPanel = () => (_prDetails ??= import('./prDetailsPanel'));
export const loadedPrDetailsPanel = () => _prDetails;

let _pipelineRun: Promise<typeof import('./pipelineRunDetailsPanel')> | undefined;
export const loadPipelineRunDetailsPanel = () =>
(_pipelineRun ??= import('./pipelineRunDetailsPanel'));
export const loadedPipelineRunDetailsPanel = () => _pipelineRun;