init
This commit is contained in:
32
src/lib/milestoneStatus.ts
Normal file
32
src/lib/milestoneStatus.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import type { StoryGroup } from '../types/jira'
|
||||
import type { Milestone } from './dashboardConfig'
|
||||
import { storyProgressPercent } from './storyMetrics'
|
||||
|
||||
/** Pour les jalons : story sans sous-tâche = considérée comme « livrée » côté sous-tâches. */
|
||||
function storyCompletionForMilestone(g: StoryGroup): number {
|
||||
if (g.subtasks.length === 0) return 100
|
||||
return storyProgressPercent(g.subtasks)
|
||||
}
|
||||
|
||||
function endOfDay(isoDate: string): Date {
|
||||
const d = new Date(isoDate + 'T12:00:00')
|
||||
d.setHours(23, 59, 59, 999)
|
||||
return d
|
||||
}
|
||||
|
||||
/** Jalon en retard : date dépassée et au moins une story concernée n’est pas à 100 %. */
|
||||
export function isMilestoneLate(m: Milestone, groups: StoryGroup[]): boolean {
|
||||
if (groups.length === 0) return false
|
||||
const deadline = endOfDay(m.date)
|
||||
if (new Date() <= deadline) return false
|
||||
const keys =
|
||||
m.linkedStoryKeys && m.linkedStoryKeys.length > 0
|
||||
? m.linkedStoryKeys
|
||||
: groups.map((g) => g.story.key)
|
||||
for (const key of keys) {
|
||||
const g = groups.find((x) => x.story.key === key)
|
||||
if (!g) continue
|
||||
if (storyCompletionForMilestone(g) < 100) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user