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:
@@ -11,3 +11,4 @@ export * from './saved-filter.read-model';
|
||||
export * from './sprint.read-model';
|
||||
export * from './insights.read-model';
|
||||
export * from './home.read-model';
|
||||
export * from './shared-dashboard.read-model';
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
ActivityDayReadModel,
|
||||
ReleaseForecastReadModel,
|
||||
SprintPulseReadModel,
|
||||
} from './insights.read-model';
|
||||
|
||||
/** The blocks a project can show to outsiders, in the order they are shown. */
|
||||
export const SHARED_BLOCKS = [
|
||||
'flow',
|
||||
'sprint',
|
||||
'releases',
|
||||
'epics',
|
||||
'activity',
|
||||
] as const;
|
||||
export type SharedBlock = (typeof SHARED_BLOCKS)[number];
|
||||
|
||||
/** A project's link for clients: the secret, and what it shows. */
|
||||
export class DashboardShareReadModel {
|
||||
projectId!: string;
|
||||
/** Random and long; whoever has it sees the chosen blocks. */
|
||||
token!: string;
|
||||
blocks!: SharedBlock[];
|
||||
createdAt!: string;
|
||||
}
|
||||
|
||||
/** Tickets in one status (the board's columns, archived ones left out). */
|
||||
export class SharedFlowReadModel {
|
||||
status!: string;
|
||||
name!: string;
|
||||
/** A colour name of the project's settings. */
|
||||
color!: string;
|
||||
count!: number;
|
||||
}
|
||||
|
||||
/** An open epic and how far it got: no more than its key and title. */
|
||||
export class SharedEpicReadModel {
|
||||
key!: string;
|
||||
title!: string;
|
||||
dueDate!: string | null;
|
||||
done!: number;
|
||||
total!: number;
|
||||
percent!: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* What a client sees through the link: only the chosen blocks (the others
|
||||
* are null), nothing about people or single tickets but the epics.
|
||||
*/
|
||||
export class SharedDashboardReadModel {
|
||||
projectKey!: string;
|
||||
projectName!: string;
|
||||
generatedAt!: string;
|
||||
blocks!: SharedBlock[];
|
||||
flow!: SharedFlowReadModel[] | null;
|
||||
sprint!: SprintPulseReadModel | null;
|
||||
releases!: ReleaseForecastReadModel[] | null;
|
||||
epics!: SharedEpicReadModel[] | null;
|
||||
activity!: ActivityDayReadModel[] | null;
|
||||
}
|
||||
Reference in New Issue
Block a user