feat: pinned tickets, at hand on the home page and in search

Each person pins up to 20 tickets from the ticket's page («Fijar»). They
show as a strip under the projects on the home page and in the search
palette before typing. Private and without history, like the views of
«my work» (Mongo `pinned_issues`); tickets in the trash or out of reach
are left out, and when the list is full the unreadable ones are dropped
first.

API: GET /api/me/pins, PUT/DELETE /api/issues/{issue}/pin; GraphQL
myPins, pinIssue, unpinIssue and Issue.pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 10:15:28 +02:00
parent 423f82c1a3
commit dfa42a8a1a
32 changed files with 1612 additions and 46 deletions

View File

@@ -662,6 +662,9 @@ type Issue {
"""The epic or ticket this one breaks down"""
parent: IssueParent
"""Whether I pinned it (false without a token)"""
pinned: Boolean!
priority: IssuePriority!
projectId: ID!
projectKey: String!
@@ -973,6 +976,11 @@ type Mutation {
"""Mark these as read, or all of them when `ids` is omitted"""
markNotificationsRead(ids: [ID!]): Boolean!
"""
Pin a ticket: keep it at hand on my home page and in search (private, at most 20)
"""
pinIssue(issueId: ID!): Boolean!
"""
Ship the release. Fails while it has unfinished tickets unless force = true.
"""
@@ -1046,6 +1054,9 @@ type Mutation {
unarchiveProject(projectId: ID!): CommandResult!
unlinkIssues(input: LinkIssuesInput!): CommandResult!
"""Unpin a ticket"""
unpinIssue(issueId: ID!): Boolean!
"""The link stops working"""
unshareDashboard(projectId: ID!): Boolean!
@@ -1532,6 +1543,11 @@ type Query {
"""My notifications, newest first, and how many are unread"""
myNotifications(limit: Int! = 30, unreadOnly: Boolean! = false): MyNotifications!
"""
My pinned tickets, most recently pinned first (trashed or out of reach left out)
"""
myPins: [Issue!]!
"""Projects where I am a member"""
myProjects: [Project!]!