mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 21:33:41 +02:00
* fix(issues): query workspace working agents independently Co-authored-by: multica-agent <github@multica.ai> * feat(agents): filter working agents by source type Co-authored-by: multica-agent <github@multica.ai> * feat(issues): scope working agents to My Issues Co-authored-by: multica-agent <github@multica.ai> * test(agents): cover My Issues squad relations Co-authored-by: multica-agent <github@multica.ai> * fix(issues): unify working-agent filters across views Co-authored-by: multica-agent <github@multica.ai> * fix(issues): preserve empty working-agent filters Co-authored-by: multica-agent <github@multica.ai> --------- Co-authored-by: Eve <eve@multica-ai.local> Co-authored-by: multica-agent <github@multica.ai>
80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { ListTodo } from "lucide-react";
|
|
import type {
|
|
Issue,
|
|
IssueTableFacetSpec,
|
|
IssueTableFacetsResponse,
|
|
} from "@multica/core/types";
|
|
import { useIssuesScopeStore } from "@multica/core/issues/stores/issues-scope-store";
|
|
import { useViewStore } from "@multica/core/issues/stores/view-store-context";
|
|
import { PageHeader } from "../../layout/page-header";
|
|
import { useT } from "../../i18n";
|
|
import { IssueSurface } from "../surface/issue-surface";
|
|
import { IssuesHeader } from "./issues-header";
|
|
|
|
function IssuesSurfaceHeader({
|
|
issues,
|
|
isRefreshing,
|
|
facetCountsExact,
|
|
tableFacetCounts,
|
|
onTableFacetChange,
|
|
}: {
|
|
issues: Issue[];
|
|
isRefreshing: boolean;
|
|
facetCountsExact: boolean;
|
|
tableFacetCounts?: IssueTableFacetsResponse;
|
|
onTableFacetChange: (facet: IssueTableFacetSpec | null) => void;
|
|
}) {
|
|
const dateFilter = useViewStore((s) => s.dateFilter);
|
|
const setDateFilter = useViewStore((s) => s.setDateFilter);
|
|
|
|
return (
|
|
<IssuesHeader
|
|
scopedIssues={issues}
|
|
dateFilter={dateFilter}
|
|
onDateFilterChange={setDateFilter}
|
|
isRefreshing={isRefreshing}
|
|
facetCountsExact={facetCountsExact}
|
|
tableFacetCounts={tableFacetCounts}
|
|
onTableFacetChange={onTableFacetChange}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function IssuesPage() {
|
|
const { t } = useT("issues");
|
|
const scope = useIssuesScopeStore((s) => s.scope);
|
|
|
|
return (
|
|
<div className="flex flex-1 min-h-0 flex-col">
|
|
<PageHeader className="gap-2">
|
|
<ListTodo className="h-4 w-4 text-muted-foreground" />
|
|
<h1 className="text-sm font-medium">{t(($) => $.page.breadcrumb_title)}</h1>
|
|
</PageHeader>
|
|
|
|
<IssueSurface
|
|
scope={{ type: "workspace", actorKind: scope }}
|
|
modes={["board", "list", "table", "swimlane"]}
|
|
batchToolbar="list"
|
|
renderHeader={({ controller }) => (
|
|
<IssuesSurfaceHeader
|
|
issues={controller.surfaceIssues}
|
|
isRefreshing={controller.isRefreshing}
|
|
facetCountsExact={controller.facetCountsExact}
|
|
tableFacetCounts={controller.tableFacetCounts}
|
|
onTableFacetChange={controller.setActiveTableFacet}
|
|
/>
|
|
)}
|
|
renderEmpty={() => (
|
|
<div className="flex flex-1 min-h-0 flex-col items-center justify-center gap-2 text-muted-foreground">
|
|
<ListTodo className="h-10 w-10 text-muted-foreground/40" />
|
|
<p className="text-sm">{t(($) => $.page.empty_title)}</p>
|
|
<p className="text-xs">{t(($) => $.page.empty_hint)}</p>
|
|
</div>
|
|
)}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|