feat: estimate tickets and see the team's velocity
Story points can be set on the ticket page and when creating a ticket, and show on cards, column headers, subtasks and the backlog. The Sprints tab charts the points finished per closed sprint and warns when a planned sprint holds more than the recent average. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@ import {
|
||||
matches,
|
||||
mentionQuery,
|
||||
mentionSegments,
|
||||
POINT_SCALE,
|
||||
ReleaseStatus,
|
||||
} from '@task-stream/web/tracker/domain';
|
||||
import {
|
||||
@@ -51,6 +52,7 @@ import {
|
||||
initials,
|
||||
LINK,
|
||||
options,
|
||||
pointOptions,
|
||||
PRIORITY,
|
||||
statusLook,
|
||||
timeAgo,
|
||||
@@ -248,7 +250,17 @@ const MAX_FILE_BYTES = 25 * 1024 * 1024;
|
||||
</h2>
|
||||
@if (facade.children().length) {
|
||||
<pi-progress-bar
|
||||
[label]="facade.childProgress().percent + '% terminado'"
|
||||
[label]="
|
||||
facade.childProgress().percent +
|
||||
'% terminado' +
|
||||
(facade.childProgress().storyPoints
|
||||
? ' · ' +
|
||||
facade.childProgress().finishedStoryPoints +
|
||||
' de ' +
|
||||
facade.childProgress().storyPoints +
|
||||
' puntos'
|
||||
: '')
|
||||
"
|
||||
[value]="facade.childProgress().percent"
|
||||
/>
|
||||
<ul class="ts-children">
|
||||
@@ -618,6 +630,14 @@ const MAX_FILE_BYTES = 25 * 1024 * 1024;
|
||||
>
|
||||
<pi-label>Prioridad</pi-label>
|
||||
</pi-select-field>
|
||||
<pi-select-field
|
||||
[options]="pointsOptions()"
|
||||
[disabled]="!project.canContribute()"
|
||||
[value]="issue.storyPoints === null ? '' : '' + issue.storyPoints"
|
||||
(valueChange)="update({ storyPoints: $event ? +$event : null })"
|
||||
>
|
||||
<pi-label>Estimación</pi-label>
|
||||
</pi-select-field>
|
||||
<pi-select-field
|
||||
[options]="areaOptions()"
|
||||
[disabled]="!project.canContribute()"
|
||||
@@ -801,6 +821,9 @@ export class IssuePage {
|
||||
);
|
||||
});
|
||||
protected readonly priorityOptions = options(PRIORITY);
|
||||
protected readonly pointsOptions = computed(() =>
|
||||
pointOptions(POINT_SCALE, this.facade.issue()?.storyPoints ?? null),
|
||||
);
|
||||
/** Active values, plus the ticket's own even if archived since. */
|
||||
protected readonly typeOptions = computed<PiSelectFieldOption<string>[]>(
|
||||
() => {
|
||||
@@ -964,6 +987,7 @@ export class IssuePage {
|
||||
type?: string;
|
||||
priority?: IssuePriority;
|
||||
area?: string | null;
|
||||
storyPoints?: number | null;
|
||||
}): void {
|
||||
this.facade.update(changes);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user