mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 13:29:44 +02:00
fix(issues): keep header controls horizontally scrollable
This commit is contained in:
@@ -538,68 +538,70 @@ export function IssuesHeader({
|
||||
const scopeLabel = t(($) => $.scope[SCOPE_LABEL_KEY[scope]]);
|
||||
|
||||
return (
|
||||
<div className="flex h-12 shrink-0 items-center justify-between gap-2 px-4">
|
||||
{/* Left: scope buttons */}
|
||||
<div className="hidden items-center gap-1 md:flex">
|
||||
{SCOPE_VALUES.map((s) => (
|
||||
<Tooltip key={s}>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={
|
||||
scope === s
|
||||
? "bg-accent text-accent-foreground hover:bg-accent/80"
|
||||
: "text-muted-foreground"
|
||||
}
|
||||
onClick={() => setScope(s)}
|
||||
>
|
||||
<div className="h-12 shrink-0 overflow-x-auto px-4 [-webkit-overflow-scrolling:touch]">
|
||||
<div className="flex h-full w-max min-w-full items-center justify-between gap-2">
|
||||
{/* Left: scope buttons */}
|
||||
<div className="hidden shrink-0 items-center gap-1 md:flex">
|
||||
{SCOPE_VALUES.map((s) => (
|
||||
<Tooltip key={s}>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={
|
||||
scope === s
|
||||
? "bg-accent text-accent-foreground hover:bg-accent/80"
|
||||
: "text-muted-foreground"
|
||||
}
|
||||
onClick={() => setScope(s)}
|
||||
>
|
||||
{t(($) => $.scope[SCOPE_LABEL_KEY[s]])}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<TooltipContent side="bottom">{t(($) => $.scope[SCOPE_DESC_KEY[s]])}</TooltipContent>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="shrink-0 gap-1 text-muted-foreground md:hidden"
|
||||
>
|
||||
<span className="truncate">{scopeLabel}</span>
|
||||
<ChevronDown className="size-3 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DropdownMenuContent align="start" className="w-auto">
|
||||
<DropdownMenuRadioGroup value={scope} onValueChange={(value) => setScope(value as IssuesScope)}>
|
||||
{SCOPE_VALUES.map((s) => (
|
||||
<DropdownMenuRadioItem key={s} value={s}>
|
||||
{t(($) => $.scope[SCOPE_LABEL_KEY[s]])}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<TooltipContent side="bottom">{t(($) => $.scope[SCOPE_DESC_KEY[s]])}</TooltipContent>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-w-0 gap-1 text-muted-foreground md:hidden"
|
||||
>
|
||||
<span className="truncate">{scopeLabel}</span>
|
||||
<ChevronDown className="size-3 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DropdownMenuContent align="start" className="w-auto">
|
||||
<DropdownMenuRadioGroup value={scope} onValueChange={(value) => setScope(value as IssuesScope)}>
|
||||
{SCOPE_VALUES.map((s) => (
|
||||
<DropdownMenuRadioItem key={s} value={s}>
|
||||
{t(($) => $.scope[SCOPE_LABEL_KEY[s]])}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<div className="flex min-w-0 items-center gap-1">
|
||||
{agentRunningFilter && (
|
||||
<span className="mr-1 hidden text-xs text-muted-foreground md:inline">
|
||||
{t(($) => $.agent_activity.filter_active_label)}
|
||||
</span>
|
||||
)}
|
||||
<WorkspaceAgentWorkingChip
|
||||
value={agentRunningFilter}
|
||||
onToggle={toggleAgentRunningFilter}
|
||||
scopedIssueIds={scopedIssueIds}
|
||||
/>
|
||||
<IssueDisplayControls scopedIssues={scopedIssues} allowGantt={allowGantt} />
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
{agentRunningFilter && (
|
||||
<span className="mr-1 hidden text-xs text-muted-foreground md:inline">
|
||||
{t(($) => $.agent_activity.filter_active_label)}
|
||||
</span>
|
||||
)}
|
||||
<WorkspaceAgentWorkingChip
|
||||
value={agentRunningFilter}
|
||||
onToggle={toggleAgentRunningFilter}
|
||||
scopedIssueIds={scopedIssueIds}
|
||||
/>
|
||||
<IssueDisplayControls scopedIssues={scopedIssues} allowGantt={allowGantt} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -681,7 +683,7 @@ export function IssueDisplayControls({
|
||||
const controlButtonClass = "h-8 w-8 gap-1 px-0 text-muted-foreground md:h-7 md:w-auto md:px-2.5";
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
{/* Filter */}
|
||||
<DropdownMenu>
|
||||
<Tooltip>
|
||||
|
||||
@@ -37,70 +37,72 @@ export function MyIssuesHeader({ allIssues }: { allIssues: Issue[] }) {
|
||||
const scopeLabel = SCOPES.find((s) => s.value === scope)?.label ?? SCOPES[0]?.label;
|
||||
|
||||
return (
|
||||
<div className="flex h-12 shrink-0 items-center justify-between gap-2 px-4">
|
||||
<div className="hidden items-center gap-1 md:flex">
|
||||
{SCOPES.map((s) => (
|
||||
<Tooltip key={s.value}>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={
|
||||
scope === s.value
|
||||
? "bg-accent text-accent-foreground hover:bg-accent/80"
|
||||
: "text-muted-foreground"
|
||||
}
|
||||
onClick={() => act.setScope(s.value)}
|
||||
>
|
||||
{s.label}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<TooltipContent side="bottom">{s.description}</TooltipContent>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
<div className="h-12 shrink-0 overflow-x-auto px-4 [-webkit-overflow-scrolling:touch]">
|
||||
<div className="flex h-full w-max min-w-full items-center justify-between gap-2">
|
||||
<div className="hidden shrink-0 items-center gap-1 md:flex">
|
||||
{SCOPES.map((s) => (
|
||||
<Tooltip key={s.value}>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={
|
||||
scope === s.value
|
||||
? "bg-accent text-accent-foreground hover:bg-accent/80"
|
||||
: "text-muted-foreground"
|
||||
}
|
||||
onClick={() => act.setScope(s.value)}
|
||||
>
|
||||
{s.label}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<TooltipContent side="bottom">{s.description}</TooltipContent>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-w-0 gap-1 text-muted-foreground md:hidden"
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="shrink-0 gap-1 text-muted-foreground md:hidden"
|
||||
>
|
||||
<span className="truncate">{scopeLabel}</span>
|
||||
<ChevronDown className="size-3 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DropdownMenuContent align="start" className="w-auto">
|
||||
<DropdownMenuRadioGroup
|
||||
value={scope}
|
||||
onValueChange={(value) => act.setScope(value as MyIssuesScope)}
|
||||
>
|
||||
<span className="truncate">{scopeLabel}</span>
|
||||
<ChevronDown className="size-3 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DropdownMenuContent align="start" className="w-auto">
|
||||
<DropdownMenuRadioGroup
|
||||
value={scope}
|
||||
onValueChange={(value) => act.setScope(value as MyIssuesScope)}
|
||||
>
|
||||
{SCOPES.map((s) => (
|
||||
<DropdownMenuRadioItem key={s.value} value={s.value}>
|
||||
{s.label}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
{SCOPES.map((s) => (
|
||||
<DropdownMenuRadioItem key={s.value} value={s.value}>
|
||||
{s.label}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<div className="flex min-w-0 items-center gap-1">
|
||||
{agentRunningFilter && (
|
||||
<span className="mr-1 hidden text-xs text-muted-foreground md:inline">
|
||||
{tIssues(($) => $.agent_activity.filter_active_label)}
|
||||
</span>
|
||||
)}
|
||||
<WorkspaceAgentWorkingChip
|
||||
value={agentRunningFilter}
|
||||
onToggle={act.toggleAgentRunningFilter}
|
||||
scopedIssueIds={scopedIssueIds}
|
||||
/>
|
||||
<IssueDisplayControls scopedIssues={allIssues} />
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
{agentRunningFilter && (
|
||||
<span className="mr-1 hidden text-xs text-muted-foreground md:inline">
|
||||
{tIssues(($) => $.agent_activity.filter_active_label)}
|
||||
</span>
|
||||
)}
|
||||
<WorkspaceAgentWorkingChip
|
||||
value={agentRunningFilter}
|
||||
onToggle={act.toggleAgentRunningFilter}
|
||||
scopedIssueIds={scopedIssueIds}
|
||||
/>
|
||||
<IssueDisplayControls scopedIssues={allIssues} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user