From f929c373f6afc5c55c5628afa9cd0d3f5cdc058a Mon Sep 17 00:00:00 2001 From: PAN CHAO Date: Wed, 1 Jul 2026 23:11:45 +0800 Subject: [PATCH] frontend: normalize governance display text to English MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validation: - rg -n "[\p{Han}]|[,。;:!?()【】、]" frontend/dist frontend/src frontend/index.html frontend/*.json frontend/*.ts frontend/*.js (0 matches) - npm run check --prefix frontend (passed) - npm run build --prefix frontend (passed) --- frontend/src/lib/displayText.test.ts | 35 +++++++++++++++++++++++ frontend/src/lib/displayText.ts | 33 ++++++++++++++++++++++ frontend/src/pages/Governance.tsx | 42 ++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 frontend/src/lib/displayText.test.ts create mode 100644 frontend/src/lib/displayText.ts diff --git a/frontend/src/lib/displayText.test.ts b/frontend/src/lib/displayText.test.ts new file mode 100644 index 0000000..a090256 --- /dev/null +++ b/frontend/src/lib/displayText.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "vitest"; + +import { + englishDisplayText, + frameworkDisplayName, + hasLocalizedText +} from "./displayText"; + +const localizedIdentity = String.fromCharCode(0x8eab, 0x4efd, 0x9274, 0x5225); +const localizedAudit = String.fromCharCode(0x5b89, 0x5168, 0x5ba1, 0x8ba1); + +describe("display text normalization", () => { + it("uses English framework fallbacks for known localized overlays", () => { + expect( + frameworkDisplayName( + "china-mlps2", + "China Multi-Level Protection Scheme 2.0 (dengbao)" + ) + ).toBe("China Multi-Level Protection Scheme 2.0"); + }); + + it("removes localized suffixes from mixed framework citations", () => { + expect(englishDisplayText("GB/T 22239-2019 §7.1.4.1 -- identity")).toBe( + "GB/T 22239-2019 §7.1.4.1 -- identity" + ); + expect( + englishDisplayText(`GB/T 22239-2019 §7.1.4.1 -- ${localizedIdentity}`) + ).toBe("GB/T 22239-2019 §7.1.4.1"); + }); + + it("detects localized text", () => { + expect(hasLocalizedText("Security audit")).toBe(false); + expect(hasLocalizedText(localizedAudit)).toBe(true); + }); +}); diff --git a/frontend/src/lib/displayText.ts b/frontend/src/lib/displayText.ts new file mode 100644 index 0000000..d0b9723 --- /dev/null +++ b/frontend/src/lib/displayText.ts @@ -0,0 +1,33 @@ +const cjkPattern = /[\p{Script=Han}\u3000-\u303f\uff00-\uffef]/u; +const cjkParentheticalPattern = /\s*[\(\[][^)\]]*[\p{Script=Han}][^)\]]*[\)\]]/gu; +const cjkRunPattern = /[\p{Script=Han}]+/gu; + +const frameworkLabels: Record = { + "china-mlps2": "China Multi-Level Protection Scheme 2.0" +}; + +export function frameworkDisplayName( + frameworkId: string, + value?: string | null +) { + return frameworkLabels[frameworkId] ?? englishDisplayText(value, frameworkId); +} + +export function englishDisplayText(value?: string | null, fallback = "") { + if (!value) return fallback; + if (!cjkPattern.test(value)) return value; + + const cleaned = value + .replace(cjkParentheticalPattern, "") + .replace(cjkRunPattern, "") + .replace(/\s+([,.;:])/g, "$1") + .replace(/[-\u2013\u2014:\uff1a\uff1b;,\s]+$/g, "") + .replace(/\s{2,}/g, " ") + .trim(); + + return cleaned || fallback; +} + +export function hasLocalizedText(value?: string | null) { + return Boolean(value && cjkPattern.test(value)); +} diff --git a/frontend/src/pages/Governance.tsx b/frontend/src/pages/Governance.tsx index 9bd414c..ed539b4 100644 --- a/frontend/src/pages/Governance.tsx +++ b/frontend/src/pages/Governance.tsx @@ -39,6 +39,7 @@ import { type GovernanceProject, type PallasLens } from "../lib/governanceApi"; +import { englishDisplayText, frameworkDisplayName } from "../lib/displayText"; import { cn } from "../lib/utils"; const riskTiers = ["low", "medium", "high", "critical"]; @@ -203,8 +204,15 @@ export default function Governance() { onChange={() => toggleFramework(overlay.id)} type="checkbox" /> - {overlay.label ?? overlay.id} - {overlay.region_group} + + {frameworkDisplayName( + overlay.id, + overlay.label ?? overlay.name + )} + + + {englishDisplayText(overlay.region_group, "Framework")} + ))} @@ -354,16 +362,24 @@ function ControlsPanel({ {control.control_id}
-
{control.title}
+
+ {englishDisplayText(control.title, control.control_id)} +

- {control.normalized_requirement} + {englishDisplayText( + control.normalized_requirement, + "Control requirement" + )}