feat(ST-507): show code badges on cards, lists and dialogs across the app

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-04-26 20:36:59 +02:00
parent 66063f035a
commit b71eb53fa8
15 changed files with 122 additions and 38 deletions

View file

@ -35,6 +35,7 @@ export default async function ProductBacklogPage({ params }: Props) {
orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }],
select: {
id: true,
code: true,
title: true,
description: true,
acceptance_criteria: true,
@ -87,7 +88,7 @@ export default async function ProductBacklogPage({ params }: Props) {
left={
<PbiList
productId={id}
pbis={pbis.map((p: (typeof pbis)[number]) => ({ id: p.id, title: p.title, priority: p.priority, description: p.description }))}
pbis={pbis.map((p: (typeof pbis)[number]) => ({ id: p.id, code: p.code, title: p.title, priority: p.priority, description: p.description }))}
isDemo={isDemo}
/>
}

View file

@ -40,7 +40,14 @@ export default async function SoloProductPage({ params }: Props) {
},
},
include: {
story: { select: { id: true, title: true } },
story: {
select: {
id: true,
code: true,
title: true,
tasks: { select: { id: true }, orderBy: { sort_order: 'asc' } },
},
},
},
orderBy: [
{ story: { sort_order: 'asc' } },
@ -52,6 +59,7 @@ export default async function SoloProductPage({ params }: Props) {
where: { sprint_id: sprint.id, assignee_id: null },
select: {
id: true,
code: true,
title: true,
tasks: {
select: { id: true, title: true, description: true, priority: true, status: true },
@ -62,20 +70,28 @@ export default async function SoloProductPage({ params }: Props) {
}),
])
const tasks: SoloTask[] = rawTasks.map(t => ({
id: t.id,
title: t.title,
description: t.description,
implementation_plan: t.implementation_plan,
priority: t.priority,
sort_order: t.sort_order,
status: t.status as SoloTask['status'],
story_id: t.story.id,
story_title: t.story.title,
}))
const tasks: SoloTask[] = rawTasks.map(t => {
const positionInStory = t.story.tasks.findIndex(st => st.id === t.id)
const taskCode =
t.story.code && positionInStory >= 0 ? `${t.story.code}.${positionInStory + 1}` : null
return {
id: t.id,
title: t.title,
description: t.description,
implementation_plan: t.implementation_plan,
priority: t.priority,
sort_order: t.sort_order,
status: t.status as SoloTask['status'],
story_id: t.story.id,
story_code: t.story.code,
story_title: t.story.title,
task_code: taskCode,
}
})
const unassignedStories: UnassignedStory[] = rawUnassigned.map(s => ({
id: s.id,
code: s.code,
title: s.title,
tasks: s.tasks.map(t => ({
id: t.id,

View file

@ -49,6 +49,7 @@ export default async function SprintBoardPage({ params }: Props) {
const sprintStoryItems: SprintStory[] = sprintStories.map(s => ({
id: s.id,
code: s.code,
title: s.title,
priority: s.priority,
status: s.status,
@ -86,9 +87,11 @@ export default async function SprintBoardPage({ params }: Props) {
.filter(pbi => pbi.stories.length > 0)
.map(pbi => ({
id: pbi.id,
code: pbi.code,
title: pbi.title,
stories: pbi.stories.map(s => ({
id: s.id,
code: s.code,
title: s.title,
priority: s.priority,
status: s.status,