* docs: plan load render workspace alignment * fix: normalize workspace status hydration * fix: avoid duplicate backlog hydration load * refactor: use sprint store active story * refactor: migrate solo to workspace store * chore: stabilize verification ignores
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import {
|
|
pbiStatusFromApi,
|
|
pbiStatusToApi,
|
|
storyStatusFromApi,
|
|
taskStatusFromApi,
|
|
} from '@/lib/task-status'
|
|
import type {
|
|
BacklogPbi,
|
|
BacklogStory,
|
|
BacklogTask,
|
|
ProductBacklogSnapshot,
|
|
TaskDetail,
|
|
} from '@/stores/product-workspace/types'
|
|
import type {
|
|
SprintWorkspaceSnapshot,
|
|
SprintWorkspaceStory,
|
|
SprintWorkspaceTask,
|
|
SprintWorkspaceTaskDetail,
|
|
} from '@/stores/sprint-workspace/types'
|
|
|
|
export function normalizePbiStatusForStore(status: string): BacklogPbi['status'] {
|
|
const dbStatus = pbiStatusFromApi(status)
|
|
return dbStatus ? pbiStatusToApi(dbStatus) : (status as BacklogPbi['status'])
|
|
}
|
|
|
|
export function normalizeStoryStatusForStore(status: string): string {
|
|
return storyStatusFromApi(status) ?? status
|
|
}
|
|
|
|
export function normalizeTaskStatusForStore(status: string): string {
|
|
return taskStatusFromApi(status) ?? status
|
|
}
|
|
|
|
export function normalizeBacklogPbi<T extends BacklogPbi>(pbi: T): T {
|
|
const status = normalizePbiStatusForStore(pbi.status)
|
|
return status === pbi.status ? pbi : { ...pbi, status }
|
|
}
|
|
|
|
export function normalizeBacklogStory<T extends BacklogStory>(story: T): T {
|
|
const status = normalizeStoryStatusForStore(story.status)
|
|
return status === story.status ? story : { ...story, status }
|
|
}
|
|
|
|
export function normalizeBacklogTask<T extends BacklogTask | TaskDetail>(task: T): T {
|
|
const status = normalizeTaskStatusForStore(task.status)
|
|
return status === task.status ? task : { ...task, status }
|
|
}
|
|
|
|
export function normalizeSprintStory<T extends SprintWorkspaceStory>(story: T): T {
|
|
const status = normalizeStoryStatusForStore(story.status)
|
|
return status === story.status ? story : { ...story, status }
|
|
}
|
|
|
|
export function normalizeSprintTask<T extends SprintWorkspaceTask | SprintWorkspaceTaskDetail>(
|
|
task: T,
|
|
): T {
|
|
const status = normalizeTaskStatusForStore(task.status)
|
|
return status === task.status ? task : { ...task, status }
|
|
}
|
|
|
|
export function normalizeProductBacklogSnapshot(
|
|
snapshot: ProductBacklogSnapshot,
|
|
): ProductBacklogSnapshot {
|
|
return {
|
|
...snapshot,
|
|
pbis: snapshot.pbis.map(normalizeBacklogPbi),
|
|
storiesByPbi: mapRecordLists(snapshot.storiesByPbi, normalizeBacklogStory),
|
|
tasksByStory: mapRecordLists(snapshot.tasksByStory, normalizeBacklogTask),
|
|
}
|
|
}
|
|
|
|
export function normalizeSprintWorkspaceSnapshot(
|
|
snapshot: SprintWorkspaceSnapshot,
|
|
): SprintWorkspaceSnapshot {
|
|
return {
|
|
...snapshot,
|
|
stories: snapshot.stories.map(normalizeSprintStory),
|
|
tasksByStory: mapRecordLists(snapshot.tasksByStory, normalizeSprintTask),
|
|
}
|
|
}
|
|
|
|
function mapRecordLists<T>(record: Record<string, T[]>, normalize: (item: T) => T): Record<string, T[]> {
|
|
const next: Record<string, T[]> = {}
|
|
for (const [id, list] of Object.entries(record)) {
|
|
next[id] = list.map(normalize)
|
|
}
|
|
return next
|
|
}
|