init
This commit is contained in:
64
src/lib/jiraFieldExtractors.ts
Normal file
64
src/lib/jiraFieldExtractors.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import type { JiraIssue } from '../types/jira'
|
||||
import { buildIssueIdToKeyMap, resolveParentIssueKey } from './parentResolve'
|
||||
|
||||
/** ID du champ Story Points (souvent `customfield_10028` — à vérifier dans Jira). */
|
||||
export function getStoryPointsFieldId(): string {
|
||||
return import.meta.env.VITE_JIRA_STORY_POINTS_FIELD?.trim() || 'customfield_10028'
|
||||
}
|
||||
|
||||
function coerceNumber(v: unknown): number | null {
|
||||
if (v == null || v === '') return null
|
||||
if (typeof v === 'number' && Number.isFinite(v)) return v
|
||||
if (typeof v === 'string') {
|
||||
const n = Number(v)
|
||||
return Number.isFinite(n) ? n : null
|
||||
}
|
||||
if (typeof v === 'object' && v !== null && 'value' in v) {
|
||||
return coerceNumber((v as { value: unknown }).value)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Story Points bruts depuis le champ custom Jira (nombre, chaîne, ou `{ value }`). */
|
||||
export function getStoryPoints(issue: JiraIssue): number {
|
||||
const id = getStoryPointsFieldId()
|
||||
const raw = (issue.fields as Record<string, unknown>)[id]
|
||||
const n = coerceNumber(raw)
|
||||
return n ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Reste « en unités » comme dans ton export : secondes / 27 000
|
||||
* (27 000 s ≈ 7,5 h — une journée-type Atlassian).
|
||||
*/
|
||||
export function getRemainingEstimateUnits(issue: JiraIssue): number {
|
||||
const sec = issue.fields.timetracking?.remainingEstimateSeconds
|
||||
if (sec == null || !Number.isFinite(sec)) return 0
|
||||
const v = sec / 27000
|
||||
return Number.isFinite(v) ? v : 0
|
||||
}
|
||||
|
||||
/** Objet plat proche de ton ancien `issues.map` + clé parent résolue pour le debug. */
|
||||
export function toTicketRow(issue: JiraIssue, allIssues: JiraIssue[]): {
|
||||
key: string
|
||||
summary: string
|
||||
sp: number
|
||||
remaining: number
|
||||
status: string
|
||||
issuetype: string
|
||||
assignee: string
|
||||
parentKey?: string
|
||||
} {
|
||||
const idToKey = buildIssueIdToKeyMap(allIssues)
|
||||
const parentKey = resolveParentIssueKey(issue, idToKey)
|
||||
return {
|
||||
key: issue.key,
|
||||
summary: issue.fields.summary,
|
||||
sp: getStoryPoints(issue),
|
||||
remaining: getRemainingEstimateUnits(issue),
|
||||
status: issue.fields.status?.name ?? 'Inconnu',
|
||||
issuetype: issue.fields.issuetype?.name ?? 'Inconnu',
|
||||
assignee: issue.fields.assignee?.displayName ?? 'Inconnu',
|
||||
...(parentKey ? { parentKey } : {}),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user