feat: a dashboard for clients, behind a secret link
Owners and admins turn it on in Configuración → General, pick what it
shows (tickets per status, the sprint under way, release forecasts,
open epics and activity per day) and can renew or drop the link. Whoever
has it sees /share/{token} without an account: only those blocks, no
people nor single tickets but the epics, no links into the app, read
again every minute. A renewed or dropped link says it no longer works.
REST (GET/PUT/DELETE /api/projects/{project}/share and the public
GET /api/shared/dashboards/{token}) and GraphQL (dashboardShare,
shareDashboard, unshareDashboard, sharedDashboard). The token is kept
in dashboard_shares and goes with the project.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -465,6 +465,16 @@ input CustomFieldValueInput {
|
||||
value: String
|
||||
}
|
||||
|
||||
"""The project's link for clients (owners and admins)"""
|
||||
type DashboardShare {
|
||||
blocks: [String!]!
|
||||
createdAt: String!
|
||||
projectId: ID!
|
||||
|
||||
"""Secret of the link /share/{token}"""
|
||||
token: String!
|
||||
}
|
||||
|
||||
"""A commit, branch or pull request that mentions the ticket"""
|
||||
type DevLink {
|
||||
at: String!
|
||||
@@ -1010,6 +1020,9 @@ type Mutation {
|
||||
"""Put a ticket in a sprint (null: back to the backlog)"""
|
||||
setIssueSprint(issueId: ID!, sprintId: ID): CommandResult!
|
||||
|
||||
"""Turn the link on or change its blocks; renew for a new secret"""
|
||||
shareDashboard(input: ShareDashboardInput!): DashboardShare!
|
||||
|
||||
"""Start a planned sprint (only one under way per project)"""
|
||||
startSprint(sprintId: ID!): CommandResult!
|
||||
|
||||
@@ -1033,6 +1046,9 @@ type Mutation {
|
||||
unarchiveProject(projectId: ID!): CommandResult!
|
||||
unlinkIssues(input: LinkIssuesInput!): CommandResult!
|
||||
|
||||
"""The link stops working"""
|
||||
unshareDashboard(projectId: ID!): Boolean!
|
||||
|
||||
"""Push off on this device"""
|
||||
unsubscribePush(endpoint: String!): Boolean!
|
||||
|
||||
@@ -1456,6 +1472,9 @@ type Query {
|
||||
): [Activity!]!
|
||||
automations(projectId: ID!): [Automation!]!
|
||||
|
||||
"""The project's link for clients, if any (owners and admins)"""
|
||||
dashboardShare(projectId: ID!): DashboardShare
|
||||
|
||||
"""
|
||||
A project's epics: top-level tickets that group others, with the progress of those
|
||||
"""
|
||||
@@ -1532,6 +1551,9 @@ type Query {
|
||||
|
||||
"""My views of the project's board, then the shared ones"""
|
||||
savedFilters(projectId: ID!): [SavedFilter!]!
|
||||
|
||||
"""What a link for clients shows, for anyone with it"""
|
||||
sharedDashboard(token: String!): SharedDashboard
|
||||
sprint(id: ID!): Sprint!
|
||||
|
||||
"""
|
||||
@@ -1707,6 +1729,50 @@ input SavedFilterCriteriaInput {
|
||||
unassigned: Boolean
|
||||
}
|
||||
|
||||
"""The project's link for clients"""
|
||||
input ShareDashboardInput {
|
||||
"""Blocks to show: flow, sprint, releases, epics, activity"""
|
||||
blocks: [String!]!
|
||||
projectId: ID!
|
||||
|
||||
"""A new secret: the old link stops working"""
|
||||
renew: Boolean
|
||||
}
|
||||
|
||||
"""
|
||||
What a link for clients shows: only the chosen blocks (the others are null)
|
||||
"""
|
||||
type SharedDashboard {
|
||||
activity: [ActivityDay!]
|
||||
blocks: [String!]!
|
||||
epics: [SharedEpic!]
|
||||
flow: [SharedFlow!]
|
||||
generatedAt: String!
|
||||
projectKey: String!
|
||||
projectName: String!
|
||||
releases: [ReleaseForecast!]
|
||||
sprint: SprintPulse
|
||||
}
|
||||
|
||||
"""An open epic and how far it got"""
|
||||
type SharedEpic {
|
||||
done: Int!
|
||||
dueDate: String
|
||||
key: String!
|
||||
percent: Int!
|
||||
title: String!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
"""Tickets in one status"""
|
||||
type SharedFlow {
|
||||
"""A colour name of the project settings"""
|
||||
color: String!
|
||||
count: Int!
|
||||
name: String!
|
||||
status: String!
|
||||
}
|
||||
|
||||
"""A time-boxed iteration: the tickets the team commits to"""
|
||||
type Sprint {
|
||||
burndown: SprintBurndown!
|
||||
|
||||
Reference in New Issue
Block a user