feat(ST-507): add code input to Product, Pbi and Story forms

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

View file

@ -23,6 +23,7 @@ export interface PbiDialogPbi {
title: string
priority: number
description?: string | null
code?: string | null
}
type CreateState = { mode: 'create'; productId: string; defaultPriority?: number }
@ -101,17 +102,30 @@ export function PbiDialog({ state, onClose }: PbiDialogProps) {
{!isEdit && <input type="hidden" name="productId" value={(state as CreateState | null)?.productId ?? ''} />}
<input type="hidden" name="priority" value={priority} />
<div className="grid gap-1.5">
<label htmlFor="pbi-title" className="text-sm font-medium">Titel</label>
<Input
id="pbi-title"
ref={titleRef}
name="title"
defaultValue={pbi?.title ?? ''}
placeholder="PBI-titel…"
required
maxLength={200}
/>
<div className="grid grid-cols-[6rem_1fr] gap-3">
<div className="grid gap-1.5">
<label htmlFor="pbi-code" className="text-sm font-medium">Code</label>
<Input
id="pbi-code"
name="code"
defaultValue={pbi?.code ?? ''}
placeholder={isEdit ? '' : 'auto'}
maxLength={30}
className="font-mono text-sm"
/>
</div>
<div className="grid gap-1.5">
<label htmlFor="pbi-title" className="text-sm font-medium">Titel</label>
<Input
id="pbi-title"
ref={titleRef}
name="title"
defaultValue={pbi?.title ?? ''}
placeholder="PBI-titel…"
required
maxLength={200}
/>
</div>
</div>
<div className="grid gap-1.5">

View file

@ -124,7 +124,14 @@ export function StoryDialog({ state, onClose, isDemo = false }: StoryDialogProps
<Dialog open={!!state} onOpenChange={(open) => { if (!open) onClose() }}>
<DialogContent className="sm:max-w-lg flex flex-col gap-0 p-0 max-h-[90vh] overflow-hidden">
<DialogHeader className="px-5 pt-5 pb-4 border-b border-border shrink-0 pr-14">
<DialogTitle>{isEdit ? story!.title : 'Nieuwe story'}</DialogTitle>
<div className="flex items-start gap-2">
<DialogTitle className="flex-1">{isEdit ? story!.title : 'Nieuwe story'}</DialogTitle>
{isEdit && story!.code && (
<span className="font-mono text-[11px] text-muted-foreground border border-border rounded-md bg-surface-container px-1.5 py-0.5 shrink-0 mt-0.5">
{story!.code}
</span>
)}
</div>
{isEdit && (
<div className="flex gap-2 mt-1">
<Badge className={cn('text-xs border', PRIORITY_COLORS[priority])}>
@ -154,17 +161,30 @@ export function StoryDialog({ state, onClose, isDemo = false }: StoryDialogProps
<div className="flex-1 overflow-y-auto">
{showForm ? (
<div className="p-5 space-y-4">
<div className="space-y-1.5">
<label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Titel</label>
<Input
ref={titleRef}
name="title"
defaultValue={story?.title ?? ''}
required
maxLength={200}
className={fieldError('title') ? 'border-error' : ''}
/>
{fieldError('title') && <p className="text-xs text-error">{fieldError('title')}</p>}
<div className="grid grid-cols-[6rem_1fr] gap-3">
<div className="space-y-1.5">
<label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Code</label>
<Input
name="code"
defaultValue={story?.code ?? ''}
placeholder={isEdit ? '' : 'auto'}
maxLength={30}
className={cn('font-mono text-sm', fieldError('code') ? 'border-error' : '')}
/>
{fieldError('code') && <p className="text-xs text-error">{fieldError('code')}</p>}
</div>
<div className="space-y-1.5">
<label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Titel</label>
<Input
ref={titleRef}
name="title"
defaultValue={story?.title ?? ''}
required
maxLength={200}
className={fieldError('title') ? 'border-error' : ''}
/>
{fieldError('title') && <p className="text-xs text-error">{fieldError('title')}</p>}
</div>
</div>
<div className="space-y-1.5">