Adding visual styling to details component. Adding paragraph indicator.

This commit is contained in:
Julio Ruiz 2026-05-17 10:23:08 -05:00
parent 1eb6d7df59
commit 5e69e45716
1 changed files with 36 additions and 103 deletions

View File

@ -748,13 +748,7 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
<UDashboardPanel id="estudios-ts-detail">
<UDashboardNavbar :toggle="false">
<template #leading>
<UButton
icon="i-lucide-arrow-left"
color="neutral"
variant="ghost"
class="-ms-1.5"
@click="emits('close')"
/>
<UButton icon="i-lucide-arrow-left" color="neutral" variant="ghost" class="-ms-1.5" @click="emits('close')" />
</template>
<template #title>
@ -765,14 +759,9 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
<template #right>
<UTooltip :text="isFav ? 'Quitar de mi lista' : 'Guardar en mi lista'">
<UButton
:icon="isFav ? 'i-lucide-bookmark-check' : 'i-lucide-bookmark-plus'"
:color="isFav ? 'primary' : 'neutral'"
variant="ghost"
:disabled="!document"
:aria-label="isFav ? 'Quitar de mi lista' : 'Guardar en mi lista'"
@click="onToggleFavorite"
/>
<UButton :icon="isFav ? 'i-lucide-bookmark-check' : 'i-lucide-bookmark-plus'"
:color="isFav ? 'primary' : 'neutral'" variant="ghost" :disabled="!document"
:aria-label="isFav ? 'Quitar de mi lista' : 'Guardar en mi lista'" @click="onToggleFavorite" />
</UTooltip>
</template>
</UDashboardNavbar>
@ -790,75 +779,39 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
<span class="truncate max-w-55">{{ safeLocation() }}</span>
</p>
</div>
<UButton
v-if="matchUrl"
:to="matchUrl"
target="_blank"
icon="i-lucide-external-link"
label="Ver en sitio"
color="primary"
variant="soft"
size="xs"
class="shrink-0"
/>
<UButton v-if="matchUrl" :to="matchUrl" target="_blank" icon="i-lucide-external-link" label="Ver en sitio"
color="primary" variant="soft" size="xs" class="shrink-0" />
</div>
<div v-if="fileLinks.length" class="flex flex-wrap gap-2">
<UButton
v-for="(f, idx) in fileLinks"
:key="idx"
:to="f.to"
:target="f.target"
:icon="f.icon!"
:label="f.label"
color="neutral"
variant="subtle"
size="xs"
external
/>
<UButton v-for="(f, idx) in fileLinks" :key="idx" :to="f.to" :target="f.target" :icon="f.icon!" :label="f.label"
color="neutral" variant="subtle" size="xs" external />
</div>
<!-- Buscador interno del documento -->
<div v-if="paragraphs.length" class="flex items-center gap-2">
<UInput
v-model="localQuery"
icon="i-lucide-search"
:placeholder="props.query || 'Buscar en este documento...'"
class="flex-1 min-w-0"
:ui="{ trailing: 'pe-1' }"
@keydown="onInputKey"
>
<UInput v-model="localQuery" icon="i-lucide-search" :placeholder="props.query || 'Buscar en este documento...'"
class="flex-1 min-w-0" :ui="{ trailing: 'pe-1' }" @keydown="onInputKey">
<template #trailing>
<UButton
v-if="localQuery"
icon="i-lucide-x"
variant="link"
aria-label="Limpiar"
@click="clearLocalQuery"
/>
<UButton v-if="localQuery" icon="i-lucide-x" variant="link" aria-label="Limpiar" @click="clearLocalQuery" />
</template>
</UInput>
<template v-if="matchElements.length || searchMode === 'local'">
<UBadge
v-if="searchMode === 'typesense' && matchElements.length"
label="Typesense"
size="xs"
variant="subtle"
color="warning"
class="shrink-0"
/>
<UBadge v-if="searchMode === 'typesense' && matchElements.length" label="Typesense" size="xs" variant="subtle"
color="warning" class="shrink-0" />
<span
class="text-xs tabular-nums whitespace-nowrap shrink-0 px-2 py-1 rounded-md bg-elevated border border-default"
:class="matchElements.length ? 'text-toned font-medium' : 'text-dimmed'"
>
:class="matchElements.length ? 'text-toned font-medium' : 'text-dimmed'">
{{ matchElements.length ? `${currentMatchIdx + 1} / ${matchElements.length}` : '0 / 0' }}
</span>
<div class="flex items-center gap-1 shrink-0">
<UTooltip text="Anterior (Shift+Enter)">
<UButton icon="i-lucide-chevron-up" :disabled="!matchElements.length" aria-label="Anterior" color="neutral" variant="ghost" size="sm" @click="prevMatch" />
<UButton icon="i-lucide-chevron-up" :disabled="!matchElements.length" aria-label="Anterior"
color="neutral" variant="ghost" size="sm" @click="prevMatch" />
</UTooltip>
<UTooltip text="Siguiente (Enter)">
<UButton icon="i-lucide-chevron-down" :disabled="!matchElements.length" aria-label="Siguiente" color="neutral" variant="ghost" size="sm" @click="nextMatch" />
<UButton icon="i-lucide-chevron-down" :disabled="!matchElements.length" aria-label="Siguiente"
color="neutral" variant="ghost" size="sm" @click="nextMatch" />
</UTooltip>
</div>
</template>
@ -867,54 +820,33 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
<div ref="scrollContainer" class="flex-1 overflow-y-auto relative bg-gray-100">
<!-- Cargando párrafos -->
<div
v-if="paragraphsLoading"
class="flex items-center justify-center gap-2 py-16 text-sm text-muted"
>
<div v-if="paragraphsLoading" class="flex items-center justify-center gap-2 py-16 text-sm text-muted">
<UIcon name="i-lucide-loader-circle" class="size-5 animate-spin" />
Cargando párrafos...
</div>
<!-- Todos los párrafos -->
<div
v-else-if="paragraphs.length"
ref="paragraphsContainer"
class="p-1 sm:p-4 max-w-4xl m-4 sm:mx-auto sm:my-6"
>
<div
v-for="(hit, idx) in paragraphs"
:key="idx"
:data-paragraph-number="hit.document.number"
class="bg-white rounded-lg shadow-md p-4 mb-4 last:mb-0"
>
<div class="flex items-center gap-2 mb-2">
<UBadge
v-if="hit.document.number"
:label="`#${hit.document.number}`"
size="xs"
variant="subtle"
color="info"
/>
<UBadge
v-if="hit.document.type"
:label="hit.document.type"
size="xs"
variant="subtle"
color="neutral"
/>
<div v-else-if="paragraphs.length" ref="paragraphsContainer" class="p-1 sm:p-4 max-w-4xl m-4 sm:mx-auto sm:my-6">
<div class="bg-white rounded-lg shadow-md p-4 mb-4 last:mb-0">
<div v-for="(hit, idx) in paragraphs" :key="idx" :data-paragraph-number="hit.document.number">
<div class="flex items-start gap-2 mb-2">
<div class="w-1/12">
<UBadge v-if="hit.document.number" :label="`#${hit.document.number}`" size="xs" variant="outline"
color="info" />
</div>
<div class="w-11/12">
<div
class="paragraph-html text-sm leading-relaxed text-gray-800 dark:text-gray-200"
v-html="hit.document.text"
/>
</div>
</div>
</div>
<div
class="paragraph-html text-sm leading-relaxed text-gray-800 dark:text-gray-200"
v-html="hit.document.text"
/>
</div>
</div>
<!-- Sin contenido -->
<div
v-else
class="flex flex-col items-center justify-center gap-2 py-16 text-dimmed text-sm"
>
<div v-else class="flex flex-col items-center justify-center gap-2 py-16 text-dimmed text-sm">
<UIcon name="i-lucide-file-x" class="size-10" />
<p>No hay contenido disponible para este documento.</p>
<p v-if="matchUrl">
@ -930,6 +862,7 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
.paragraph-html :deep(p) {
margin-bottom: 0.5rem;
}
.paragraph-html :deep(p:last-child) {
margin-bottom: 0;
}