Skip to content

Commit 3b88bcb

Browse files
committed
別名分頁補上出處/頁碼/備註欄
PersonBrowserService::tabAltNames() 原本就把 c_source/c_pages/c_notes 撈出來 送到前端,AltNamesTab 卻只渲染 序號/別名(拼音)/別名(中)/類型 四欄,等於是 送到前端就被丟掉的死負載。這三個欄位都在 AltnameMutationHandler 的 allowedFields 裡、可經提案修改,列表看不到會讓使用者誤以為沒存進去。 - tabAltNames() leftJoin TEXT_CODES 補出處書名(source_title_chn/source_title), 與 AltnameEditor 的 c_source label 同源;c_source 的哨兵 0 在 TEXT_CODES 沒有 對應列,leftJoin 自然落空、不需另外過濾 - AltNamesTab 加三欄;出處優先顯示書名(中/英)、查不到退回 #id,備註限寬 360px 並保留換行(SubresourceTable 外層已有橫向捲動)。表頭沿用編輯器同一組 i18n key (biogmains.source_field/pages_entries/notes_field),列表欄名與編輯器欄位標籤一致 已執行 ./vendor/bin/phpunit(2994 tests 全綠)與 npm run build
1 parent 9939c7d commit 3b88bcb

3 files changed

Lines changed: 55 additions & 1 deletion

File tree

app/Services/PersonBrowserService.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,13 @@ private function tabAltNames(int $personId): array {
649649
'ALTNAME_DATA.c_source',
650650
'ALTNAME_DATA.c_pages',
651651
'ALTNAME_DATA.c_notes',
652+
// 出處以書名顯示(與 AltnameEditor 的 c_source label 同源);c_source 的哨兵 0
653+
// 在 TEXT_CODES 沒有對應列,leftJoin 自然落空、不需另外過濾。
654+
'TC.c_title_chn AS source_title_chn',
655+
'TC.c_title AS source_title',
652656
])
653657
->leftJoin('ALTNAME_CODES AS ATC', 'ATC.c_name_type_code', '=', 'ALTNAME_DATA.c_alt_name_type_code')
658+
->leftJoin('TEXT_CODES AS TC', 'TC.c_textid', '=', 'ALTNAME_DATA.c_source')
654659
->where('ALTNAME_DATA.c_personid', $personId)
655660
->orderBy('ALTNAME_DATA.c_alt_name_type_code')
656661
->get();
@@ -670,6 +675,8 @@ private function tabAltNames(int $personId): array {
670675
'type_label_chn' => $r->c_name_type_desc_chn,
671676
'type_label' => $r->c_name_type_desc,
672677
'source_id' => $r->c_source,
678+
'source_title_chn' => $r->source_title_chn,
679+
'source_title' => $r->source_title,
673680
'pages' => $r->c_pages,
674681
'notes' => $r->c_notes,
675682
])->values()->all(),

resources/js/inertia/components/PersonBrowser/tabs/AltNamesTab.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ import { useTranslation } from '../../../hooks/useTranslation';
1414
import { Button } from '../../ui/Button';
1515
import { ConfirmDialog } from '../../ui/ConfirmDialog';
1616

