fix(knowledge): sentinel DOM ordering + restore tag visibility

Sentinel was first in DOM with order:9999, causing layout recalculation to
trigger IntersectionObserver multiple times (intersecting→not→intersecting)
as items were appended, producing duplicate pages. Move sentinel to AFTER
the v-for items so it's naturally last in both DOM and visual order.

Remove overflow:hidden from .k-card-tags — .k-card overflow:hidden already
clips escaping content; the extra overflow on the tags container was
collapsing its height to zero and hiding all tag pills.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 22:54:35 -04:00
parent 4ac26d9326
commit 3c38c04ad4
+7 -8
View File
@@ -382,11 +382,6 @@ watchEffect(() => {
<!-- Card grid (sentinel lives inside so IntersectionObserver root works) -->
<div v-else ref="cardGridEl" class="card-grid">
<!-- Infinite scroll sentinel must be inside the scrolling root -->
<div ref="sentinelEl" class="scroll-sentinel">
<span v-if="loading && items.length > 0" class="sentinel-loading">Loading</span>
</div>
<div
v-for="item in items"
:key="item.id"
@@ -450,6 +445,11 @@ watchEffect(() => {
<span class="k-card-date">{{ formatDate(item.updated_at) }}</span>
</div>
</div>
<!-- Sentinel after all cards IntersectionObserver triggers next page load -->
<div ref="sentinelEl" class="scroll-sentinel">
<span v-if="loading && items.length > 0" class="sentinel-loading">Loading</span>
</div>
</div>
</div>
@@ -853,7 +853,7 @@ watchEffect(() => {
justify-content: space-between;
gap: 6px;
}
.k-card-tags { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; overflow: hidden; }
.k-card-tags { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; }
.tag-pill {
font-size: 0.68rem;
padding: 1px 6px;
@@ -879,8 +879,7 @@ watchEffect(() => {
/* ── Infinite scroll sentinel ────────────────────────────── */
.scroll-sentinel {
grid-column: 1 / -1; /* span all grid columns */
order: 9999; /* push to end of grid items */
grid-column: 1 / -1; /* span all columns so it's not a card-sized slot */
height: 40px;
display: flex;
align-items: center;