mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-19 12:10:37 +09:00
Add optional Parent Issue column to inbox show/hide columns
Adds a "parent" column option to the inbox column toggle dropdown. When enabled, sub-issues display the parent's identifier (e.g. PAP-123) with the parent title as a tooltip. Uses the existing issueById lookup map to resolve parent info without additional API calls. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
c414790404
commit
b3b9d99519
4 changed files with 33 additions and 3 deletions
|
|
@ -515,13 +515,14 @@ describe("inbox helpers", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hides the workspace column option unless isolated workspaces are enabled", () => {
|
it("hides the workspace column option unless isolated workspaces are enabled", () => {
|
||||||
expect(getAvailableInboxIssueColumns(false)).toEqual(["status", "id", "assignee", "project", "labels", "updated"]);
|
expect(getAvailableInboxIssueColumns(false)).toEqual(["status", "id", "assignee", "project", "parent", "labels", "updated"]);
|
||||||
expect(getAvailableInboxIssueColumns(true)).toEqual([
|
expect(getAvailableInboxIssueColumns(true)).toEqual([
|
||||||
"status",
|
"status",
|
||||||
"id",
|
"id",
|
||||||
"assignee",
|
"assignee",
|
||||||
"project",
|
"project",
|
||||||
"workspace",
|
"workspace",
|
||||||
|
"parent",
|
||||||
"labels",
|
"labels",
|
||||||
"updated",
|
"updated",
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export const INBOX_LAST_TAB_KEY = "paperclip:inbox:last-tab";
|
||||||
export const INBOX_ISSUE_COLUMNS_KEY = "paperclip:inbox:issue-columns";
|
export const INBOX_ISSUE_COLUMNS_KEY = "paperclip:inbox:issue-columns";
|
||||||
export type InboxTab = "mine" | "recent" | "unread" | "all";
|
export type InboxTab = "mine" | "recent" | "unread" | "all";
|
||||||
export type InboxApprovalFilter = "all" | "actionable" | "resolved";
|
export type InboxApprovalFilter = "all" | "actionable" | "resolved";
|
||||||
export const inboxIssueColumns = ["status", "id", "assignee", "project", "workspace", "labels", "updated"] as const;
|
export const inboxIssueColumns = ["status", "id", "assignee", "project", "workspace", "parent", "labels", "updated"] as const;
|
||||||
export type InboxIssueColumn = (typeof inboxIssueColumns)[number];
|
export type InboxIssueColumn = (typeof inboxIssueColumns)[number];
|
||||||
export const DEFAULT_INBOX_ISSUE_COLUMNS: InboxIssueColumn[] = ["status", "id", "updated"];
|
export const DEFAULT_INBOX_ISSUE_COLUMNS: InboxIssueColumn[] = ["status", "id", "updated"];
|
||||||
export type InboxWorkItem =
|
export type InboxWorkItem =
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,8 @@ describe("InboxIssueTrailingColumns", () => {
|
||||||
workspaceName={null}
|
workspaceName={null}
|
||||||
assigneeName={null}
|
assigneeName={null}
|
||||||
currentUserId={null}
|
currentUserId={null}
|
||||||
|
parentIdentifier={null}
|
||||||
|
parentTitle={null}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -229,6 +231,8 @@ describe("InboxIssueTrailingColumns", () => {
|
||||||
workspaceName={null}
|
workspaceName={null}
|
||||||
assigneeName={null}
|
assigneeName={null}
|
||||||
currentUserId={null}
|
currentUserId={null}
|
||||||
|
parentIdentifier={null}
|
||||||
|
parentTitle={null}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -141,13 +141,14 @@ function readIssueIdFromRun(run: HeartbeatRun): string | null {
|
||||||
|
|
||||||
|
|
||||||
type NonIssueUnreadState = "visible" | "fading" | "hidden" | null;
|
type NonIssueUnreadState = "visible" | "fading" | "hidden" | null;
|
||||||
const trailingIssueColumns: InboxIssueColumn[] = ["assignee", "project", "workspace", "labels", "updated"];
|
const trailingIssueColumns: InboxIssueColumn[] = ["assignee", "project", "workspace", "parent", "labels", "updated"];
|
||||||
const inboxIssueColumnLabels: Record<InboxIssueColumn, string> = {
|
const inboxIssueColumnLabels: Record<InboxIssueColumn, string> = {
|
||||||
status: "Status",
|
status: "Status",
|
||||||
id: "ID",
|
id: "ID",
|
||||||
assignee: "Assignee",
|
assignee: "Assignee",
|
||||||
project: "Project",
|
project: "Project",
|
||||||
workspace: "Workspace",
|
workspace: "Workspace",
|
||||||
|
parent: "Parent issue",
|
||||||
labels: "Tags",
|
labels: "Tags",
|
||||||
updated: "Last updated",
|
updated: "Last updated",
|
||||||
};
|
};
|
||||||
|
|
@ -157,6 +158,7 @@ const inboxIssueColumnDescriptions: Record<InboxIssueColumn, string> = {
|
||||||
assignee: "Assigned agent or board user.",
|
assignee: "Assigned agent or board user.",
|
||||||
project: "Linked project pill with its color.",
|
project: "Linked project pill with its color.",
|
||||||
workspace: "Execution or project workspace used for the issue.",
|
workspace: "Execution or project workspace used for the issue.",
|
||||||
|
parent: "Parent issue identifier and title.",
|
||||||
labels: "Issue labels and tags.",
|
labels: "Issue labels and tags.",
|
||||||
updated: "Latest visible activity time.",
|
updated: "Latest visible activity time.",
|
||||||
};
|
};
|
||||||
|
|
@ -224,6 +226,7 @@ function issueTrailingGridTemplate(columns: InboxIssueColumn[]): string {
|
||||||
if (column === "assignee") return "minmax(7.5rem, 9.5rem)";
|
if (column === "assignee") return "minmax(7.5rem, 9.5rem)";
|
||||||
if (column === "project") return "minmax(6.5rem, 8.5rem)";
|
if (column === "project") return "minmax(6.5rem, 8.5rem)";
|
||||||
if (column === "workspace") return "minmax(9rem, 12rem)";
|
if (column === "workspace") return "minmax(9rem, 12rem)";
|
||||||
|
if (column === "parent") return "minmax(8rem, 12rem)";
|
||||||
if (column === "labels") return "minmax(8rem, 10rem)";
|
if (column === "labels") return "minmax(8rem, 10rem)";
|
||||||
return "minmax(6rem, 7rem)";
|
return "minmax(6rem, 7rem)";
|
||||||
})
|
})
|
||||||
|
|
@ -238,6 +241,8 @@ export function InboxIssueTrailingColumns({
|
||||||
workspaceName,
|
workspaceName,
|
||||||
assigneeName,
|
assigneeName,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
|
parentIdentifier,
|
||||||
|
parentTitle,
|
||||||
}: {
|
}: {
|
||||||
issue: Issue;
|
issue: Issue;
|
||||||
columns: InboxIssueColumn[];
|
columns: InboxIssueColumn[];
|
||||||
|
|
@ -246,6 +251,8 @@ export function InboxIssueTrailingColumns({
|
||||||
workspaceName: string | null;
|
workspaceName: string | null;
|
||||||
assigneeName: string | null;
|
assigneeName: string | null;
|
||||||
currentUserId: string | null;
|
currentUserId: string | null;
|
||||||
|
parentIdentifier: string | null;
|
||||||
|
parentTitle: string | null;
|
||||||
}) {
|
}) {
|
||||||
const activityText = timeAgo(issue.lastActivityAt ?? issue.lastExternalCommentAt ?? issue.updatedAt);
|
const activityText = timeAgo(issue.lastActivityAt ?? issue.lastExternalCommentAt ?? issue.updatedAt);
|
||||||
const userLabel = formatAssigneeUserLabel(issue.assigneeUserId, currentUserId) ?? "User";
|
const userLabel = formatAssigneeUserLabel(issue.assigneeUserId, currentUserId) ?? "User";
|
||||||
|
|
@ -348,6 +355,22 @@ export function InboxIssueTrailingColumns({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (column === "parent") {
|
||||||
|
if (!issue.parentId) {
|
||||||
|
return <span key={column} className="min-w-0" aria-hidden="true" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span key={column} className="min-w-0 truncate text-xs text-muted-foreground" title={parentTitle ?? undefined}>
|
||||||
|
{parentIdentifier ? (
|
||||||
|
<span className="font-mono">{parentIdentifier}</span>
|
||||||
|
) : (
|
||||||
|
<span className="italic">Sub-issue</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span key={column} className="min-w-0 truncate text-right text-[11px] font-medium text-muted-foreground">
|
<span key={column} className="min-w-0 truncate text-right text-[11px] font-medium text-muted-foreground">
|
||||||
{activityText}
|
{activityText}
|
||||||
|
|
@ -1979,6 +2002,8 @@ export function Inbox() {
|
||||||
})}
|
})}
|
||||||
assigneeName={agentName(issue.assigneeAgentId)}
|
assigneeName={agentName(issue.assigneeAgentId)}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
|
parentIdentifier={issue.parentId ? (issueById.get(issue.parentId)?.identifier ?? null) : null}
|
||||||
|
parentTitle={issue.parentId ? (issueById.get(issue.parentId)?.title ?? null) : null}
|
||||||
/>
|
/>
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue