import { state } from '../core/state'; import { createIcons, Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, RefreshCcw } from 'lucide'; import { openPcModal } from '../components/Modal/PCModal'; import { openHwModal } from '../components/Modal/HWModal'; import { openStorageModal } from '../components/Modal/StorageModal'; import { openSwModal } from '../components/Modal/SWModal'; import { openSwUserModal } from '../components/Modal/SWUserModal'; /** * 자산 목록 테이블 렌더링 메인 함수 */ export function renderTable(mainContent: HTMLElement) { mainContent.innerHTML = ''; const container = document.createElement('div'); container.className = 'view-container'; const table = document.createElement('table'); if (state.activeCategory === 'hw') { renderHwTable(table, container, mainContent); } else { renderSwTable(table, container, mainContent); } createIcons({ icons: { Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2 } }); } function renderHwTable(table: HTMLTableElement, container: HTMLElement, mainContent: HTMLElement) { const list = state.masterData.hw.filter(a => a.type === state.activeSubTab); const tableWrapper = document.createElement('div'); tableWrapper.className = 'table-container'; if (state.activeSubTab === '개인PC') { table.innerHTML = `No법인자산코드사용자위치CPUGPURAMSSD1SSD2HDD1HDD2구매일금액납품업체품의서관리`; tableWrapper.appendChild(table); container.appendChild(tableWrapper); mainContent.appendChild(container); const tbody = document.getElementById('dynamic-tbody')!; if (list.length === 0) { tbody.innerHTML = `등록된 자산이 없습니다.`; return; } list.forEach((asset, idx) => { const tr = document.createElement('tr'); tr.style.cursor = 'pointer'; tr.innerHTML = `${idx+1}${asset.법인}${asset.자산코드}${asset.사용자||''}${asset.위치||''}${asset.CPU||''}${asset.GPU||''}${asset.RAM||''}${asset.SSD1||'-'}${asset.SSD2||'-'}${asset.HDD1||'-'}${asset.HDD2||'-'}${asset.구매일||''}${asset.금액||''}${asset.납품업체||''}${asset.품의서명 ? '' : '-'}`; tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openPcModal(asset); }); tbody.appendChild(tr); }); } else if (state.activeSubTab === '스토리지') { table.innerHTML = `No법인유형자산코드명칭위치모델명용량담당자(정)IP주소구매일금액관리`; tableWrapper.appendChild(table); container.appendChild(tableWrapper); mainContent.appendChild(container); const tbody = document.getElementById('dynamic-tbody')!; if (list.length === 0) { tbody.innerHTML = `등록된 자산이 없습니다.`; return; } list.forEach((asset, idx) => { const tr = document.createElement('tr'); tr.style.cursor = 'pointer'; tr.innerHTML = `${idx+1}${asset.법인}${asset.storage유형||''}${asset.자산코드}${asset.명칭}${asset.위치||''}${asset.모델명||''}${asset.용량||''}${asset.담당자_정||''}${asset.IP주소||''}${asset.구매일||''}${asset.금액||''}`; tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openStorageModal(asset); }); tbody.appendChild(tr); }); } else { // 서버 또는 전산비품 if (state.activeSubTab === '서버') { table.innerHTML = `No법인자산번호유형용도상세설치위치담당자모델명OSCPURAMStorage`; } else { table.innerHTML = `No법인${state.activeSubTab === '전산비품' ? '유형' : ''}자산코드명칭위치관리자구매일금액관리`; } tableWrapper.appendChild(table); container.appendChild(tableWrapper); mainContent.appendChild(container); const tbody = document.getElementById('dynamic-tbody')!; const colCount = state.activeSubTab === '서버' ? 13 : (state.activeSubTab === '전산비품' ? 11 : 10); if (list.length === 0) { tbody.innerHTML = `등록된 자산이 없습니다.`; return; } list.forEach((asset, idx) => { const tr = document.createElement('tr'); tr.style.cursor = 'pointer'; const formatInline = (v: any) => String(v || '').replace(/\n/g, ' / ').trim(); const getBadge = (text: string, bgColor: string) => `${text}`; if (state.activeSubTab === '서버') { const mainManager = asset.담당자_정 || ''; const subManager = asset.담당자_부 || ''; const managerHtml = [mainManager ? `${getBadge('정', '#1E5149')} ${mainManager}` : '', subManager ? `${getBadge('부', '#9CA3AF')} ${subManager}` : ''].filter(v => v !== '').join(' / '); const storageInfo = [asset.SSD1, asset.SSD2].filter(v => v && v !== '').join(' / '); // 위치 정보 가공 (서관/동관 -> IDC) let locationHtml = formatInline(asset.위치); if (locationHtml.startsWith('서관') || locationHtml.startsWith('동관')) { locationHtml = `IDC(${locationHtml})`; } tr.innerHTML = ` ${idx+1} ${formatInline(asset.법인)} ${formatInline(asset.자산코드)} ${formatInline(asset.storage유형)} ${formatInline(asset.용도)} ${formatInline(asset.상세)} ${locationHtml} ${managerHtml} ${formatInline(asset.모델명)} ${formatInline(asset.OS)} ${formatInline(asset.CPU)} ${formatInline(asset.RAM)} ${formatInline(storageInfo)} `; tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openHwModal(asset); }); } else { tr.innerHTML = `${idx+1}${asset.법인}${state.activeSubTab === '전산비품' ? `${asset.비품유형||'-'}` : ''}${asset.자산코드}${asset.명칭}${asset.위치}${asset.관리자}${asset.구매일||''}${asset.금액||''}`; tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openHwModal(asset); }); } tbody.appendChild(tr); }); } } function renderSwTable(table: HTMLTableElement, container: HTMLElement, mainContent: HTMLElement) { const fullList = state.masterData.sw.filter(a => a.type === state.activeSubTab); const isSub = state.activeSubTab === '구독SW'; container.innerHTML = ''; const filterBar = document.createElement('div'); filterBar.className = 'search-bar'; filterBar.innerHTML = `
`; container.appendChild(filterBar); const tableWrapper = document.createElement('div'); tableWrapper.className = 'table-container'; table.classList.add('sw-table'); table.innerHTML = `No.분야법인부서제품명구매일${isSub ? '구독일' : ''}금액수량사용가능관리`; tableWrapper.appendChild(table); container.appendChild(tableWrapper); mainContent.appendChild(container); const tbody = document.getElementById('dynamic-tbody')!; const updateTable = () => { const keyword = (document.getElementById('filter-keyword') as HTMLInputElement).value.toLowerCase().trim(); const field = (document.getElementById('filter-field') as HTMLSelectElement).value; const corp = (document.getElementById('filter-corp') as HTMLSelectElement).value; const filtered = fullList.filter(asset => { const matchKeyword = !keyword || (asset.제품명 || '').toLowerCase().includes(keyword) || (asset.부서 || '').toLowerCase().includes(keyword); const matchField = !field || asset.분야 === field; const matchCorp = !corp || asset.법인 === corp; return matchKeyword && matchField && matchCorp; }); tbody.innerHTML = ''; if (filtered.length === 0) { tbody.innerHTML = `검색 결과가 없습니다.`; return; } filtered.forEach((asset, idx) => { const assigned = state.masterData.swUsers.filter(u => u.swId === asset.id).length; const qty = typeof asset.수량 === 'number' ? asset.수량 : parseInt(asset.수량||'0', 10); const avail = qty - assigned; const tr = document.createElement('tr'); tr.style.cursor = 'pointer'; tr.innerHTML = `${idx+1}${asset.분야||''}${asset.법인}${asset.부서||''}${asset.제품명}${asset.구매일||''}${isSub ? `${asset.구독일||''}` : ''}${asset.금액||'0'}${qty}${avail}`; tr.addEventListener('click', (e) => { if (!(e.target as HTMLElement).closest('button')) openSwModal(asset); }); tr.querySelector('.btn-edit')?.addEventListener('click', () => openSwModal(asset)); tr.querySelector('.btn-users')?.addEventListener('click', () => openSwUserModal(asset)); tbody.appendChild(tr); }); createIcons({ icons: { Edit2, Users, RefreshCcw } }); }; const keywordInput = document.getElementById('filter-keyword') as HTMLInputElement; const fieldSelect = document.getElementById('filter-field') as HTMLSelectElement; const corpSelect = document.getElementById('filter-corp') as HTMLSelectElement; const resetBtn = document.getElementById('btn-reset-filters') as HTMLButtonElement; keywordInput.addEventListener('input', updateTable); fieldSelect.addEventListener('change', updateTable); corpSelect.addEventListener('change', updateTable); resetBtn.addEventListener('click', () => { keywordInput.value = ''; fieldSelect.value = ''; corpSelect.value = ''; updateTable(); }); updateTable(); }