Skip to content

Commit a1f2908

Browse files
authored
Merge pull request #46 from singyichen/fix/prototype-i18n-annotation-results
fix(annotation): localize reviewer result text and stats in English mode
2 parents aec8418 + 21cc218 commit a1f2908

48 files changed

Lines changed: 2287 additions & 181 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

design/prototype/pages/account/profile.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@
6363
/* ── Main Content ────────────────────────────────────────────── */
6464
.main-content {
6565
flex: 1;
66-
padding: 32px 24px 80px;
66+
padding: 24px 24px 80px;
6767
overflow-x: hidden;
6868
}
6969

70-
.content-inner { max-width: 672px; }
70+
.content-inner { max-width: 1280px; width: 100%; margin: 0 auto; }
7171

72-
@media (min-width: 768px) { .main-content { padding: 32px 40px 64px; } }
72+
@media (min-width: 768px) { .main-content { padding: 24px 24px 64px; } }
7373

7474
/* ── Page Header ─────────────────────────────────────────────── */
7575
.page-heading {
@@ -78,10 +78,10 @@
7878
font-weight: 700;
7979
color: var(--color-ink);
8080
line-height: 1.3;
81-
margin-bottom: 4px;
81+
margin: 0 0 4px;
8282
}
8383

84-
.page-subheading { font-size: 14px; color: #64748B; margin-bottom: 24px; }
84+
.page-subheading { font-size: 14px; line-height: 1.8; color: var(--color-text-soft); margin: 0 0 24px; }
8585

8686
/* ── Section Card ────────────────────────────────────────────── */
8787
.section-card {

design/prototype/pages/admin/role-settings.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
/* ── Page Layout ─────────────────────────────────────────────── */
3232
.page-wrapper { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
3333
.main-content {
34-
flex: 1; padding: var(--space-xl) var(--space-2xl);
34+
flex: 1; padding: var(--space-lg);
35+
max-width: 1280px; width: 100%; margin: 0 auto;
3536
overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-xl);
3637
}
3738

@@ -66,10 +67,10 @@
6667
.admin-tab.active { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
6768

6869
/* ── Page Header ─────────────────────────────────────────────── */
69-
.page-header { display: flex; flex-direction: column; gap: var(--space-sm); }
70+
.page-header { display: flex; flex-direction: column; gap: 0; margin-bottom: 24px; }
7071
.page-header-main { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-lg); flex-wrap: wrap; }
7172
.page-title { font-family: 'Crimson Pro', 'Noto Serif TC', serif; font-weight: 700; font-size: 28px; color: var(--color-ink); line-height: 1.3; margin: 0 0 4px; }
72-
.page-subtitle { font-size: 14px; color: var(--color-ink-muted); margin: 0; }
73+
.page-subtitle { font-size: 14px; line-height: 1.8; color: var(--color-text-soft); margin: 0; }
7374
.page-actions { display: flex; align-items: center; gap: var(--space-sm); flex-shrink: 0; }
7475

7576
/* ── Buttons ─────────────────────────────────────────────────── */

design/prototype/pages/admin/user-management.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
/* ── Main Layout ────────────────────────────────────────────── */
3030
main { flex: 1; display: flex; flex-direction: column; overflow-y: auto; }
31-
.layout { max-width: 1200px; width: 100%; margin: 0 auto; padding: var(--space-lg); }
31+
.layout { max-width: 1280px; width: 100%; margin: 0 auto; padding: var(--space-lg); }
3232

3333
/* ── Page Header ────────────────────────────────────────────── */
3434
.page-header {
@@ -41,7 +41,7 @@
4141
font-family: 'Crimson Pro', 'Noto Serif TC', serif;
4242
font-size: 28px; line-height: 1.3; font-weight: 700; color: var(--color-ink); margin: 0 0 4px;
4343
}
44-
.page-main-subtitle { font-size: 14px; color: var(--color-text-soft); margin: 0; }
44+
.page-main-subtitle { font-size: 14px; line-height: 1.8; color: var(--color-text-soft); margin: 0; }
4545
.page-header-actions { display: flex; gap: var(--space-sm); align-items: center; flex-wrap: wrap; }
4646

4747
/* ── Admin Tabs ─────────────────────────────────────────────── */

design/prototype/pages/annotation/annotation-list.html

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,25 @@
2626

2727
.layout {
2828
flex: 1;
29-
padding: var(--space-xl);
29+
max-width: 1280px;
30+
width: 100%;
31+
margin: 0 auto;
32+
padding: var(--space-lg);
3033
display: flex;
3134
flex-direction: column;
3235
gap: var(--space-lg);
3336
min-width: 0;
3437
}
35-
.page-header { display: flex; align-items: flex-start; gap: var(--space-md); }
36-
.page-title { font-size: 28px; line-height: 1.2; font-weight: 700; }
37-
.page-subtitle { font-size: 14px; color: var(--color-ink-muted); margin-top: 6px; }
38+
.page-header { display: flex; align-items: flex-start; gap: var(--space-md); margin-bottom: 24px; }
39+
.page-title {
40+
font-family: var(--font-serif-display);
41+
font-size: 28px;
42+
line-height: 1.3;
43+
font-weight: 700;
44+
color: var(--color-ink);
45+
margin: 0 0 4px;
46+
}
47+
.page-subtitle { font-size: 14px; line-height: 1.8; color: var(--color-text-soft); margin: 0; }
3848
.list {
3949
display: grid;
4050
gap: var(--space-sm);
@@ -450,7 +460,6 @@
450460

451461
@media (max-width: 768px) {
452462
.layout { padding: var(--space-md) var(--space-md) var(--space-xl); }
453-
.page-title { font-size: 22px; }
454463
.task-item-header {
455464
flex-direction: column;
456465
align-items: flex-start;
@@ -500,9 +509,6 @@
500509
}
501510
@media (max-width: 420px) {
502511
.mobile-user-name { max-width: 56px; font-size: 11px; }
503-
.navbar-brand { width: auto; flex: 1; min-width: 0; }
504-
.navbar-wordmark { font-size: 13px; }
505-
.mobile-lang-toggle { padding: 6px 8px; }
506512
}
507513
.toast-container { position: fixed; bottom: var(--space-lg); right: var(--space-lg); z-index: var(--z-toast); pointer-events: none; }
508514
.toast {
@@ -643,7 +649,7 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
643649
<tbody id="sampleRows"></tbody>
644650
</table>
645651
</div>
646-
<div class="empty hidden" id="emptyState">找不到符合條件的資料。</div>
652+
<div class="empty hidden" id="emptyState"></div>
647653
<div class="pagination hidden" id="paginationBar">
648654
<div class="pagination-left">
649655
<span class="pagination-info" id="paginationInfo"></span>
@@ -708,10 +714,15 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
708714
quickContinueBtnReviewer: '快速審核',
709715
editBtnLabel: '編輯',
710716
expandBtnLabel: '展開',
717+
approveBtnLabel: '通過',
718+
rejectBtnLabel: '退回',
719+
approveAllBtnLabel: '全部通過',
720+
rejectAllBtnLabel: '全部退回',
711721
searchPlaceholder: '搜尋',
712722
searchAriaLabel: '搜尋',
713723
statusFilterAll: '全部完成狀態',
714724
clearFiltersLabel: '清除篩選',
725+
emptyNoResults: '找不到符合條件的資料。',
715726
paginationTpl: '共 {total} 筆 · 第 {page} / {totalPages} 頁',
716727
pageSizeTpl: '{size} / 頁',
717728
roleLabelAnnotator: '標記員',
@@ -750,10 +761,15 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
750761
quickContinueBtnReviewer: 'Quick Review',
751762
editBtnLabel: 'Edit',
752763
expandBtnLabel: 'Expand',
764+
approveBtnLabel: 'Approve',
765+
rejectBtnLabel: 'Reject',
766+
approveAllBtnLabel: 'Approve all',
767+
rejectAllBtnLabel: 'Reject all',
753768
searchPlaceholder: 'Search',
754769
searchAriaLabel: 'Search',
755770
statusFilterAll: 'All statuses',
756771
clearFiltersLabel: 'Clear filters',
772+
emptyNoResults: 'No matching data.',
757773
paginationTpl: 'Total {total} · Page {page} / {totalPages}',
758774
pageSizeTpl: '{size} / page',
759775
roleLabelAnnotator: 'Annotator',
@@ -771,6 +787,97 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
771787
return CURRENT_LANG === 'en' && sample.textEn ? sample.textEn : sample.text;
772788
}
773789

790+
var REVIEWER_RESULT_TRANSLATIONS = {
791+
'電池續航力': 'battery life',
792+
'服務員的態度': 'staff attitude',
793+
'操作流程順暢': 'smooth workflow',
794+
'客服回應速度': 'support response speed',
795+
'半導體產業論壇': 'Semiconductor Industry Forum',
796+
'創辦人張忠謀': 'founder Morris Chang',
797+
'鴻海精密工業': 'Foxconn',
798+
'越南胡志明市': 'Ho Chi Minh City, Vietnam',
799+
'超音波檢查': 'ultrasound exam',
800+
'賀爾蒙變化': 'hormonal changes',
801+
'胃部不適': 'gastrointestinal discomfort',
802+
'整體設計': 'overall design',
803+
'菜色選擇': 'menu options',
804+
'服務態度': 'service attitude',
805+
'用餐體驗': 'dining experience',
806+
'停車空間': 'parking space',
807+
'房間隔音': 'room soundproofing',
808+
'介面設計': 'interface design',
809+
'操作流程': 'workflow',
810+
'客戶支援': 'customer support',
811+
'佩戴舒適度': 'wearing comfort',
812+
'主動降噪功能': 'active noise cancellation',
813+
'主動降噪': 'active noise cancellation',
814+
'降噪功能': 'noise cancellation',
815+
'音質表現': 'audio quality',
816+
'服務員': 'staff',
817+
'早餐品質': 'breakfast quality',
818+
'停車場': 'parking',
819+
'隔音效果': 'soundproofing',
820+
'電池壽命': 'battery life',
821+
'高效能': 'high performance',
822+
'未完全出現在句子中': 'not an exact sentence match',
823+
'已刪除': 'deleted',
824+
'螢幕': 'screen',
825+
'價格': 'price',
826+
'環境': 'ambiance',
827+
'介面': 'interface',
828+
'音質': 'audio quality',
829+
'舒適度': 'comfort',
830+
'隔音': 'soundproofing',
831+
'體育': 'Sports',
832+
'娛樂': 'Entertainment',
833+
'社會': 'Society',
834+
'政治': 'Politics',
835+
'科技': 'Technology',
836+
'財經': 'Finance',
837+
'等價': 'Equivalent',
838+
'相關': 'Related',
839+
'無關': 'Unrelated',
840+
'阿司匹靈': 'Aspirin',
841+
'頭痛': 'headache',
842+
'乳房': 'breast',
843+
'疼痛': 'pain',
844+
'月經週期': 'menstrual cycle',
845+
'超音波': 'ultrasound',
846+
'膽囊結石': 'gallstones',
847+
'腹部疼痛': 'abdominal pain',
848+
'台積電': 'TSMC',
849+
'張忠謀': 'Morris Chang',
850+
'台北': 'Taipei',
851+
'鴻海': 'Foxconn',
852+
'越南': 'Vietnam',
853+
'胡志明市': 'Ho Chi Minh City',
854+
'衛生福利部': 'Ministry of Health and Welfare',
855+
'薛瑞元': 'Hsueh Jui-yuan',
856+
'2025年': '2025',
857+
'草稿': 'draft'
858+
};
859+
860+
var SORTED_REVIEWER_TRANSLATION_KEYS = Object.keys(REVIEWER_RESULT_TRANSLATIONS).sort(function (a, b) {
861+
return b.length - a.length;
862+
});
863+
864+
function localizeReviewerText(text) {
865+
var output = String(text || '');
866+
if (CURRENT_LANG !== 'en' || output === '-') return output;
867+
SORTED_REVIEWER_TRANSLATION_KEYS.forEach(function (source) {
868+
output = output.split(source).join(REVIEWER_RESULT_TRANSLATIONS[source]);
869+
});
870+
return output
871+
.replace(//g, ', ')
872+
.replace(//g, ' (')
873+
.replace(//g, ')')
874+
.replace(//g, 'original: ')
875+
.replace(/\s+,/g, ',')
876+
.replace(/,\s*/g, ', ')
877+
.replace(/\s{2,}/g, ' ')
878+
.trim();
879+
}
880+
774881
var toastTimer = null;
775882
function showToast(msg, type) {
776883
var toast = document.getElementById('toast');
@@ -1425,17 +1532,17 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
14251532
var resultSpan = document.createElement('span');
14261533
var colorClass = getVaColorClass(ann.result, vaRange);
14271534
resultSpan.className = 'annotator-result-tag' + (colorClass ? ' ' + colorClass : '');
1428-
resultSpan.textContent = ann.result;
1535+
resultSpan.textContent = localizeReviewerText(ann.result);
14291536

14301537
var approveBtn = document.createElement('button');
14311538
approveBtn.type = 'button';
14321539
approveBtn.className = 'mini-btn mini-btn-approve';
1433-
approveBtn.textContent = '✓ 通過';
1540+
approveBtn.textContent = '✓ ' + t('approveBtnLabel');
14341541

14351542
var rejectBtn = document.createElement('button');
14361543
rejectBtn.type = 'button';
14371544
rejectBtn.className = 'mini-btn mini-btn-reject';
1438-
rejectBtn.textContent = '✕ 退回';
1545+
rejectBtn.textContent = '✕ ' + t('rejectBtnLabel');
14391546

14401547
updateAnnotatorBtns(approveBtn, rejectBtn, REVIEW_STATES[key]);
14411548

@@ -1819,7 +1926,7 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
18191926
}
18201927

18211928
function formatReviewerLabelStats(sample, taskType) {
1822-
var statsText = sample && sample.labelStats ? String(sample.labelStats) : '-';
1929+
var statsText = sample && sample.labelStats ? localizeReviewerText(sample.labelStats) : '-';
18231930
if (taskType !== 'relation_extraction') return statsText;
18241931
return statsText.replace(/\s·\s/g, '\n');
18251932
}
@@ -1902,12 +2009,12 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
19022009
var approveAllBtn = document.createElement('button');
19032010
approveAllBtn.type = 'button';
19042011
approveAllBtn.className = 'mini-btn mini-btn-approve';
1905-
approveAllBtn.textContent = '✓ 全部通過';
2012+
approveAllBtn.textContent = '✓ ' + t('approveAllBtnLabel');
19062013
approveAllBtn.dataset.bulkApproveFor = sample.sampleId;
19072014
var rejectAllBtn = document.createElement('button');
19082015
rejectAllBtn.type = 'button';
19092016
rejectAllBtn.className = 'mini-btn mini-btn-reject';
1910-
rejectAllBtn.textContent = '✕ 全部退回';
2017+
rejectAllBtn.textContent = '✕ ' + t('rejectAllBtnLabel');
19112018
rejectAllBtn.dataset.bulkRejectFor = sample.sampleId;
19122019

19132020
updateBulkReviewBtns(approveAllBtn, rejectAllBtn, getBulkReviewState(sample.sampleId, annotators));
@@ -2123,6 +2230,8 @@ <h1 class="page-title" id="pageTitle">標記清單</h1>
21232230
}
21242231
var clearFiltersBtn = document.getElementById('clearFiltersBtn');
21252232
if (clearFiltersBtn) clearFiltersBtn.setAttribute('aria-label', t('clearFiltersLabel'));
2233+
var emptyState = document.getElementById('emptyState');
2234+
if (emptyState) emptyState.textContent = t('emptyNoResults');
21262235

21272236
renderTableHeader(context.role);
21282237
renderTaskInfo(context);

0 commit comments

Comments
 (0)