From 6df1b2d7c1c4ffcd7a82ec44eee8dddb690be03d Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Tue, 16 Jun 2026 14:28:51 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20FE-PE:=20Link=20h=E1=BB=93=20s=C6=A1?= =?UTF-8?q?=20auto-detect=20=E2=80=94=20http(s)=20->=20hyperlink=20b?= =?UTF-8?q?=E1=BA=A5m-m=E1=BB=9F=20/=20=C4=91=C6=B0=E1=BB=9Dng=20d?= =?UTF-8?q?=E1=BA=ABn=20=E1=BB=95=20m=E1=BA=A1ng=20->=20ch=E1=BB=AF=20+=20?= =?UTF-8?q?n=C3=BAt=20Copy=20(x2=20app=20SHA256)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- fe-admin/src/components/pe/PeDetailTabs.tsx | 55 ++++++++++++++++++--- fe-user/src/components/pe/PeDetailTabs.tsx | 55 ++++++++++++++++++--- 2 files changed, 94 insertions(+), 16 deletions(-) diff --git a/fe-admin/src/components/pe/PeDetailTabs.tsx b/fe-admin/src/components/pe/PeDetailTabs.tsx index 8164e52..fc44fc0 100644 --- a/fe-admin/src/components/pe/PeDetailTabs.tsx +++ b/fe-admin/src/components/pe/PeDetailTabs.tsx @@ -1433,14 +1433,21 @@ function HoSoLinkRow({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: ) : ev.hoSoLink ? ( - - {ev.hoSoLink} - + /^https?:\/\//i.test(ev.hoSoLink.trim()) ? ( + // Link web (http/https — vd SharePoint) → bấm mở thẳng tab mới. + + {ev.hoSoLink} + + ) : ( + // Đường dẫn ổ cứng/ổ mạng (O:\…, \\server) → trình duyệt CHẶN mở file:// + // từ https nên bấm sẽ hụt → hiện chữ + nút Copy để dán vào File Explorer. + + ) ) : ( )} @@ -1449,6 +1456,38 @@ function HoSoLinkRow({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: ) } +// e.bis — Đường dẫn ổ cứng/ổ mạng (không phải http) → chữ + nút Copy. Trình duyệt +// CHẶN mở file:// từ trang https nên KHÔNG render bấm-mở (bấm sẽ hụt); thay +// bằng Copy → người dùng dán vào File Explorer (máy có map ổ mạng là mở ngay). +function PathWithCopy({ path }: { path: string }) { + const [copied, setCopied] = useState(false) + const copy = async () => { + try { + await navigator.clipboard.writeText(path) + setCopied(true) + setTimeout(() => setCopied(false), 1500) + } catch { + toast.error('Không copy được — vui lòng bôi đen đường dẫn rồi Ctrl+C.') + } + } + return ( +
+ + {path} + + +
+ ) +} + // Form row: label cố định 176px (w-44) bên trái + value bên phải (giống spec). function FormRow({ label, value }: { label: string; value: React.ReactNode }) { return ( diff --git a/fe-user/src/components/pe/PeDetailTabs.tsx b/fe-user/src/components/pe/PeDetailTabs.tsx index 8164e52..fc44fc0 100644 --- a/fe-user/src/components/pe/PeDetailTabs.tsx +++ b/fe-user/src/components/pe/PeDetailTabs.tsx @@ -1433,14 +1433,21 @@ function HoSoLinkRow({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: ) : ev.hoSoLink ? ( -
- {ev.hoSoLink} - + /^https?:\/\//i.test(ev.hoSoLink.trim()) ? ( + // Link web (http/https — vd SharePoint) → bấm mở thẳng tab mới. + + {ev.hoSoLink} + + ) : ( + // Đường dẫn ổ cứng/ổ mạng (O:\…, \\server) → trình duyệt CHẶN mở file:// + // từ https nên bấm sẽ hụt → hiện chữ + nút Copy để dán vào File Explorer. + + ) ) : ( )} @@ -1449,6 +1456,38 @@ function HoSoLinkRow({ ev, readOnly = false }: { ev: PeDetailBundle; readOnly?: ) } +// e.bis — Đường dẫn ổ cứng/ổ mạng (không phải http) → chữ + nút Copy. Trình duyệt +// CHẶN mở file:// từ trang https nên KHÔNG render bấm-mở (bấm sẽ hụt); thay +// bằng Copy → người dùng dán vào File Explorer (máy có map ổ mạng là mở ngay). +function PathWithCopy({ path }: { path: string }) { + const [copied, setCopied] = useState(false) + const copy = async () => { + try { + await navigator.clipboard.writeText(path) + setCopied(true) + setTimeout(() => setCopied(false), 1500) + } catch { + toast.error('Không copy được — vui lòng bôi đen đường dẫn rồi Ctrl+C.') + } + } + return ( +
+ + {path} + + +
+ ) +} + // Form row: label cố định 176px (w-44) bên trái + value bên phải (giống spec). function FormRow({ label, value }: { label: string; value: React.ReactNode }) { return (