feat: a home page with life
Greeting and summary of the day, the coming week, the latest across my projects, who is online now, the week in numbers (mine and the team's, with a streak), sprints under way, «Retomar», project cards with their activity, what to pick up when nothing is mine and first steps for newcomers. REST (GET /api/me/home), GraphQL (myHome) and MCP (get_my_week). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { ActivityReadModel } from './activity.read-model';
|
||||
import { SprintPulseReadModel } from './insights.read-model';
|
||||
import { UserRefReadModel } from './user-ref.read-model';
|
||||
|
||||
/** Something on a day of my coming week. */
|
||||
export class AgendaItemReadModel {
|
||||
/** `YYYY-MM-DD`. */
|
||||
day!: string;
|
||||
/** A ticket of mine due, a sprint ending or a release planned. */
|
||||
kind!: 'ISSUE' | 'SPRINT_END' | 'RELEASE';
|
||||
projectKey!: string;
|
||||
title!: string;
|
||||
/** For tickets. */
|
||||
issueKey!: string | null;
|
||||
}
|
||||
|
||||
/** The last 7 days against the 7 before. */
|
||||
export class WeekCountReadModel {
|
||||
thisWeek!: number;
|
||||
lastWeek!: number;
|
||||
}
|
||||
|
||||
/** Tickets finished by the teams of my projects. */
|
||||
export class TeamWeekReadModel extends WeekCountReadModel {
|
||||
/** The last 14 days, oldest first. */
|
||||
perDay!: number[];
|
||||
}
|
||||
|
||||
/** Tickets I finished (they were mine when they reached DONE). */
|
||||
export class MyWeekReadModel extends WeekCountReadModel {
|
||||
/** Days in a row, up to today (or yesterday), with at least one. */
|
||||
streak!: number;
|
||||
}
|
||||
|
||||
/** A sprint under way in one of my projects. */
|
||||
export class HomeSprintReadModel {
|
||||
projectKey!: string;
|
||||
projectName!: string;
|
||||
sprint!: SprintPulseReadModel;
|
||||
}
|
||||
|
||||
/** What a project's card on the home page shows besides its name. */
|
||||
export class HomeProjectReadModel {
|
||||
projectId!: string;
|
||||
open!: number;
|
||||
overdue!: number;
|
||||
/** Activity per day, the last 14 days, oldest first. */
|
||||
activity!: number[];
|
||||
sprint!: { name: string; percent: number; behind: boolean } | null;
|
||||
}
|
||||
|
||||
/** Something worth doing when nothing is assigned to me. */
|
||||
export class SuggestionReadModel {
|
||||
kind!: 'UNASSIGNED' | 'PROPOSALS' | 'QA_WAITING';
|
||||
projectKey!: string;
|
||||
count!: number;
|
||||
}
|
||||
|
||||
/** The first things to do in TaskStream, done or not. */
|
||||
export class FirstStepsReadModel {
|
||||
project!: boolean;
|
||||
invited!: boolean;
|
||||
ticket!: boolean;
|
||||
calendar!: boolean;
|
||||
}
|
||||
|
||||
/** Someone of my projects on a ticket right now. */
|
||||
export class OnlineReadModel {
|
||||
user!: UserRefReadModel;
|
||||
projectKey!: string;
|
||||
issueKey!: string | null;
|
||||
issueTitle!: string | null;
|
||||
editing!: boolean;
|
||||
at!: string;
|
||||
}
|
||||
|
||||
/** Everything the home page shows beyond «my work». */
|
||||
export class HomeReadModel {
|
||||
agenda!: AgendaItemReadModel[];
|
||||
/** Newest first, across my projects. */
|
||||
activity!: ActivityReadModel[];
|
||||
team!: TeamWeekReadModel;
|
||||
me!: MyWeekReadModel;
|
||||
sprints!: HomeSprintReadModel[];
|
||||
projects!: HomeProjectReadModel[];
|
||||
suggestions!: SuggestionReadModel[];
|
||||
firstSteps!: FirstStepsReadModel;
|
||||
online!: OnlineReadModel[];
|
||||
}
|
||||
@@ -10,3 +10,4 @@ export * from './notification.read-model';
|
||||
export * from './saved-filter.read-model';
|
||||
export * from './sprint.read-model';
|
||||
export * from './insights.read-model';
|
||||
export * from './home.read-model';
|
||||
|
||||
Reference in New Issue
Block a user