@@ -12,7 +12,7 @@ import { GithubItemStateEnum, IAccount, IMilestone, IProject, IProjectItem, Repo
1212import { IssueModel } from './issueModel' ;
1313import { getAssigneesQuickPickItems , getLabelOptions , getMilestoneFromQuickPick , getProjectFromQuickPick } from './quickPicks' ;
1414import { isInCodespaces , vscodeDevPrLink } from './utils' ;
15- import { ChangeAssigneesReply , DisplayLabel , Issue , ProjectItemsReply , SubmitReviewReply } from './views' ;
15+ import { ChangeAssigneesReply , DisplayLabel , Issue , ProjectItemsReply , SubmitReviewReply , UnresolvedIdentity } from './views' ;
1616import { COPILOT_ACCOUNTS , IComment } from '../common/comment' ;
1717import { emojify , ensureEmojis } from '../common/emoji' ;
1818import Logger from '../common/logger' ;
@@ -34,14 +34,16 @@ export class IssueOverviewPanel<TItem extends IssueModel = IssueModel> extends W
3434
3535 protected readonly _panel : vscode . WebviewPanel ;
3636 protected _item : TItem ;
37+ protected _identity : UnresolvedIdentity ;
3738 protected _folderRepositoryManager : FolderRepositoryManager ;
3839 protected _scrollPosition = { x : 0 , y : 0 } ;
3940
4041 public static async createOrShow (
4142 telemetry : ITelemetry ,
4243 extensionUri : vscode . Uri ,
4344 folderRepositoryManager : FolderRepositoryManager ,
44- issue : IssueModel ,
45+ identity : UnresolvedIdentity ,
46+ issue ?: IssueModel ,
4547 toTheSide : Boolean = false ,
4648 _preserveFocus : boolean = true ,
4749 existingPanel ?: vscode . WebviewPanel
@@ -58,7 +60,7 @@ export class IssueOverviewPanel<TItem extends IssueModel = IssueModel> extends W
5860 if ( IssueOverviewPanel . currentPanel ) {
5961 IssueOverviewPanel . currentPanel . _panel . reveal ( activeColumn , true ) ;
6062 } else {
61- const title = `Issue #${ issue . number . toString ( ) } ` ;
63+ const title = `Issue #${ identity . number . toString ( ) } ` ;
6264 IssueOverviewPanel . currentPanel = new IssueOverviewPanel (
6365 telemetry ,
6466 extensionUri ,
@@ -71,7 +73,7 @@ export class IssueOverviewPanel<TItem extends IssueModel = IssueModel> extends W
7173 ) ;
7274 }
7375
74- await IssueOverviewPanel . currentPanel ! . update ( folderRepositoryManager , issue ) ;
76+ await IssueOverviewPanel . currentPanel ! . updateWithIdentity ( folderRepositoryManager , identity , issue ) ;
7577 }
7678
7779 public static refresh ( ) : void {
@@ -287,7 +289,32 @@ export class IssueOverviewPanel<TItem extends IssueModel = IssueModel> extends W
287289 // none for issues
288290 }
289291
290- public async update ( foldersManager : FolderRepositoryManager , issueModel : TItem , progressLocation ?: string ) : Promise < void > {
292+ /**
293+ * Resolve a model from an unresolved identity.
294+ * Subclasses can override to resolve different types (e.g., pull requests vs issues).
295+ */
296+ protected async resolveModel ( identity : UnresolvedIdentity ) : Promise < TItem | undefined > {
297+ return this . _folderRepositoryManager . resolveIssue (
298+ identity . owner ,
299+ identity . repo ,
300+ identity . number
301+ ) as Promise < TItem | undefined > ;
302+ }
303+
304+ /**
305+ * Get the display name for the item type (for error messages).
306+ */
307+ protected getItemTypeName ( ) : string {
308+ return 'issue' ;
309+ }
310+
311+ /**
312+ * Update the panel with an unresolved identity and optional model.
313+ * If no model is provided, it will be resolved from the identity.
314+ */
315+ public async updateWithIdentity ( foldersManager : FolderRepositoryManager , identity : UnresolvedIdentity , issueModel ?: TItem , progressLocation ?: string ) : Promise < void > {
316+ this . _identity = identity ;
317+
291318 if ( this . _folderRepositoryManager !== foldersManager ) {
292319 this . _folderRepositoryManager = foldersManager ;
293320 this . registerPrListeners ( ) ;
@@ -298,19 +325,39 @@ export class IssueOverviewPanel<TItem extends IssueModel = IssueModel> extends W
298325 scrollPosition : this . _scrollPosition ,
299326 } ) ;
300327
301- if ( ! this . _item || ( this . _item . number !== issueModel . number ) || ! this . _panel . webview . html ) {
328+ const isNewItem = ! this . _item || ( this . _item . number !== identity . number ) ;
329+ if ( isNewItem || ! this . _panel . webview . html ) {
302330 this . _panel . webview . html = this . getHtmlForWebview ( ) ;
303331 this . _postMessage ( { command : 'pr.clear' } ) ;
332+ }
304333
334+ // If no model provided, resolve it from the identity
335+ if ( ! issueModel ) {
336+ const resolvedModel = await this . resolveModel ( identity ) ;
337+ if ( ! resolvedModel ) {
338+ throw new Error (
339+ `Failed to resolve ${ this . getItemTypeName ( ) } #${ identity . number } in ${ identity . owner } /${ identity . repo } ` ,
340+ ) ;
341+ }
342+ issueModel = resolvedModel ;
305343 }
306344
307345 if ( progressLocation ) {
308- return vscode . window . withProgress ( { location : { viewId : progressLocation } } , ( ) => this . updateItem ( issueModel ) ) ;
346+ return vscode . window . withProgress ( { location : { viewId : progressLocation } } , ( ) => this . updateItem ( issueModel ! ) ) ;
309347 } else {
310348 return this . updateItem ( issueModel ) ;
311349 }
312350 }
313351
352+ public async update ( foldersManager : FolderRepositoryManager , issueModel : TItem , progressLocation ?: string ) : Promise < void > {
353+ const identity : UnresolvedIdentity = {
354+ owner : issueModel . remote . owner ,
355+ repo : issueModel . remote . repositoryName ,
356+ number : issueModel . number
357+ } ;
358+ return this . updateWithIdentity ( foldersManager , identity , issueModel , progressLocation ) ;
359+ }
360+
314361 protected override async _onDidReceiveMessage ( message : IRequestMessage < any > ) {
315362 const result = await super . _onDidReceiveMessage ( message ) ;
316363 if ( result !== this . MESSAGE_UNHANDLED ) {
0 commit comments