/* ============================================================================= * 회사 조회 후 고르기(시스템 관리자 회사 알약 · 29-5) * 찾기 칸(이름 · 사업자번호 · 띄어쓰기 단어 모두 맞음) → 거른 목록(처음엔 최근 등록 순) → * 줄 누르면 고름. 목록은 LIMIT 줄까지만 그림 — 회사가 많아도 찾기로 좁힘. * ========================================================================== */ import { createButton, createInputField } from "@ui/ui_template_elements"; import type { CompanyInfo } from "./B01_Dashboard_Api_Fetch"; import { L } from "./B01_Dashboard_UI_Common"; const LIMIT = 50; /** 이름 · 사업자번호(줄표 빼고도)에 모든 단어가 들어간 회사 — 순서는 받은 그대로 */ export function filterCompanies(companies: CompanyInfo[], text: string): CompanyInfo[] { const words = text.toLowerCase().split(/\s+/).filter(Boolean); return companies.filter((c) => { const no = c.business_registration_number ?? ""; const hay = `${c.name} ${no} ${no.replace(/-/g, "")}`.toLowerCase(); return words.every((w) => hay.includes(w)); }); } export function openCompanyPicker( companies: CompanyInfo[], currentId: number | null, onPick: (company: CompanyInfo) => void, ): void { const modal = document.createElement("div"); modal.className = "b01-dashboard__modal"; const panel = document.createElement("div"); panel.className = "b01-dashboard__modal-panel"; const heading = document.createElement("h3"); heading.className = "b01-dashboard__modal-title"; heading.textContent = L("B01_Dashboard_PickCompany"); const query = createInputField({ label: L("B01_Dashboard_Field_Search"), placeholder: L("B01_Dashboard_PickCompanyHint"), }); const count = document.createElement("p"); count.className = "b01-dashboard__company-count"; const list = document.createElement("div"); list.className = "b01-dashboard__company-list"; const close = (): void => { modal.remove(); document.removeEventListener("keydown", onKey, true); }; const pick = (company: CompanyInfo): void => { close(); onPick(company); }; let shown: CompanyInfo[] = []; const render = (): void => { const found = filterCompanies(companies, query.input.value); shown = found.slice(0, LIMIT); count.textContent = found.length > LIMIT ? L("B01_Dashboard_PickCompanyMore") .replace("{count}", String(found.length)) .replace("{limit}", String(LIMIT)) : L("B01_Dashboard_PickCompanyCount").replace("{count}", String(found.length)); list.replaceChildren( ...shown.map((company) => { const row = document.createElement("button"); row.type = "button"; row.className = "b01-dashboard__company-row"; row.classList.toggle("is-current", company.id === currentId); const name = document.createElement("span"); name.textContent = company.name; const no = document.createElement("small"); no.textContent = company.business_registration_number ?? ""; row.append(name, no); row.addEventListener("click", () => pick(company)); return row; }), ); }; // Enter = 첫 줄 고름 · Esc = 닫기 const onKey = (event: KeyboardEvent): void => { if (event.key === "Escape") close(); else if (event.key === "Enter" && event.target === query.input && shown[0]) pick(shown[0]); else return; event.preventDefault(); event.stopPropagation(); }; query.input.addEventListener("input", render); document.addEventListener("keydown", onKey, true); modal.addEventListener("click", (event) => { if (event.target === modal) close(); }); const actions = document.createElement("div"); actions.className = "b01-dashboard__actions"; actions.append(createButton({ label: L("Common_Btn_Cancel"), variant: "ghost", onClick: close })); panel.append(heading, query.root, count, list, actions); modal.append(panel); document.body.append(modal); render(); query.input.focus(); }