17+
/**
18+
* 出處顯示:優先書名(中/英),沒有對應 TEXT_CODES 列時退回 `#id`,
19+
* 哨兵 0 與 null 一律視為「未填」。
20+
*/
21+
function formatSourceLabel(item: AltNameItem): string | null {
22+
const label = formatBilingualLabel(item.source_title_chn, item.source_title);
23+
if (label) return label;
24+
return item.source_id ? `#${item.source_id}` : null;
25+
}
26+
1727
interface AltNameItem {
1828
pk: {
1929
c_personid: number;
@@ -27,6 +37,8 @@ interface AltNameItem {
2737
type_label_chn: string | null;
2838
type_label: string | null;
2939
source_id: number | null;
40+
source_title_chn: string | null;
41+
source_title: string | null;
3042
pages: string | null;
3143
notes: string | null;
3244
}
@@ -131,6 +143,11 @@ export default function AltNamesTab({
131143
{ header: tb('altname_pinyin_label'), render: (item) => item.name },
132144
{ header: tb('altname_chinese'), render: (item) => item.name_chn },
133145
{ header: t('alt_name_type'), render: (item) => formatBilingualLabel(item.type_label_chn, item.type_label) },
146+
// 出處/頁碼/備註:AltnameMutationHandler 的 allowedFields 允許提案修改,
147+
// 卻只在編輯器裡看得到——列表不顯示會讓使用者以為沒存進去。
148+
{ header: tb('source_field'), render: (item) => formatSourceLabel(item) },
149+
{ header: tb('pages_entries'), render: (item) => item.pages },
150+
{ header: tb('notes_field'), render: (item) => (item.notes ? <div style={notesCellStyle}>{item.notes}</div> : null) },
134151
]}
135152
actions={(canEdit || canPropose) ? (item) => (useReactEditor ? (
136153
<span style={actionCellStyle}>
@@ -165,6 +182,13 @@ export default function AltNamesTab({
165182
);
166183
}
167184

185+
// 備註可能很長:限寬並保留換行,避免把整張表撐爆(外層 SubresourceTable 已有橫向捲動)。
186+
const notesCellStyle: React.CSSProperties = {
187+
maxWidth: 360,
188+
whiteSpace: 'pre-wrap',
189+
wordBreak: 'break-word',
190+
};
191+
168192
const containerStyle: React.CSSProperties = {
169193
display: 'flex',
170194
flexDirection: 'column',

tests/Feature/PersonBrowserTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,8 @@ protected function seedTestData(): void {
654654

655655
DB::table('ALTNAME_DATA')->insert([
656656
['c_personid' => 1, 'c_sequence' => 1, 'c_alt_name_chn' => '太白', 'c_alt_name' => 'Taibai', 'c_alt_name_type_code' => 4, 'c_source' => null, 'c_pages' => null, 'c_notes' => null],
657-
['c_personid' => 1, 'c_sequence' => 2, 'c_alt_name_chn' => '青蓮居士', 'c_alt_name' => 'Qinglian Jushi', 'c_alt_name_type_code' => 5, 'c_source' => null, 'c_pages' => null, 'c_notes' => null],
657+
// 出處/頁碼/備註在這一列填滿,釘住 alt_names 分頁確實把「提案可改欄位」送到前端。
658+
['c_personid' => 1, 'c_sequence' => 2, 'c_alt_name_chn' => '青蓮居士', 'c_alt_name' => 'Qinglian Jushi', 'c_alt_name_type_code' => 5, 'c_source' => 1, 'c_pages' => '卷一', 'c_notes' => '測試備註'],
658659
['c_personid' => 3, 'c_sequence' => 1, 'c_alt_name_chn' => '子瞻', 'c_alt_name' => 'Zizhan', 'c_alt_name_type_code' => 4, 'c_source' => null, 'c_pages' => null, 'c_notes' => null],
659660
['c_personid' => 3, 'c_sequence' => 2, 'c_alt_name_chn' => '東坡居士', 'c_alt_name' => 'Dongpo Jushi', 'c_alt_name_type_code' => 5, 'c_source' => null, 'c_pages' => null, 'c_notes' => null],
660661
]);
@@ -1151,6 +1152,28 @@ public function test_tab_alt_names_returns_typed_items(): void {
11511152
$response->assertJsonPath('items.0.type_label', 'Zi');
11521153
}
11531154

1155+
/**
1156+
* 出處/頁碼/備註同樣是 AltnameMutationHandler 允許提案修改的欄位,必須送到前端
1157+
* (以前撈了卻沒進 UI,看起來像「沒存進去」)。出處以 TEXT_CODES 書名顯示。
1158+
*/
1159+
#[Test]
1160+
public function test_tab_alt_names_exposes_source_pages_and_notes(): void {
1161+
$response = $this->actingAs($this->user)
1162+
->getJson(route('app.person-browser.tab', ['personId' => 1, 'tabKey' => 'alt_names']));
1163+
1164+
$response->assertOk();
1165+
$response->assertJsonPath('items.1.name_chn', '青蓮居士');
1166+
$response->assertJsonPath('items.1.source_id', 1);
1167+
$response->assertJsonPath('items.1.source_title_chn', '新唐書');
1168+
$response->assertJsonPath('items.1.source_title', 'New Tang Book');
1169+
$response->assertJsonPath('items.1.pages', '卷一');
1170+
$response->assertJsonPath('items.1.notes', '測試備註');
1171+
1172+
// 沒有出處的列不可因 leftJoin 落空而多出/少掉欄位。
1173+
$response->assertJsonPath('items.0.source_title_chn', null);
1174+
$response->assertJsonPath('items.0.notes', null);
1175+
}
1176+
11541177
#[Test]
11551178
public function test_tab_texts_returns_role_labels(): void {
11561179
$response = $this->actingAs($this->user)

0 commit comments

Comments
 (0)