feat: 서버 상세 모달 그룹화 및 전역 UI/UX 통일, 조회/수정 모드 구현
주요 변경 사항: - 서버 자산 상세 정보 4개 그룹(Identity, Connectivity, Specs, Operation)으로 최적화 - 모달 내 조회/수정 모드 전환 및 수정 강조색(#FF3D00) 적용 - 모든 모달의 버튼 사이즈 및 폰트 스타일 가이드 준수 통일 - 수정 취소(Revert) 기능 및 누락된 대시보드 상세 모달 추가 - TypeScript 타입 오류 및 런타임 렌더링 결함 긴급 복구
This commit is contained in:
169
src/main.ts
169
src/main.ts
@@ -1,88 +1,95 @@
|
||||
import { createIcons, Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History } from 'lucide';
|
||||
import { downloadTemplate, exportToExcel, parseExcel } from './excelHandler';
|
||||
import { state } from './state';
|
||||
import { initSidebar } from './components/Sidebar';
|
||||
import { initBaseModal } from './components/Modal/BaseModal';
|
||||
import { initPCModal, openPcModal } from './components/Modal/PCModal';
|
||||
import { initHWModal, openHwModal } from './components/Modal/HWModal';
|
||||
import { initStorageModal, openStorageModal } from './components/Modal/StorageModal';
|
||||
import { initSWModal, openSwModal } from './components/Modal/SWModal';
|
||||
import { initSWUserModal, openSwUserModal } from './components/Modal/SWUserModal';
|
||||
import { renderSidebar } from './components/Sidebar';
|
||||
import { renderDashboard } from './views/DashboardView';
|
||||
import { renderTable } from './views/AssetTableView';
|
||||
import { downloadTemplate, exportToExcel, parseExcel } from './excelHandler';
|
||||
import { initPcModal } from './components/Modal/PCModal';
|
||||
import { initHwModal, openHwModal } from './components/Modal/HWModal';
|
||||
import { initStorageModal } from './components/Modal/StorageModal';
|
||||
import { initSwModal } from './components/Modal/SWModal';
|
||||
import { initSwUserModal } from './components/Modal/SWUserModal';
|
||||
import { createIcons, Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw } from 'lucide';
|
||||
|
||||
declare var Chart: any;
|
||||
|
||||
// --- DOM Elements ---
|
||||
const mainContent = document.getElementById('main-content') as HTMLElement;
|
||||
const uploadInput = document.getElementById('excel-upload') as HTMLInputElement;
|
||||
const btnAddAsset = document.getElementById('btn-add-asset') as HTMLButtonElement;
|
||||
const btnDownloadTemp = document.getElementById('btn-download-template') as HTMLButtonElement;
|
||||
const btnExport = document.getElementById('btn-export-excel') as HTMLButtonElement;
|
||||
|
||||
// Initialize Icons
|
||||
createIcons({
|
||||
icons: { Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History }
|
||||
});
|
||||
|
||||
// Initialize Components
|
||||
const { closeAllModals } = initBaseModal();
|
||||
initSidebar(renderContent);
|
||||
initPCModal(renderContent, closeAllModals);
|
||||
initHWModal(renderContent, closeAllModals);
|
||||
initStorageModal(renderContent, closeAllModals);
|
||||
initSWModal(renderContent, closeAllModals);
|
||||
initSWUserModal(renderContent, closeAllModals);
|
||||
|
||||
// Dashboard Detail 닫기 버튼 (공통 처리용)
|
||||
const btnCloseDashboardDetail = document.getElementById('btn-close-dashboard-detail') as HTMLButtonElement;
|
||||
btnCloseDashboardDetail?.addEventListener('click', () => {
|
||||
document.getElementById('dashboard-detail-modal')?.classList.add('hidden');
|
||||
});
|
||||
|
||||
// Add Element Button
|
||||
btnAddAsset?.addEventListener('click', () => {
|
||||
if (state.activeSubTab === '대시보드') return;
|
||||
if (state.activeCategory === 'hw') {
|
||||
if (state.activeSubTab === '개인PC') openPcModal();
|
||||
else if (state.activeSubTab === '스토리지') openStorageModal();
|
||||
else openHwModal();
|
||||
} else {
|
||||
openSwModal();
|
||||
}
|
||||
});
|
||||
|
||||
// --- Excel Controls ---
|
||||
btnDownloadTemp?.addEventListener('click', () => downloadTemplate());
|
||||
btnExport?.addEventListener('click', () => exportToExcel(state.masterData));
|
||||
|
||||
uploadInput?.addEventListener('change', async (e) => {
|
||||
const file = (e.target as HTMLInputElement).files?.[0];
|
||||
if (!file) return;
|
||||
try {
|
||||
state.masterData = await parseExcel(file);
|
||||
renderContent();
|
||||
alert('모든 시트 데이터 연동 완료');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert('엑셀 파싱 오류: 템플릿 양식이 다르거나 파일이 손상되었습니다.');
|
||||
} finally {
|
||||
uploadInput.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 전역 렌더링 함수 - 각 컴포넌트에서 호출하여 화면을 갱신합니다.
|
||||
*/
|
||||
function renderContent() {
|
||||
mainContent.innerHTML = ''; // 화면 초기화
|
||||
// --- App Initialization ---
|
||||
function initApp() {
|
||||
const mainContent = document.getElementById('main-content')!;
|
||||
|
||||
if (state.activeSubTab === '대시보드') {
|
||||
renderDashboard(mainContent);
|
||||
} else {
|
||||
renderTable(mainContent);
|
||||
}
|
||||
// 1. 초기 뷰 렌더링 (대시보드)
|
||||
renderDashboard(mainContent);
|
||||
|
||||
// 2. 사이드바 초기화
|
||||
renderSidebar((tab) => {
|
||||
if (tab === '대시보드') {
|
||||
renderDashboard(mainContent);
|
||||
document.getElementById('btn-add-asset')?.classList.add('hidden');
|
||||
} else {
|
||||
renderTable(mainContent);
|
||||
document.getElementById('btn-add-asset')?.classList.remove('hidden');
|
||||
}
|
||||
// 상단 타이틀 업데이트
|
||||
const titleEl = document.getElementById('current-tab-title')!;
|
||||
titleEl.textContent = `${state.activeCategory === 'hw' ? '하드웨어' : '소프트웨어'} / ${state.activeSubTab}`;
|
||||
});
|
||||
|
||||
// 3. 모달 초기화
|
||||
initPcModal();
|
||||
initHwModal();
|
||||
initStorageModal();
|
||||
initSwModal();
|
||||
initSwUserModal(() => renderTable(mainContent), () => {});
|
||||
initDashboardDetailModal();
|
||||
|
||||
// 4. 전역 버튼 이벤트 바인딩
|
||||
document.getElementById('btn-download-template')?.addEventListener('click', () => downloadTemplate());
|
||||
document.getElementById('btn-export-excel')?.addEventListener('click', () => exportToExcel(state.masterData));
|
||||
|
||||
const uploadInput = document.getElementById('excel-upload') as HTMLInputElement;
|
||||
uploadInput?.addEventListener('change', async (e) => {
|
||||
const file = (e.target as HTMLInputElement).files?.[0];
|
||||
if (file) {
|
||||
const data = await parseExcel(file);
|
||||
state.masterData = data;
|
||||
renderTable(mainContent);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('btn-add-asset')?.addEventListener('click', () => {
|
||||
if (state.activeSubTab === '서버' || state.activeSubTab === '전산비품' || state.activeSubTab === '스토리지') {
|
||||
const newAsset = {
|
||||
id: Math.random().toString(36).substring(2, 9),
|
||||
type: state.activeSubTab,
|
||||
법인: '한맥',
|
||||
자산코드: '',
|
||||
명칭: '',
|
||||
위치: '',
|
||||
관리자: '',
|
||||
IP주소: '',
|
||||
MACaddress: '',
|
||||
HW사양: '',
|
||||
OS: '',
|
||||
납품업체: '',
|
||||
품의서명: ''
|
||||
};
|
||||
openHwModal(newAsset);
|
||||
}
|
||||
});
|
||||
|
||||
// 전역 아이콘 초기화
|
||||
createIcons({
|
||||
icons: { Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw }
|
||||
});
|
||||
}
|
||||
|
||||
// Initial Render
|
||||
renderContent();
|
||||
function initDashboardDetailModal() {
|
||||
const modal = document.getElementById('dashboard-detail-modal')!;
|
||||
const closeBtn = document.getElementById('btn-close-dashboard-detail-modal')!;
|
||||
const cancelBtn = document.getElementById('btn-cancel-dashboard-detail-modal')!;
|
||||
|
||||
const closeModal = () => modal.classList.add('hidden');
|
||||
closeBtn.addEventListener('click', closeModal);
|
||||
cancelBtn.addEventListener('click', closeModal);
|
||||
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
|
||||
}
|
||||
|
||||
// Start the app
|
||||
document.addEventListener('DOMContentLoaded', initApp);
|
||||
|
||||
Reference in New Issue
Block a user