feat(ui): issues tabs in GitLab MR and GitHub PR views

Add an Issues tab alongside the merge-request / pull-request content in the
context panel's PR surface for both providers. The tab lists open issues
lazily and expands a selected issue into an inline detail view (body, labels,
assignees, comments) with a back action. Read-only: no issue create, update,
or close actions. Adds 15 i18n keys across all 11 locales.
This commit is contained in:
2026-08-16 16:27:49 +00:00
parent 7c8c2bba3f
commit be13272eb1
15 changed files with 1022 additions and 16 deletions
@@ -5,6 +5,8 @@ import { Button } from '@/components/ui/button';
import { ScrollShadow } from '@/components/ui/ScrollShadow';
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
import { SimpleMarkdownRenderer } from '@/components/chat/MarkdownRenderer';
import { SortableTabsStrip } from '@/components/ui/sortable-tabs-strip';
import { GitLabIssuesSection } from '@/components/views/git/GitLabIssuesSection';
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
import { useGitStatus, useGitStore } from '@/stores/useGitStore';
@@ -83,6 +85,10 @@ export const GitLabMrView: React.FC = () => {
setSettingsDialogOpen(true);
}, [setSettingsDialogOpen, setSettingsPage]);
// Local tab selection between the merge-request and issues surfaces. Not
// persisted: reopening the panel always lands on merge requests.
const [activeTab, setActiveTab] = React.useState<'mr' | 'issues'>('mr');
// ---- Current-branch merge request --------------------------------------
const [branchMr, setBranchMr] = React.useState<GitLabMergeRequestSummary | null>(null);
@@ -558,6 +564,23 @@ export const GitLabMrView: React.FC = () => {
preventOverscroll
>
<div className="flex flex-col gap-4">
<div className="flex h-8 min-w-0">
<SortableTabsStrip
className="h-full"
items={[
{ id: 'mr', label: t('contextPanel.gitlabMr.tabs.mergeRequests') },
{ id: 'issues', label: t('contextPanel.gitlabMr.tabs.issues') },
]}
activeId={activeTab}
onSelect={(tabId) => setActiveTab(tabId as 'mr' | 'issues')}
layoutMode="fit"
variant="active-pill"
activePillButtonClassName="h-7"
/>
</div>
{activeTab === 'mr' ? (
<>
<div className="flex flex-col gap-0.5">
<div className="typography-ui-header font-semibold text-foreground">{t('contextPanel.gitlabMr.title')}</div>
<div className="typography-micro text-muted-foreground">{t('contextPanel.gitlabMr.listSectionTitle')}</div>
@@ -921,6 +944,10 @@ export const GitLabMrView: React.FC = () => {
</div>
)}
</section>
</>
) : (
<GitLabIssuesSection directory={currentDirectory} />
)}
</div>
</ScrollableOverlay>
);