refactor(ui): CardHeading primitive for icon+title card/dialog headings (DRY pattern sweep)
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
CI / integration (push) Successful in 3m10s

The icon+title v-card-title heading (d-flex align-center + gap + <v-icon size=small> +
<span>) was hand-rolled identically in 13 cards/dialogs (15 heading instances).
Consolidate to <CardHeading icon title> (components/common) with an iconColor
prop (error headings) and a default slot for trailing content (spacer+actions,
inline status chip). Adopted everywhere the pattern appears — all-or-nothing per
the hardened DRY process.

Over-DRY guard: plain text-only <v-card-title> one-liners are NOT this pattern
and stay; DownloadDetailModal leads with a status CHIP (not an icon), a different
concept, left alone. §8b: the only remaining d-flex align-center v-card-title is
that intentional variant. Catalog updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 23:22:01 -04:00
parent 4854d74c5a
commit 9deebfa133
14 changed files with 66 additions and 59 deletions
@@ -1,9 +1,6 @@
<template>
<v-card class="fc-post-maint">
<v-card-title class="d-flex align-center" style="gap: 10px;">
<v-icon icon="mdi-post-outline" size="small" />
<span>Post maintenance</span>
</v-card-title>
<CardHeading icon="mdi-post-outline" title="Post maintenance" />
<v-card-text>
<p class="fc-muted text-body-2 mb-4">
Remove <strong>bare posts</strong> post rows with no images (neither
@@ -61,6 +58,7 @@ import { ref } from 'vue'
import { useAdminStore } from '../../stores/admin.js'
import SampleNameGrid from '../common/SampleNameGrid.vue'
import CardHeading from '../common/CardHeading.vue'
const store = useAdminStore()
const preview = ref(null)