diff --git a/src/app/issues/issue-detail/issue-detail.html b/src/app/issues/issue-detail/issue-detail.html index 67cbcd9..b10ecc7 100644 --- a/src/app/issues/issue-detail/issue-detail.html +++ b/src/app/issues/issue-detail/issue-detail.html @@ -105,14 +105,16 @@
-
+
-
- - -
+ @if (!isEpicIssue) { +
+ + +
+ }
diff --git a/src/app/issues/issues.css b/src/app/issues/issues.css index 7282836..13ebb0b 100644 --- a/src/app/issues/issues.css +++ b/src/app/issues/issues.css @@ -15,4 +15,13 @@ outline-offset: -2px; } +.progress-cell { + min-width: 130px; +} + +.progress-label { + min-width: 2.5rem; + text-align: right; +} + diff --git a/src/app/issues/issues.html b/src/app/issues/issues.html index 5671232..7ed0b19 100644 --- a/src/app/issues/issues.html +++ b/src/app/issues/issues.html @@ -1,3 +1,4 @@ +

Issues

@@ -6,6 +7,25 @@
+
+ + @for (type of typeOptions; track type) { + + } +
+
@@ -16,10 +36,11 @@ + - @for (issue of issues(); track issue.id) { + @for (issue of filteredIssues; track issue.id) { {{ issue.priority }} + } diff --git a/src/app/issues/issues.ts b/src/app/issues/issues.ts index d57e3b7..e5ee32d 100644 --- a/src/app/issues/issues.ts +++ b/src/app/issues/issues.ts @@ -13,6 +13,20 @@ export class Issues { private readonly issuesStore = inject(IssuesStore); protected readonly issues = this.issuesStore.issues; + protected selectedType: IssueEntity['type'] | null = null; + + protected readonly typeOptions: IssueEntity['type'][] = [ + 'Epic', 'Bug', 'Study', 'Story', 'Task', 'Technical Story', + ]; + + protected get filteredIssues(): IssueEntity[] { + if (this.selectedType === null) return this.issues(); + return this.issues().filter((i) => i.type === this.selectedType); + } + + protected selectType(type: IssueEntity['type'] | null): void { + this.selectedType = this.selectedType === type ? null : type; + } protected createIssue(): void { const nextId = this.issuesStore.getNextId(); @@ -25,6 +39,18 @@ export class Issues { this.router.navigate(['/issues', issueId]); } + protected getProgress(issue: IssueEntity): number { + if (issue.type !== 'Epic') { + return issue.progress; + } + const children = this.issues().filter( + (i) => i.id !== issue.id && (i.epic === issue.name || i.dependsOnIds.includes(issue.id)), + ); + if (children.length === 0) return 0; + const done = children.filter((i) => i.status === 'done').length; + return Math.round((done / children.length) * 100); + } + protected typeBadgeClass(type: IssueEntity['type']): string { const map: Record = { Bug: 'text-bg-danger',
Priorite Statut AssigneeProgression
{{ issue.status }} {{ issue.assignee }} +
+
+
+
+ {{ getProgress(issue) }}% +
+