import { state } from '../core/state'; import { openHwModal } from '../components/Modal/HWModal'; import { ASSET_SCHEMA } from '../core/schema'; import { LOCATION_DATA, IMAGE_LOCATIONS } from '../components/Modal/SharedData'; /** * 위치 중심 자산 현황 뷰 (Vercel Integrated) */ export async function renderLocationView(container: HTMLElement) { if (!container) return; let currentLoc = '기술개발센터'; let currentDetail = '서버실'; let currentPage = 0; let mapConfig: any = {}; try { const res = await fetch('/api/maps'); mapConfig = await res.json(); } catch (err) { console.error('Failed to load map config', err); } const render = () => { const locImages = (IMAGE_LOCATIONS[currentLoc] && IMAGE_LOCATIONS[currentLoc][currentDetail]) ? IMAGE_LOCATIONS[currentLoc][currentDetail] : []; const mapPath = locImages[currentPage] || ''; // 조회 모드: 설정 파일에 정의된 asset_id를 기준으로 자산 데이터 매핑 const allBoxes = mapConfig[mapPath] || []; const boxes = allBoxes.filter((box: any) => box.asset_id != null); // 모든 하드웨어 카테고리에서 자산 검색 const allHwAssets = [ ...state.masterData.pc, ...state.masterData.server, ...state.masterData.storage, ...state.masterData.network, ...state.masterData.equipment, ...state.masterData.survey, ...state.masterData.officeSupplies, ...state.masterData.pcParts ]; container.innerHTML = `
${mapPath ? `
${boxes.map((box: any, idx: number) => { const asset = allHwAssets.find(a => a.id === box.asset_id); const name = asset ? ((asset as any).asset_purpose || asset.asset_code) : (box.name || `#${idx+1}`); // w, h가 없거나 너무 작으면 최소 크기(3%) 보장하여 영역으로 표시 const width = Math.max(parseFloat(box.w || '3'), 3); const height = Math.max(parseFloat(box.h || '3'), 3); return `
`}).join('')}
` : '
해당 위치의 도면이 등록되지 않았습니다.
'}
지도에서 자산 위치를 클릭하세요.
`; const syncOverlaySize = () => { const img = container.querySelector('#main-map-img') as HTMLImageElement; const overlay = container.querySelector('#box-overlay') as HTMLElement; if (img && overlay && img.complete) { overlay.style.width = img.clientWidth + 'px'; overlay.style.height = img.clientHeight + 'px'; overlay.style.left = img.offsetLeft + 'px'; overlay.style.top = img.offsetTop + 'px'; } }; const img = container.querySelector('#main-map-img') as HTMLImageElement; if (img) { if (img.complete) { syncOverlaySize(); setTimeout(syncOverlaySize, 50); } else { img.onload = syncOverlaySize; } } window.removeEventListener('resize', syncOverlaySize); window.addEventListener('resize', syncOverlaySize); const selMain = container.querySelector('#sel-loc-main') as HTMLSelectElement; selMain?.addEventListener('change', () => { currentLoc = selMain.value; currentDetail = LOCATION_DATA[currentLoc][0]; currentPage = 0; render(); }); const selDetail = container.querySelector('#sel-loc-detail') as HTMLSelectElement; selDetail?.addEventListener('change', () => { currentDetail = selDetail.value; currentPage = 0; render(); }); container.querySelector('#btn-prev-page')?.addEventListener('click', () => { currentPage--; render(); }); container.querySelector('#btn-next-page')?.addEventListener('click', () => { currentPage++; render(); }); const chkBox = container.querySelector('#chk-list-view-loc') as HTMLInputElement; if (chkBox) { chkBox.checked = state.viewMode === 'list'; const handleToggle = () => { const isListMode = chkBox.checked; if (isListMode) { state.viewMode = 'list'; } else { state.viewMode = 'location'; } window.dispatchEvent(new Event('refresh-view')); }; chkBox.addEventListener('change', handleToggle); } container.querySelectorAll('.location-box-area').forEach(box => { box.addEventListener('click', () => { const assetId = box.getAttribute('data-asset-id'); if (!assetId) return; const targetAsset = allHwAssets.find(a => a.id === assetId); if (targetAsset) renderAssetDetail(targetAsset); container.querySelectorAll('.location-box-area').forEach(b => (b as HTMLElement).style.background = 'rgba(30, 81, 73, 0.1)'); (box as HTMLElement).style.background = 'rgba(30, 81, 73, 0.4)'; }); }); }; const renderAssetDetail = (asset: any) => { const title = container.querySelector('#loc-list-title')!; const tableContainer = container.querySelector('#loc-asset-table-container')!; title.innerHTML = `
${asset.asset_code || '미부여'} ${asset.service_type || '운영'} ${asset.asset_type || 'PC'}
`; const fields = [ { label: ASSET_SCHEMA.CURRENT_DEPT.ui, value: asset.current_dept }, { label: ASSET_SCHEMA.HW_STATUS.ui, value: asset.hw_status }, { label: ASSET_SCHEMA.MANAGER_MAIN.ui, value: asset.manager_primary }, { label: ASSET_SCHEMA.MANAGER_SUB.ui, value: asset.manager_secondary }, { label: ASSET_SCHEMA.ASSET_PURPOSE.ui, value: asset.asset_purpose, fullWidth: true }, { label: ASSET_SCHEMA.MODEL_NAME.ui, value: asset.model_name }, { label: ASSET_SCHEMA.OS.ui, value: asset.os }, { label: ASSET_SCHEMA.CPU.ui, value: asset.cpu }, { label: ASSET_SCHEMA.RAM.ui, value: asset.ram }, { label: ASSET_SCHEMA.GPU.ui, value: asset.gpu, fullWidth: true }, { label: ASSET_SCHEMA.IP_ADDR.ui, value: asset.ip_address }, { label: ASSET_SCHEMA.MAC_ADDR.ui, value: asset.mac_address }, { label: ASSET_SCHEMA.REMOTE_TOOL.ui, value: asset.remote_tool }, { label: ASSET_SCHEMA.MONITORING.ui, value: asset.monitoring }, { label: ASSET_SCHEMA.MEMO.ui, value: asset.memo, fullWidth: true } ]; const sectionsHTML = `
${fields.map(f => `
${f.label}
${f.value || '-'}
`).join('')}
`; tableContainer.innerHTML = `
${sectionsHTML}
`; container.querySelector('#btn-view-from-loc')?.addEventListener('click', () => { openHwModal(asset, 'view'); }); }; render(); }