mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 10:50:38 +09:00
Add linked issues row to execution workspace detail
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
e3f07aad55
commit
d9005405b9
6 changed files with 150 additions and 0 deletions
|
|
@ -24,6 +24,7 @@ export const issuesApi = {
|
|||
inboxArchivedByUserId?: string;
|
||||
unreadForUserId?: string;
|
||||
labelId?: string;
|
||||
executionWorkspaceId?: string;
|
||||
originKind?: string;
|
||||
originId?: string;
|
||||
includeRoutineExecutions?: boolean;
|
||||
|
|
@ -40,6 +41,7 @@ export const issuesApi = {
|
|||
if (filters?.inboxArchivedByUserId) params.set("inboxArchivedByUserId", filters.inboxArchivedByUserId);
|
||||
if (filters?.unreadForUserId) params.set("unreadForUserId", filters.unreadForUserId);
|
||||
if (filters?.labelId) params.set("labelId", filters.labelId);
|
||||
if (filters?.executionWorkspaceId) params.set("executionWorkspaceId", filters.executionWorkspaceId);
|
||||
if (filters?.originKind) params.set("originKind", filters.originKind);
|
||||
if (filters?.originId) params.set("originId", filters.originId);
|
||||
if (filters?.includeRoutineExecutions) params.set("includeRoutineExecutions", "true");
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ export const queryKeys = {
|
|||
labels: (companyId: string) => ["issues", companyId, "labels"] as const,
|
||||
listByProject: (companyId: string, projectId: string) =>
|
||||
["issues", companyId, "project", projectId] as const,
|
||||
listByExecutionWorkspace: (companyId: string, executionWorkspaceId: string) =>
|
||||
["issues", companyId, "execution-workspace", executionWorkspaceId] as const,
|
||||
detail: (id: string) => ["issues", "detail", id] as const,
|
||||
comments: (issueId: string) => ["issues", "comments", issueId] as const,
|
||||
attachments: (issueId: string) => ["issues", "attachments", issueId] as const,
|
||||
|
|
|
|||
|
|
@ -249,6 +249,14 @@ export function ExecutionWorkspaceDetail() {
|
|||
enabled: Boolean(workspace?.derivedFromExecutionWorkspaceId),
|
||||
});
|
||||
const derivedWorkspace = derivedWorkspaceQuery.data ?? null;
|
||||
const linkedIssuesQuery = useQuery({
|
||||
queryKey: workspace
|
||||
? queryKeys.issues.listByExecutionWorkspace(workspace.companyId, workspace.id)
|
||||
: ["issues", "__execution-workspace__", "__none__"],
|
||||
queryFn: () => issuesApi.list(workspace!.companyId, { executionWorkspaceId: workspace!.id }),
|
||||
enabled: Boolean(workspace?.companyId),
|
||||
});
|
||||
const linkedIssues = linkedIssuesQuery.data ?? [];
|
||||
|
||||
const linkedProjectWorkspace = useMemo(
|
||||
() => project?.workspaces.find((item) => item.id === workspace?.projectWorkspaceId) ?? null,
|
||||
|
|
@ -785,6 +793,55 @@ export function ExecutionWorkspaceDetail() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-border bg-card p-5">
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className="space-y-1">
|
||||
<div className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Linked issues</div>
|
||||
<h2 className="text-lg font-semibold">Issues using this workspace</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Any issue attached to this execution workspace appears here so you can review the full session context before reusing or closing it.
|
||||
</p>
|
||||
</div>
|
||||
<StatusPill>{linkedIssues.length} linked</StatusPill>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
{linkedIssuesQuery.isLoading ? (
|
||||
<p className="text-sm text-muted-foreground">Loading linked issues…</p>
|
||||
) : linkedIssuesQuery.error ? (
|
||||
<p className="text-sm text-destructive">
|
||||
{linkedIssuesQuery.error instanceof Error
|
||||
? linkedIssuesQuery.error.message
|
||||
: "Failed to load linked issues."}
|
||||
</p>
|
||||
) : linkedIssues.length > 0 ? (
|
||||
<div className="-mx-1 flex gap-3 overflow-x-auto px-1 pb-1">
|
||||
{linkedIssues.map((issue) => (
|
||||
<Link
|
||||
key={issue.id}
|
||||
to={issueUrl(issue)}
|
||||
className="min-w-72 rounded-xl border border-border/80 bg-background px-4 py-3 transition-colors hover:bg-accent/20"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0 space-y-1">
|
||||
<div className="font-mono text-xs text-muted-foreground">
|
||||
{issue.identifier ?? issue.id.slice(0, 8)}
|
||||
</div>
|
||||
<div className="line-clamp-2 text-sm font-medium">{issue.title}</div>
|
||||
</div>
|
||||
<StatusPill className="shrink-0">{issue.status}</StatusPill>
|
||||
</div>
|
||||
<div className="mt-3 flex items-center justify-between gap-3 text-xs text-muted-foreground">
|
||||
<span className="uppercase tracking-[0.16em]">{issue.priority}</span>
|
||||
<span>{formatDateTime(issue.updatedAt)}</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">No issues are currently linked to this execution workspace.</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ExecutionWorkspaceCloseDialog
|
||||
workspaceId={workspace.id}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue