fix(frontend): restore scrolling on the available channels page

The available channels table rendered inside its own
"card overflow-hidden" wrapper instead of the ".table-wrapper" element
that TablePageLayout's scroll chain expects. The outer
.table-scroll-container is overflow-hidden, so when the channel list
grew taller than the viewport the content was simply clipped with no
scrollbar. The extra card wrapper also drew a double border inside the
layout's own card chrome.

Mount the table on .table-wrapper like every other table page so it
receives overflow-y-auto from the layout, and add a source-convention
regression test in the style of TablePageLayout.spec.ts.

Fixes #4555

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Astrenix
2026-07-19 02:18:41 +08:00
co-authored by Claude Fable 5
parent d4b9797ff7
commit 4c73149af8
2 changed files with 23 additions and 1 deletions
@@ -1,5 +1,7 @@
<template>
<div class="card overflow-hidden">
<!-- .table-wrapper 是 TablePageLayout 滚动链的挂载点:外层 .table-scroll-container
负责卡片外观并 overflow-hidden,本层接收 overflow-y-auto 才能在内容超高时滚动。 -->
<div class="table-wrapper">
<table class="w-full table-fixed border-collapse text-sm">
<thead>
<tr class="border-b border-gray-100 bg-gray-50/50 text-xs font-medium uppercase tracking-wide text-gray-500 dark:border-dark-700 dark:bg-dark-800/50 dark:text-gray-400">
@@ -0,0 +1,20 @@
import { readFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
const componentPath = resolve(dirname(fileURLToPath(import.meta.url)), '../AvailableChannelsTable.vue')
const componentSource = readFileSync(componentPath, 'utf8')
describe('AvailableChannelsTable scroll integration', () => {
// #4555:根元素必须是 TablePageLayout 滚动链约定的 .table-wrapper,
// 否则内容超出视口高度时被外层 overflow-hidden 裁剪且没有滚动条。
it('mounts the table on the .table-wrapper scroll hook', () => {
expect(componentSource).toMatch(/<div class="table-wrapper">\s*<table/)
})
it('does not clip content with its own overflow-hidden card wrapper', () => {
expect(componentSource).not.toMatch(/<div class="card overflow-hidden">/)
})
})