mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-09 04:19:27 -07:00
fix(stats): collapse word and reading into one column in Top 50 table
This commit is contained in:
40
stats/src/components/vocabulary/FrequencyRankTable.test.tsx
Normal file
40
stats/src/components/vocabulary/FrequencyRankTable.test.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { renderToStaticMarkup } from 'react-dom/server';
|
||||||
|
import { FrequencyRankTable } from './FrequencyRankTable';
|
||||||
|
import type { VocabularyEntry } from '../../types/stats';
|
||||||
|
|
||||||
|
function makeEntry(over: Partial<VocabularyEntry>): VocabularyEntry {
|
||||||
|
return {
|
||||||
|
wordId: 1,
|
||||||
|
headword: '日本語',
|
||||||
|
word: '日本語',
|
||||||
|
reading: 'にほんご',
|
||||||
|
frequency: 5,
|
||||||
|
frequencyRank: 100,
|
||||||
|
animeCount: 1,
|
||||||
|
partOfSpeech: null,
|
||||||
|
firstSeen: 0,
|
||||||
|
lastSeen: 0,
|
||||||
|
...over,
|
||||||
|
} as VocabularyEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
test('renders headword and reading inline in a single column (no separate Reading header)', () => {
|
||||||
|
const entry = makeEntry({});
|
||||||
|
const markup = renderToStaticMarkup(
|
||||||
|
<FrequencyRankTable words={[entry]} knownWords={new Set()} />,
|
||||||
|
);
|
||||||
|
assert.ok(!markup.includes('>Reading<'), 'should not have a Reading column header');
|
||||||
|
assert.ok(markup.includes('日本語'), 'should include the headword');
|
||||||
|
assert.ok(markup.includes('にほんご'), 'should include the reading inline');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('omits reading when reading equals headword', () => {
|
||||||
|
const entry = makeEntry({ headword: 'カレー', word: 'カレー', reading: 'カレー' });
|
||||||
|
const markup = renderToStaticMarkup(
|
||||||
|
<FrequencyRankTable words={[entry]} knownWords={new Set()} />,
|
||||||
|
);
|
||||||
|
assert.ok(markup.includes('カレー'), 'should include the headword');
|
||||||
|
assert.ok(!markup.includes('【カレー】'), 'should not render reading in brackets when equal to headword');
|
||||||
|
});
|
||||||
@@ -113,7 +113,6 @@ export function FrequencyRankTable({ words, knownWords, onSelectWord }: Frequenc
|
|||||||
<tr className="text-xs text-ctp-overlay2 border-b border-ctp-surface1">
|
<tr className="text-xs text-ctp-overlay2 border-b border-ctp-surface1">
|
||||||
<th className="text-left py-2 pr-3 font-medium w-16">Rank</th>
|
<th className="text-left py-2 pr-3 font-medium w-16">Rank</th>
|
||||||
<th className="text-left py-2 pr-3 font-medium">Word</th>
|
<th className="text-left py-2 pr-3 font-medium">Word</th>
|
||||||
<th className="text-left py-2 pr-3 font-medium">Reading</th>
|
|
||||||
<th className="text-left py-2 pr-3 font-medium w-20">POS</th>
|
<th className="text-left py-2 pr-3 font-medium w-20">POS</th>
|
||||||
<th className="text-right py-2 font-medium w-20">Seen</th>
|
<th className="text-right py-2 font-medium w-20">Seen</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -128,9 +127,17 @@ export function FrequencyRankTable({ words, knownWords, onSelectWord }: Frequenc
|
|||||||
<td className="py-1.5 pr-3 font-mono tabular-nums text-ctp-peach text-xs">
|
<td className="py-1.5 pr-3 font-mono tabular-nums text-ctp-peach text-xs">
|
||||||
#{w.frequencyRank!.toLocaleString()}
|
#{w.frequencyRank!.toLocaleString()}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-1.5 pr-3 text-ctp-text font-medium">{w.headword}</td>
|
<td className="py-1.5 pr-3">
|
||||||
<td className="py-1.5 pr-3 text-ctp-subtext0">
|
<span className="text-ctp-text font-medium">{w.headword}</span>
|
||||||
{fullReading(w.headword, w.reading) || w.headword}
|
{(() => {
|
||||||
|
const reading = fullReading(w.headword, w.reading);
|
||||||
|
if (!reading || reading === w.headword) return null;
|
||||||
|
return (
|
||||||
|
<span className="text-ctp-subtext0 text-xs ml-1.5">
|
||||||
|
【{reading}】
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-1.5 pr-3">
|
<td className="py-1.5 pr-3">
|
||||||
{w.partOfSpeech && <PosBadge pos={w.partOfSpeech} />}
|
{w.partOfSpeech && <PosBadge pos={w.partOfSpeech} />}
|
||||||
|
|||||||
Reference in New Issue
Block a user