feat(PBI-49): add BEM sub-element data-debug-id to components/ideas/*
This commit is contained in:
parent
82c0341ff3
commit
0b9f8708ab
8 changed files with 35 additions and 23 deletions
|
|
@ -144,7 +144,7 @@ export function IdeaDetailLayout({
|
|||
</Link>
|
||||
|
||||
{/* Header */}
|
||||
<header className="flex flex-wrap items-start justify-between gap-4">
|
||||
<header className="flex flex-wrap items-start justify-between gap-4" data-debug-id="idea-detail-layout__header">
|
||||
<div className="space-y-1">
|
||||
<p className="font-mono text-xs text-muted-foreground">{idea.code}</p>
|
||||
<h1 className="text-2xl font-medium text-foreground">{idea.title}</h1>
|
||||
|
|
@ -184,7 +184,7 @@ export function IdeaDetailLayout({
|
|||
<IdeaPbiLinkCard idea={idea} isDemo={isDemo} />
|
||||
|
||||
{/* Tab-switcher */}
|
||||
<nav className="border-b border-input flex gap-1">
|
||||
<nav className="border-b border-input flex gap-1" data-debug-id="idea-detail-layout__main">
|
||||
{([
|
||||
{ key: 'idee' as TabKey, label: 'Idee', disabled: false, hasContent: true },
|
||||
{ key: 'grill' as TabKey, label: 'Grill', disabled: !grill_md, hasContent: !!grill_md },
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
|||
return (
|
||||
<div className="space-y-4" {...debugProps('idea-list', 'IdeaList', 'components/ideas/idea-list.tsx')}>
|
||||
{/* Top-bar: search + nieuw-knop */}
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<div className="flex flex-wrap items-center gap-3" data-debug-id="idea-list__toolbar">
|
||||
<Input
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
|
|
@ -403,7 +403,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
|||
: 'Geen ideeën die aan de filters voldoen.'}
|
||||
</p>
|
||||
) : (
|
||||
<Table>
|
||||
<Table data-debug-id="idea-list__items">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-24"><SortHeader col="code" label="Code" sortKey={sortKey} sortDir={sortDir} onSort={handleSort} /></TableHead>
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ export function IdeaMdEditor({ ideaId, kind, initialValue, onCancel }: Props) {
|
|||
onKeyDown={onKeyDown}
|
||||
rows={24}
|
||||
className="font-mono text-sm leading-relaxed"
|
||||
data-debug-id="idea-md-editor__textarea"
|
||||
placeholder={
|
||||
kind === 'grill'
|
||||
? '# Idee — ...\n## Scope\n...'
|
||||
|
|
@ -160,6 +161,7 @@ export function IdeaMdEditor({ ideaId, kind, initialValue, onCancel }: Props) {
|
|||
size="sm"
|
||||
onClick={save}
|
||||
disabled={!dirty || submitting || (errors.length > 0 && kind === 'plan')}
|
||||
data-debug-id="idea-md-editor__save"
|
||||
>
|
||||
<Save className="size-3.5 mr-1" />
|
||||
Opslaan
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export function IdeaPbiLinkCard({ idea, isDemo }: Props) {
|
|||
return (
|
||||
<div className="rounded-md border border-status-done/30 bg-status-done/10 p-4 flex items-center gap-3" {...debugProps('idea-pbi-link-card', 'IdeaPbiLinkCard', 'components/ideas/idea-pbi-link-card.tsx')}>
|
||||
<div className="flex-1">
|
||||
<p className="text-xs uppercase tracking-wide text-status-done font-medium">
|
||||
<p className="text-xs uppercase tracking-wide text-status-done font-medium" data-debug-id="idea-pbi-link-card__title">
|
||||
Gepland
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
|
|
@ -38,6 +38,7 @@ export function IdeaPbiLinkCard({ idea, isDemo }: Props) {
|
|||
<Link
|
||||
href={`/products/${idea.product_id}`}
|
||||
className="font-medium text-status-done hover:underline inline-flex items-center gap-1"
|
||||
data-debug-id="idea-pbi-link-card__link"
|
||||
>
|
||||
{idea.pbi.code} — {idea.pbi.title}
|
||||
<ExternalLink className="size-3" />
|
||||
|
|
|
|||
|
|
@ -149,24 +149,28 @@ export function IdeaRowActions({ idea, isDemo, onArchive }: IdeaRowActionsProps)
|
|||
)}
|
||||
|
||||
{/* Grill Me */}
|
||||
<ActionButton
|
||||
label="Grill"
|
||||
icon={<Flame className="size-3.5" />}
|
||||
enabled={grillEnabled}
|
||||
blockedReason={grillBlockedReason}
|
||||
isDemo={isDemo}
|
||||
onClick={() => runStart(startGrillJobAction)}
|
||||
/>
|
||||
<span data-debug-id="idea-row-actions__grill">
|
||||
<ActionButton
|
||||
label="Grill"
|
||||
icon={<Flame className="size-3.5" />}
|
||||
enabled={grillEnabled}
|
||||
blockedReason={grillBlockedReason}
|
||||
isDemo={isDemo}
|
||||
onClick={() => runStart(startGrillJobAction)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{/* Make Plan */}
|
||||
<ActionButton
|
||||
label="Plan"
|
||||
icon={<Sparkles className="size-3.5" />}
|
||||
enabled={makePlanEnabled}
|
||||
blockedReason={makePlanBlockedReason}
|
||||
isDemo={isDemo}
|
||||
onClick={() => runStart(startMakePlanJobAction)}
|
||||
/>
|
||||
<span data-debug-id="idea-row-actions__plan">
|
||||
<ActionButton
|
||||
label="Plan"
|
||||
icon={<Sparkles className="size-3.5" />}
|
||||
enabled={makePlanEnabled}
|
||||
blockedReason={makePlanBlockedReason}
|
||||
isDemo={isDemo}
|
||||
onClick={() => runStart(startMakePlanJobAction)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{/* Materialiseer */}
|
||||
<ActionButton
|
||||
|
|
@ -218,6 +222,7 @@ export function IdeaRowActions({ idea, isDemo, onArchive }: IdeaRowActionsProps)
|
|||
disabled={isDemo || pending}
|
||||
aria-label="Archiveer idee"
|
||||
title="Archiveer"
|
||||
data-debug-id="idea-row-actions__delete"
|
||||
>
|
||||
<Archive className="size-4" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export function IdeaSyncTab({ data }: Props) {
|
|||
return (
|
||||
<div className="space-y-4" {...debugProps('idea-sync-tab', 'IdeaSyncTab', 'components/ideas/idea-sync-tab.tsx')}>
|
||||
{/* Header: PBI-link + PR-status */}
|
||||
<div className="flex flex-wrap items-center gap-3 rounded-md border border-border bg-surface-container p-3">
|
||||
<div className="flex flex-wrap items-center gap-3 rounded-md border border-border bg-surface-container p-3" data-debug-id="idea-sync-tab__header">
|
||||
<a
|
||||
href={`/backlog/${pbi.id}`}
|
||||
className="font-mono text-sm text-primary hover:underline"
|
||||
|
|
@ -119,6 +119,7 @@ export function IdeaSyncTab({ data }: Props) {
|
|||
</div>
|
||||
|
||||
{/* Stories */}
|
||||
<div data-debug-id="idea-sync-tab__items">
|
||||
{pbi.stories.length === 0 && (
|
||||
<p className="text-sm text-muted-foreground italic">
|
||||
Deze PBI heeft nog geen stories.
|
||||
|
|
@ -229,6 +230,7 @@ export function IdeaSyncTab({ data }: Props) {
|
|||
</div>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ export function IdeaTimeline({
|
|||
Nog geen activiteit op dit idee.
|
||||
</p>
|
||||
) : (
|
||||
<ol className="border-l-2 border-input pl-4 space-y-3 ml-2">
|
||||
<ol className="border-l-2 border-input pl-4 space-y-3 ml-2" data-debug-id="idea-timeline__items">
|
||||
{merged.map((entry, i) => {
|
||||
// Expliciete locale + format om SSR/CSR hydration-mismatch te voorkomen
|
||||
// (server-locale verschilde van browser-locale).
|
||||
|
|
|
|||
|
|
@ -59,12 +59,14 @@ export function UserChatInput({ ideaId, isDemo = false }: Props) {
|
|||
rows={3}
|
||||
placeholder="Bijv. Waarom is gekozen voor X in plaats van Y?"
|
||||
disabled={pending}
|
||||
data-debug-id="user-chat-input__textarea"
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={pending || !text.trim()}
|
||||
onClick={submit}
|
||||
data-debug-id="user-chat-input__submit"
|
||||
>
|
||||
<Send className="size-4" />
|
||||
{pending ? 'Bezig…' : 'Verzend'}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue