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:
@@ -1305,3 +1305,46 @@ export class HomeDto {
|
||||
@ApiProperty({ type: FirstStepsDto }) firstSteps!: FirstStepsDto;
|
||||
@ApiProperty({ type: [OnlineDto] }) online!: OnlineDto[];
|
||||
}
|
||||
|
||||
export class DashboardShareDto {
|
||||
@ApiProperty() projectId!: string;
|
||||
@ApiProperty({ description: 'Secret of the link /share/{token}' })
|
||||
token!: string;
|
||||
@ApiProperty({ type: [String], example: ['flow', 'sprint', 'releases'] })
|
||||
blocks!: string[];
|
||||
@ApiProperty() createdAt!: string;
|
||||
}
|
||||
|
||||
export class SharedFlowDto {
|
||||
@ApiProperty() status!: string;
|
||||
@ApiProperty() name!: string;
|
||||
@ApiProperty({ description: 'A colour name of the project settings' })
|
||||
color!: string;
|
||||
@ApiProperty() count!: number;
|
||||
}
|
||||
|
||||
export class SharedEpicDto {
|
||||
@ApiProperty() key!: string;
|
||||
@ApiProperty() title!: string;
|
||||
@ApiProperty({ type: String, nullable: true }) dueDate!: string | null;
|
||||
@ApiProperty() done!: number;
|
||||
@ApiProperty() total!: number;
|
||||
@ApiProperty() percent!: number;
|
||||
}
|
||||
|
||||
export class SharedDashboardDto {
|
||||
@ApiProperty() projectKey!: string;
|
||||
@ApiProperty() projectName!: string;
|
||||
@ApiProperty() generatedAt!: string;
|
||||
@ApiProperty({ type: [String] }) blocks!: string[];
|
||||
@ApiProperty({ type: [SharedFlowDto], nullable: true })
|
||||
flow!: SharedFlowDto[] | null;
|
||||
@ApiProperty({ type: SprintPulseDto, nullable: true })
|
||||
sprint!: SprintPulseDto | null;
|
||||
@ApiProperty({ type: [ReleaseForecastDto], nullable: true })
|
||||
releases!: ReleaseForecastDto[] | null;
|
||||
@ApiProperty({ type: [SharedEpicDto], nullable: true })
|
||||
epics!: SharedEpicDto[] | null;
|
||||
@ApiProperty({ type: [ActivityDayDto], nullable: true })
|
||||
activity!: ActivityDayDto[] | null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user