feat: migrate ServerPC data to asset_pc, enhance filters with location, and standardize page headers
- 서버PC 자산을 asset_pc 테이블로 통합 마이그레이션 및 스키마 확장 (위치, IP 정보 복구 완료) - 하드웨어 자산 페이지의 구매법인 필터를 자산위치 필터로 교체 및 동적 데이터 바인딩 적용 - 모든 자산 리스트 페이지 상단에 설명(Description) 필드 추가 및 헤더 표준화 - 상세 모달 내 삭제 버튼 기능 구현 및 서버PC 용도 필드 노출 오류 수정 - 현 사용조직 필터 리스트가 비어있던 DOM 셀렉터 버그 수정
This commit is contained in:
51
src/main.ts
51
src/main.ts
@@ -2,16 +2,14 @@ import { state, loadMasterDataFromDB, saveAsset } from './core/state';
|
||||
import { renderNavigation } from './components/Navigation';
|
||||
import { renderDashboard } from './views/DashboardView';
|
||||
import { renderSWTable } from './views/SW_Table';
|
||||
import { downloadTemplate, exportToExcel, parseExcel } from './core/excelHandler';
|
||||
import { initBaseModal } from './components/Modal/BaseModal';
|
||||
import { initHwModal, openHwModal } from './components/Modal/HWModal';
|
||||
import { initSwModal, openSwModal } from './components/Modal/SWModal';
|
||||
import { initSwUserModal } from './components/Modal/SWUserModal';
|
||||
import { initDomainModal, openDomainModal } from './components/Modal/DomainModal';
|
||||
import { initUploadPreviewModal, openUploadPreview } from './components/Modal/UploadPreviewModal';
|
||||
import { initDashboardDetailModal } from './components/Modal/DashboardDetailModal';
|
||||
import { initGuide } from './components/Guide';
|
||||
import { createIcons, Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings } from 'lucide';
|
||||
import { createIcons, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings } from 'lucide';
|
||||
|
||||
// --- DB 저장을 위한 세분화된 헬퍼 함수들 ---
|
||||
async function apiBatchSave(url: string, data: any[], label: string) {
|
||||
@@ -42,6 +40,7 @@ const saveSwExternalToDB = () => apiBatchSave(`http://${location.hostname}:3000/
|
||||
const saveCloudToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/cloud/batch`, state.masterData.cloud, '클라우드');
|
||||
const saveSwUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/asset/software/assignment/batch`, state.masterData.swUsers, 'SW사용자');
|
||||
const saveLogsToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/asset/history/batch`, state.masterData.logs, '자산 로그');
|
||||
const saveUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/users/batch`, state.masterData.users, '사용자마스터');
|
||||
|
||||
// 화면 갱신 통합 핸들러
|
||||
function refreshView() {
|
||||
@@ -60,7 +59,7 @@ async function saveAllDataToDB() {
|
||||
await Promise.all([
|
||||
savePcToDB(), saveServerToDB(), saveStorageToDB(), saveNetworkToDB(),
|
||||
saveEquipToDB(), saveSwInternalToDB(), saveSwExternalToDB(),
|
||||
saveCloudToDB(), saveSwUsersToDB(), saveLogsToDB()
|
||||
saveCloudToDB(), saveSwUsersToDB(), saveLogsToDB(), saveUsersToDB()
|
||||
]);
|
||||
await loadMasterDataFromDB();
|
||||
refreshView();
|
||||
@@ -93,10 +92,6 @@ function initApp() {
|
||||
|
||||
initDashboardDetailModal();
|
||||
initDomainModal();
|
||||
initUploadPreviewModal(async () => {
|
||||
await loadMasterDataFromDB();
|
||||
refreshView();
|
||||
});
|
||||
initGuide();
|
||||
|
||||
loadMasterDataFromDB().then((success) => {
|
||||
@@ -112,54 +107,32 @@ function initApp() {
|
||||
document.addEventListener('click', (e) => {
|
||||
const target = e.target as HTMLElement;
|
||||
|
||||
// 양식 다운로드
|
||||
if (target.closest('#btn-download-template')) {
|
||||
downloadTemplate();
|
||||
return;
|
||||
}
|
||||
|
||||
// 엑셀 내보내기
|
||||
if (target.closest('#btn-export-excel')) {
|
||||
exportToExcel(state.masterData);
|
||||
return;
|
||||
}
|
||||
|
||||
// 자산 추가
|
||||
if (target.closest('#btn-add-asset')) {
|
||||
const tab = state.activeSubTab;
|
||||
const cat = state.activeCategory;
|
||||
const newId = Math.random().toString(36).substring(2, 9);
|
||||
|
||||
if (cat === 'users') {
|
||||
// 사용자 추가는 renderUserList 내부에서 별도로 처리하거나 여기서 호출 가능
|
||||
// 현재 renderUserList에서 별도로 핸들링하고 있으므로 중복 실행 방지
|
||||
return;
|
||||
}
|
||||
|
||||
if (cat === 'hw') {
|
||||
openHwModal({ id: newId, asset_code: '', category: tab } as any, 'add');
|
||||
} else if (cat === 'sw') {
|
||||
openSwModal({ id: newId, asset_type: tab === '대시보드' ? '외부SW' : tab } as any, 'add');
|
||||
const swType = tab === '외부' ? '외부SW' : (tab === '내부' ? '내부SW' : '외부SW');
|
||||
openSwModal({ id: newId, asset_type: swType } as any, 'add');
|
||||
} else if (cat === 'ops') {
|
||||
if (tab === '도메인') openDomainModal(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// 엑셀 업로드 (Change 이벤트 위임)
|
||||
document.addEventListener('change', async (e) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
if (target.id === 'excel-upload') {
|
||||
const file = target.files?.[0];
|
||||
if (file) {
|
||||
try {
|
||||
const data = await parseExcel(file);
|
||||
openUploadPreview(data);
|
||||
target.value = '';
|
||||
} catch (err) {
|
||||
alert('엑셀 파일을 읽는 중 오류가 발생했습니다.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
createIcons({
|
||||
icons: { Download, Upload, FileSpreadsheet, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings }
|
||||
icons: { Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings }
|
||||
});
|
||||
window.addEventListener('refresh-view', () => refreshView());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user