import { createButton } from "@ui/ui_template_elements"; import type { AuditLog, DashboardUser } from "./B01_Dashboard_Api_Fetch"; import { canChangeRole, canDeleteUser } from "./B01_Dashboard_UI_Helper"; import { openChangeRoleModal, openDeleteUserModal, openEditUserModal, } from "./B01_Dashboard_UI_Modals"; import { table, text } from "@ui/ui_template_general_blocks"; import { DASHBOARD_VISIBLE_ROWS, formatDate, formatTime, L, stackedCell, } from "./B01_Dashboard_UI_Common"; export function userTable(users: DashboardUser[], currentUser: DashboardUser): HTMLElement { return table( [ L("B01_Dashboard_Table_Email"), L("B01_Dashboard_Table_Name"), L("B01_Dashboard_Table_Position"), L("B01_Dashboard_Table_Department"), L("B01_Account_Field_Phone"), L("B01_Dashboard_Table_Role"), L("B01_Dashboard_Table_Status"), L("B01_Dashboard_Table_Action"), ], users.map((user) => { const actionsEl = document.createElement("div"); actionsEl.className = "b01-dashboard__actions"; actionsEl.append( createButton({ label: L("Common_Btn_Edit"), variant: "ghost", onClick: () => openEditUserModal(currentUser, user), }), ); if (canChangeRole(currentUser, user)) { actionsEl.append( createButton({ label: L("B01_Dashboard_ChangeRole"), variant: "ghost", onClick: () => openChangeRoleModal(user), }), ); } // 회사에서 빼기·계정 삭제 (2026-09-06 사용자 지시) — 범위는 백엔드가 다시 본다. if (canDeleteUser(currentUser, user) && user.id !== currentUser.id) { actionsEl.append( createButton({ label: L("B01_Dashboard_DeleteUser"), variant: "ghost", onClick: () => openDeleteUserModal(user), }), ); } return [ text(user.email), text(user.name), text(user.position), text(user.department), text(user.phone), text(user.role), text(user.status), actionsEl, ]; }), DASHBOARD_VISIBLE_ROWS, ); } /** 무엇에 한 일인지 — 표에 저장된 대상 종류·번호를 사람이 읽는 말로. */ function auditTarget(log: AuditLog): string { // 저장값은 소문자(`project`)로 들어온다 — 대문자로 맞춰 찾는다. const key = (log.resource_type ?? "").toUpperCase(); const kind = TARGET_LABELS[key] ?? log.resource_type ?? ""; const reference = log.resource_ref ?? (log.resource_id ? String(log.resource_id) : ""); if (!kind) return reference || "-"; // 프로젝트 UUID 는 길어 앞 8자만 — 어느 프로젝트인지 가리기에는 충분하다. const shortened = reference.length > 12 ? `${reference.slice(0, 8)}…` : reference; return shortened ? `${kind} ${shortened}` : kind; } const TARGET_LABELS: Record = { PROJECT: "프로젝트", COMPANY: "회사", USER: "사용자", ASSET: "자산", }; export function auditLogTable(logs: AuditLog[]): HTMLElement { return table( [ L("B01_Dashboard_Table_Email"), // 관리 버튼 열과 같은 말(「관리」)을 돌려 쓰던 것을 갈랐다 (2026-09-06 사용자 지적). L("B01_Dashboard_Table_Event"), L("B01_Dashboard_Table_Target"), L("B01_Dashboard_Table_Origin"), L("B01_Dashboard_Table_When"), ], logs.map((log) => [ text(log.email), text(log.action), text(auditTarget(log)), // 접속 주소 — 기록이 없는 옛 줄은 빈칸으로 남는다 (2026-09-06부터 기록). text(log.ip_address ?? "-"), // 날짜와 시각을 두 줄로 — 아랫줄이 작은 글씨라 행 높이는 그대로다. stackedCell(formatDate(log.timestamp), formatTime(log.timestamp)), ]), DASHBOARD_VISIBLE_ROWS, ); }