feat(dashboard): show PR badges and deep-link to Review Center

Add pull request badges to the repository dashboard and enable deep-
linking to the Review Center with a repository and source pre-filter.
Badges are populated by resolving remotes, matching them to configured
integration sources, and querying providers for open PRs while handling
loading, error, and unavailable states. The dashboard badge opens the
Review Center pre-filled and the app stores initial query/source values
to support the deep-link.

- Resolve and normalize remotes to match integration sources reliably.
- Query provider APIs using stored credentials with sensible timeouts.
- Expose a badge action that navigates to the Review Center pre-filtered.
This commit is contained in:
2026-09-07 16:19:26 +02:00
parent a55a3ca300
commit c6553218a2
3 changed files with 178 additions and 7 deletions
+10 -2
View File
@@ -315,6 +315,8 @@
let unlistenStartupRepository: (() => void) | undefined;
let activeRepoPath = "";
let activeView: AppView = "management";
let reviewCenterInitialQuery = "";
let reviewCenterInitialSourceId = "";
let repoTabs: RepoTab[] = [];
let repoTabContextMenu: RepoTabContextMenu | null = null;
let recentRepoPaths: string[] = [];
@@ -2587,9 +2589,11 @@
void backgroundRepoStatusTick(false);
}
function openReviewCenter() {
function openReviewCenter(repository = "", sourceId = "") {
if (isBusy) return;
closeRepoTabContextMenu();
reviewCenterInitialQuery = repository;
reviewCenterInitialSourceId = sourceId;
activeView = "review-center";
trackEvent("review_center_opened", { integrations: Object.values(gitIntegrationSettings.providers).filter((provider) => provider.enabled && provider.tokenStored).length });
}
@@ -5178,7 +5182,7 @@
{isBusy}
language={appLanguage}
onOpenManagement={openRepoManagement}
onOpenReviewCenter={openReviewCenter}
onOpenReviewCenter={() => openReviewCenter()}
isActive={(path) => activeView === "repository" && sameRepoPath(activeRepoPath, path)}
onSelect={selectRepoTab}
onClose={closeRepoTab}
@@ -5343,15 +5347,19 @@
{#if activeView === "management"}
<RepositoryDashboard
repos={dashboardRepos} language={appLanguage} {isBusy}
integrations={gitIntegrationSettings} loadCredential={loadStoredCredential}
onOpen={selectRepoTab} onAdd={chooseRepositoryFolder} onClone={openCloneDialog}
onInit={initializeRepository}
onFavorite={toggleFavoriteRepo} onClose={closeDashboardRepository}
onRemoveRecent={removeRepoFromRecent}
onOpenPullRequests={(repository, sourceId) => openReviewCenter(repository, sourceId)}
/>
{:else if activeView === "review-center"}
<ReviewCenter
language={appLanguage}
integrations={gitIntegrationSettings}
initialQuery={reviewCenterInitialQuery}
initialSourceId={reviewCenterInitialSourceId}
loadCredential={loadStoredCredential}
onOpenSettings={() => { appSettingsOpen = true; }}
/>