Calcule du temps estimé des Milestone et Epic
This commit is contained in:
@@ -186,7 +186,11 @@
|
||||
<div class="row g-2">
|
||||
<div [class]="isEpicIssue ? 'col-12' : 'col-6'">
|
||||
<label class="field-label">Temps estimé (h)</label>
|
||||
<input aria-label="Temps estimé" class="form-control form-control-sm" type="number" min="0" step="0.5" [(ngModel)]="estimatedTimeValue" (blur)="saveIssue()" />
|
||||
@if (isEpicIssue) {
|
||||
<div class="form-control form-control-sm bg-body-secondary text-secondary">{{ epicEstimatedTime !== null ? epicEstimatedTime : '—' }}</div>
|
||||
} @else {
|
||||
<input aria-label="Temps estimé" class="form-control form-control-sm" type="number" min="0" step="0.5" [(ngModel)]="estimatedTimeValue" (blur)="saveIssue()" />
|
||||
}
|
||||
</div>
|
||||
@if (!isEpicIssue) {
|
||||
<div class="col-6">
|
||||
|
||||
@@ -580,6 +580,39 @@ describe('IssueDetail — existing issue', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('epicEstimatedTime', () => {
|
||||
beforeEach(() => {
|
||||
(component as any).issue.type = 'Epic';
|
||||
(component as any).issue.name = 'Test Epic';
|
||||
});
|
||||
|
||||
it('returns null when there are no child issues', () => {
|
||||
expect((component as any).epicEstimatedTime).toBeNull();
|
||||
});
|
||||
|
||||
it('returns null when all children have null estimatedTime', () => {
|
||||
store.upsert(makeIssue({ id: 200, epic: 'Test Epic', estimatedTime: null }));
|
||||
expect((component as any).epicEstimatedTime).toBeNull();
|
||||
});
|
||||
|
||||
it('returns the sum of children estimatedTime', () => {
|
||||
store.upsert(makeIssue({ id: 200, epic: 'Test Epic', estimatedTime: 8 }));
|
||||
store.upsert(makeIssue({ id: 201, epic: 'Test Epic', estimatedTime: 4 }));
|
||||
expect((component as any).epicEstimatedTime).toBe(12);
|
||||
});
|
||||
|
||||
it('ignores children with null estimatedTime in the sum', () => {
|
||||
store.upsert(makeIssue({ id: 200, epic: 'Test Epic', estimatedTime: 8 }));
|
||||
store.upsert(makeIssue({ id: 201, epic: 'Test Epic', estimatedTime: null }));
|
||||
expect((component as any).epicEstimatedTime).toBe(8);
|
||||
});
|
||||
|
||||
it('includes children linked via dependsOnIds', () => {
|
||||
store.upsert(makeIssue({ id: 200, dependsOnIds: [1], estimatedTime: 6 }));
|
||||
expect((component as any).epicEstimatedTime).toBe(6);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create-in-epic flow', () => {
|
||||
beforeEach(() => {
|
||||
(component as any).issue.type = 'Epic';
|
||||
|
||||
@@ -150,6 +150,13 @@ export class IssueDetail {
|
||||
this.issue.type = value;
|
||||
}
|
||||
|
||||
protected get epicEstimatedTime(): number | null {
|
||||
const times = this.composedIssues
|
||||
.filter((i): i is IssueEntity & { estimatedTime: number } => i.estimatedTime !== null)
|
||||
.map((i) => i.estimatedTime);
|
||||
return times.length === 0 ? null : times.reduce((a, b) => a + b, 0);
|
||||
}
|
||||
|
||||
protected get epicIssues(): IssueEntity[] {
|
||||
return this.issues().filter((issue) => issue.type === 'Epic');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user