import { state } from '../../core/state'; import { openPartsMasterModal } from '../../components/Modal/PartsMasterModal'; import { openJobSpecModal } from '../../components/Modal/JobSpecModal'; import { formatInline } from '../../core/utils'; import { createListView } from './ListFactory'; export let activePartsMasterSubTab: 'parts-master' | 'job-spec' = 'parts-master'; export function renderPartsMasterList(container: HTMLElement) { if (activePartsMasterSubTab === 'parts-master') { createListView(container, { title: '부품 마스터', dataSource: () => state.masterData.partsMaster || [], searchKeys: ['component_name', 'category', 'score_tier'], filterOptions: { keywordLabel: '부품명 / 등급 검색', showLoc: false, showDept: false, showType: false }, onRowClick: (component) => openPartsMasterModal(component, 'view'), columns: [ { header: 'ID', sortKey: 'id', align: 'center', width: '5%', render: c => c.id.toString() }, { header: '분류', sortKey: 'category', align: 'center', width: '15%', render: c => { let badgeClass = 'badge-primary'; if (c.category === 'CPU') badgeClass = 'badge-primary'; else if (c.category === 'GPU') badgeClass = 'badge-success'; else if (c.category === 'RAM') badgeClass = 'badge-warning'; return `${c.category}`; } }, { header: '부품 표준 명칭', sortKey: 'component_name', render: c => formatInline(c.component_name || '-') }, { header: '성능 등급', sortKey: 'score_tier', align: 'center', width: '15%', render: c => c.score_tier || '-' }, { header: '감점 점수', sortKey: 'deduction', align: 'center', width: '15%', render: c => { const score = c.deduction || 0; let color = '#3b82f6'; // blue if (score >= 20) color = '#ef4444'; // red else if (score >= 10) color = '#f59e0b'; // orange return `-${score}점`; } } ] }); } else { createListView(container, { title: '직무별 기준 사양', dataSource: () => state.masterData.jobSpecs || [], searchKeys: ['job_name', 'cpu_standard', 'ram_standard', 'gpu_standard', 'remarks'], filterOptions: { keywordLabel: '직무명 / 사양 검색', showLoc: false, showDept: false, showType: false }, onRowClick: (jobSpec) => openJobSpecModal(jobSpec, 'view'), columns: [ { header: 'ID', sortKey: 'id', align: 'center', width: '5%', render: j => j.id.toString() }, { header: '직무명', sortKey: 'job_name', width: '15%', render: j => `${formatInline(j.job_name || '-')}` }, { header: '권장 CPU 사양', sortKey: 'cpu_standard', render: j => formatInline(j.cpu_standard || '-') }, { header: '권장 RAM 사양', sortKey: 'ram_standard', width: '12%', render: j => formatInline(j.ram_standard || '-') }, { header: '권장 GPU 사양', sortKey: 'gpu_standard', render: j => formatInline(j.gpu_standard || '-') }, { header: '기준 점수', sortKey: 'min_score', align: 'center', width: '10%', render: j => `${j.min_score || 0}점 이상` }, { header: '비고', sortKey: 'remarks', width: '20%', render: j => formatInline(j.remarks || '-') } ] }); } renderSubTabs(container); } function renderSubTabs(container: HTMLElement) { const header = container.querySelector('.page-header'); if (!header) return; // 기존에 생성된 탭 바가 있다면 제거하여 중복 방지 (스타일만 수정하는 최소 침습 방식) const existingTabs = container.querySelector('.sub-tab-container'); if (existingTabs) existingTabs.remove(); const tabContainer = document.createElement('div'); tabContainer.className = 'sub-tab-container'; tabContainer.style.cssText = 'display: flex; gap: 1rem; padding: 0 2rem; border-bottom: 1px solid var(--hairline); background: var(--canvas);'; const tab1Active = activePartsMasterSubTab === 'parts-master'; const tab2Active = activePartsMasterSubTab === 'job-spec'; tabContainer.innerHTML = ` `; header.parentNode!.insertBefore(tabContainer, header.nextSibling); const tabPartsMaster = tabContainer.querySelector('#tab-parts-master')!; const tabJobSpec = tabContainer.querySelector('#tab-job-spec')!; tabPartsMaster.addEventListener('click', () => { if (activePartsMasterSubTab !== 'parts-master') { activePartsMasterSubTab = 'parts-master'; renderPartsMasterList(container); } }); tabJobSpec.addEventListener('click', () => { if (activePartsMasterSubTab !== 'job-spec') { activePartsMasterSubTab = 'job-spec'; renderPartsMasterList(container); } }); }