feat(rennmausakte): Hinweis-Chip für Geschwisterverpaarung in der Tierakte
Stammt ein Tier aus einer Vollgeschwister-Verpaarung (Vater und Mutter teilen dieselbe litterId), zeigt die Rennmausakte jetzt einen Chip "⚭ Geschwisterverpaarung" in der Fakten-Zeile — neben Geschlecht, Geburtsdatum und Farbschlag, in Akzentfarbe hervorgehoben (zuchtrelevant). e2e-Test: Chip erscheint für 'Inzucht Kind' (Eltern aus demselben Wurf), nicht für 'Krümel' (Eltern aus verschiedenen Würfen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,20 @@ test('Detailseite: Wurf-Feld ist ein Link zur Wurf-Detailseite (WURF-LINK)', asy
|
|||||||
await expect(page.getByRole('heading', { name: 'Wurf K' })).toBeVisible()
|
await expect(page.getByRole('heading', { name: 'Wurf K' })).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Detailseite zeigt Geschwisterverpaarungs-Hinweis nur wenn die Eltern Vollgeschwister sind (SIBLING-PAIRING)', async ({ page }) => {
|
||||||
|
skipUnlessMock()
|
||||||
|
// 'Inzucht Kind': Eltern Zwilling Bock + Zwilling Maus aus demselben Wurf
|
||||||
|
// 'w-zwillinge' → Vollgeschwister → Hinweis sichtbar.
|
||||||
|
await page.goto('/rennmaeuse/inzucht-kind')
|
||||||
|
await expect(page.getByRole('heading', { name: 'Inzucht Kind' })).toBeVisible()
|
||||||
|
await expect(page.locator('.ak-fact--sibling')).toContainText(t.detail.siblingPairing)
|
||||||
|
|
||||||
|
// 'Krümel': Eltern Fridolin × Luna aus verschiedenen Würfen → kein Hinweis.
|
||||||
|
await page.goto('/rennmaeuse/kruemel')
|
||||||
|
await expect(page.getByRole('heading', { name: 'Krümel' })).toBeVisible()
|
||||||
|
await expect(page.locator('.ak-fact--sibling')).toHaveCount(0)
|
||||||
|
})
|
||||||
|
|
||||||
test('Detailseite: Herkunft zeigt originBreeder als Text wenn kein Kontakt (WURF-LINK-Addendum)', async ({ page }) => {
|
test('Detailseite: Herkunft zeigt originBreeder als Text wenn kein Kontakt (WURF-LINK-Addendum)', async ({ page }) => {
|
||||||
skipUnlessMock()
|
skipUnlessMock()
|
||||||
// Fridolin hat originContactId=null + originBreeder='Zoohandlung Meier' → plain text, kein Link
|
// Fridolin hat originContactId=null + originBreeder='Zoohandlung Meier' → plain text, kein Link
|
||||||
|
|||||||
@@ -137,6 +137,15 @@ export default function GerbilDetailPage() {
|
|||||||
const lookup = (map: Map<string, string>, key: string | null) => (key ? (map.get(key) ?? '—') : '—')
|
const lookup = (map: Map<string, string>, key: string | null) => (key ? (map.get(key) ?? '—') : '—')
|
||||||
const storedColorName = g.colorVarietyId ? (colorName.get(g.colorVarietyId) ?? null) : null
|
const storedColorName = g.colorVarietyId ? (colorName.get(g.colorVarietyId) ?? null) : null
|
||||||
|
|
||||||
|
// Geschwisterverpaarung: Vater und Mutter dieses Tiers stammen aus demselben
|
||||||
|
// Wurf (Vollgeschwister) — erkennbar an gemeinsamer litterId der Eltern.
|
||||||
|
const isSiblingPairing =
|
||||||
|
!!father.data &&
|
||||||
|
!!mother.data &&
|
||||||
|
father.data.id !== mother.data.id &&
|
||||||
|
!!father.data.litterId &&
|
||||||
|
father.data.litterId === mother.data.litterId
|
||||||
|
|
||||||
const parentLink = (
|
const parentLink = (
|
||||||
pid: string | null,
|
pid: string | null,
|
||||||
p: Parameters<typeof gerbilName>[0] | null,
|
p: Parameters<typeof gerbilName>[0] | null,
|
||||||
@@ -204,6 +213,12 @@ export default function GerbilDetailPage() {
|
|||||||
{storedColorName}
|
{storedColorName}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{isSiblingPairing && (
|
||||||
|
<span className="ak-fact ak-fact--sibling" title={t.detail.siblingPairingTitle}>
|
||||||
|
<span aria-hidden="true">⚭</span>
|
||||||
|
{t.detail.siblingPairing}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="ak-actions">
|
<div className="ak-actions">
|
||||||
|
|||||||
@@ -139,6 +139,12 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
/* Geschwisterverpaarung: hervorgehoben, da zuchtrelevant (Inzucht). */
|
||||||
|
.ak-fact--sibling {
|
||||||
|
background: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface));
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Actions ---------- */
|
/* ---------- Actions ---------- */
|
||||||
.ak-actions {
|
.ak-actions {
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ export const de = {
|
|||||||
parentLittersEmpty: 'Keine Würfe als Elternteil erfasst.',
|
parentLittersEmpty: 'Keine Würfe als Elternteil erfasst.',
|
||||||
parentLittersRoleVater: 'Vater',
|
parentLittersRoleVater: 'Vater',
|
||||||
parentLittersRoleMutter: 'Mutter',
|
parentLittersRoleMutter: 'Mutter',
|
||||||
|
// Hinweis: Eltern dieses Tiers sind Vollgeschwister (gleicher Wurf).
|
||||||
|
siblingPairing: 'Geschwisterverpaarung',
|
||||||
|
siblingPairingTitle:
|
||||||
|
'Die Eltern dieses Tiers stammen aus demselben Wurf (Vollgeschwister).',
|
||||||
},
|
},
|
||||||
// Formular (anlegen/bearbeiten)
|
// Formular (anlegen/bearbeiten)
|
||||||
form: {
|
form: {
|
||||||
|
|||||||
Reference in New Issue
Block a user