mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
fix(labs): mark un-linked lab groups and bridge biomarker detail to source reports
- Lab groups not backfilled to a catalog biomarker now carry a muted 'not linked to a biomarker yet' affordance in both list and card views, so an inert row no longer reads as a broken link next to clickable neighbours. - The biomarker detail page links to the document vault filtered to lab-result reports (gated on the documents module), giving a path from a value to its source scans. A per-value document relation remains a data-model follow-up.
This commit is contained in:
1 parent
e5ca125dfb
commit
1c57da7d44
8 files changed
+52
-7
No files matched your search
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "PDF-Scannen benötigt einen Claude-Bildanbieter; lade stattdessen ein Foto hoch."
|
||||
},
|
||||
"loadMoreReadings": "Weitere Werte laden",
|
||||
"documentsLink": "Befund-Dokumente"
|
||||
"documentsLink": "Befund-Dokumente",
|
||||
"notLinkedYet": "Noch keinem Biomarker zugeordnet"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "PDF scanning needs a Claude vision provider; upload a photo instead."
|
||||
},
|
||||
"loadMoreReadings": "Load more readings",
|
||||
"documentsLink": "Lab report documents"
|
||||
"documentsLink": "Lab report documents",
|
||||
"notLinkedYet": "Not linked to a biomarker yet"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "El escaneo de PDF necesita un proveedor de visión de Claude; sube una foto en su lugar."
|
||||
},
|
||||
"loadMoreReadings": "Cargar más mediciones",
|
||||
"documentsLink": "Documentos de resultados"
|
||||
"documentsLink": "Documentos de resultados",
|
||||
"notLinkedYet": "Aún no vinculado a un biomarcador"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "Le scan PDF nécessite un fournisseur de vision Claude ; importez plutôt une photo."
|
||||
},
|
||||
"loadMoreReadings": "Charger plus de mesures",
|
||||
"documentsLink": "Documents de résultats"
|
||||
"documentsLink": "Documents de résultats",
|
||||
"notLinkedYet": "Pas encore lié à un biomarqueur"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "La scansione PDF richiede un provider di visione Claude; carica invece una foto."
|
||||
},
|
||||
"loadMoreReadings": "Carica altre misurazioni",
|
||||
"documentsLink": "Documenti dei referti"
|
||||
"documentsLink": "Documenti dei referti",
|
||||
"notLinkedYet": "Non ancora collegato a un biomarcatore"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
+2
-1
@@ -7383,7 +7383,8 @@
|
||||
"pdfNeedsAnthropic": "Skanowanie PDF wymaga dostawcy wizji Claude; prześlij zamiast tego zdjęcie."
|
||||
},
|
||||
"loadMoreReadings": "Wczytaj więcej pomiarów",
|
||||
"documentsLink": "Dokumenty wyników badań"
|
||||
"documentsLink": "Dokumenty wyników badań",
|
||||
"notLinkedYet": "Jeszcze niepowiązane z biomarkerem"
|
||||
},
|
||||
"modules": {
|
||||
"cycle": {
|
||||
|
||||
@@ -9,9 +9,17 @@ import {
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
import { FlaskConical, ListOrdered, Pencil, Plus } from "lucide-react";
|
||||
import {
|
||||
ArrowRight,
|
||||
FlaskConical,
|
||||
FolderOpen,
|
||||
ListOrdered,
|
||||
Pencil,
|
||||
Plus,
|
||||
} from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { DeleteButton } from "@/components/data-list";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
@@ -84,6 +92,7 @@ const READINGS_PAGE_SIZE = 200;
|
||||
* it. Mirrors the measurement-detail layout.
|
||||
*/
|
||||
export function LabBiomarkerDetail({ biomarkerId }: { biomarkerId: string }) {
|
||||
const { user } = useAuth();
|
||||
const { t } = useTranslations();
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
@@ -367,6 +376,22 @@ export function LabBiomarkerDetail({ biomarkerId }: { biomarkerId: string }) {
|
||||
catalog-less marker still carries a description. */}
|
||||
<p className="text-foreground text-sm leading-relaxed">{description}</p>
|
||||
|
||||
{/* Bridge to the source report PDFs. There is no per-value document
|
||||
relation in the data model yet, so this links to the vault filtered
|
||||
to lab-result documents rather than the exact scan behind one value.
|
||||
Only when the documents module is enabled. */}
|
||||
{user?.modules?.inboundDocuments ? (
|
||||
<Link
|
||||
href="/documents?kind=LAB_RESULT"
|
||||
data-slot="lab-biomarker-documents-link"
|
||||
className="text-muted-foreground hover:text-foreground focus-visible:ring-ring/50 inline-flex items-center gap-1.5 rounded-md text-sm transition-colors focus-visible:ring-[3px] focus-visible:outline-none"
|
||||
>
|
||||
<FolderOpen className="size-4" aria-hidden="true" />
|
||||
{t("labs.documentsLink")}
|
||||
<ArrowRight className="size-3.5" aria-hidden="true" />
|
||||
</Link>
|
||||
) : null}
|
||||
|
||||
{isLoading ? (
|
||||
<Card>
|
||||
<CardContent>
|
||||
|
||||
@@ -230,11 +230,17 @@ export function LabList({ onAddFirst }: { onAddFirst?: () => void } = {}) {
|
||||
<ChevronRight className="text-muted-foreground h-4 w-4 shrink-0" />
|
||||
</Link>
|
||||
) : (
|
||||
// Un-linked group (not backfilled to a catalog biomarker):
|
||||
// render inert but say so, so it doesn't read as a broken
|
||||
// link next to its clickable neighbours.
|
||||
<div className="flex min-w-0 flex-1 items-center gap-3">
|
||||
{inner}
|
||||
<LabTrendSparkline
|
||||
values={group.readings.map((r) => r.value)}
|
||||
/>
|
||||
<span className="text-muted-foreground shrink-0 text-xs italic">
|
||||
{t("labs.notLinkedYet")}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -319,6 +325,14 @@ export function LabList({ onAddFirst }: { onAddFirst?: () => void } = {}) {
|
||||
values={group.readings.map((r) => r.value)}
|
||||
/>
|
||||
</div>
|
||||
{/* Un-linked group: the header renders no link, so name the
|
||||
reason rather than leaving a card that silently does
|
||||
nothing on tap. */}
|
||||
{!group.biomarkerId ? (
|
||||
<p className="text-muted-foreground text-xs italic">
|
||||
{t("labs.notLinkedYet")}
|
||||
</p>
|
||||
) : null}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</li>
|
||||
|
||||
Reference in new issue
Block a user