merge: merge origin/main into HW_Dashboard and resolve conflicts

This commit is contained in:
2026-06-11 11:39:09 +09:00
25 changed files with 1972 additions and 217 deletions

View File

@@ -2,6 +2,7 @@ import { state, loadMasterDataFromDB, saveAsset } from './core/state';
import { renderNavigation } from './components/Navigation';
import { renderDashboard } from './views/DashboardView';
import { renderSWTable } from './views/SW_Table';
import { renderLocationView } from './views/LocationView';
import { initBaseModal } from './components/Modal/BaseModal';
import { initHwModal, openHwModal } from './components/Modal/HWModal';
import { initSwModal, openSwModal } from './components/Modal/SWModal';
@@ -12,52 +13,48 @@ import { initGuide } from './components/Guide';
import { pcFlowModal } from './components/Modal/PCFlowModal';
import { createIcons, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings } from 'lucide';
async function apiBatchSave(url: string, data: any[], label: string) {
try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error(`${label} DB 저장 실패`);
console.log(`${label} DB 저장 완료`);
} catch (err) {
console.error(`${label} DB 저장 오류:`, err);
alert(`${label} 저장 중 오류가 발생했습니다: ${(err as any).message}`);
}
}
const savePcToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/pc/batch`, state.masterData.pc, '개인PC');
const saveServerToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/server/batch`, state.masterData.server, '서버');
const saveStorageToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/storage/batch`, state.masterData.storage, '스토리지');
const saveNetworkToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/network/batch`, state.masterData.network, '네트워크');
const saveEquipToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/equipment/batch`, state.masterData.equipment, '업무지원장비');
const saveSwInternalToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/swInternal/batch`, state.masterData.swInternal, '내부SW');
const saveSwExternalToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/swExternal/batch`, state.masterData.swExternal, '외부SW');
const saveCloudToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/cloud/batch`, state.masterData.cloud, '클라우드');
const saveSwUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/swUsers/batch`, state.masterData.swUsers, 'SW사용자');
const saveLogsToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/logs/batch`, state.masterData.logs, '자산 로그');
const saveUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/users/batch`, state.masterData.users, '사용자마스터');
// 화면 갱신 통합 핸들러
function refreshView() {
const mainContent = document.getElementById('main-content')!;
if (!mainContent) return;
// 서버 탭이 아닐 경우 '자산현황(위치)' 뷰 진입 방지 및 강제 리스트 모드 전환
if (state.activeSubTab !== '서버' && state.viewMode === 'location') {
state.viewMode = 'list';
}
const isServerTab = state.activeSubTab === '서버';
if (state.activeSubTab === '대시보드') {
renderDashboard(mainContent);
mainContent.innerHTML = `
<div class="view-header">
<div class="view-toggle-container" style="${isServerTab ? '' : 'display:none;'}">
<button class="mode-toggle-btn ${state.viewMode === 'location' ? 'active' : ''}" data-mode="location">자산현황(위치)</button>
<button class="mode-toggle-btn ${state.viewMode === 'list' ? 'active' : ''}" data-mode="list">자산목록</button>
</div>
</div>
<div id="view-body" style="flex: 1; overflow: hidden; display: flex; flex-direction: column;"></div>
`;
// 이벤트 바인딩
mainContent.querySelectorAll('.mode-toggle-btn').forEach(btn => {
btn.addEventListener('click', () => {
const mode = (btn as HTMLElement).getAttribute('data-mode') as any;
state.viewMode = mode;
refreshView();
});
});
const viewBody = document.getElementById('view-body')!;
if (state.viewMode === 'location') {
renderLocationView(viewBody);
} else {
renderSWTable(mainContent);
renderSWTable(viewBody); // 리스트 형식
}
}
// 통합 저장 및 갱신
async function saveAllDataToDB() {
await Promise.all([
savePcToDB(), saveServerToDB(), saveStorageToDB(), saveNetworkToDB(),
saveEquipToDB(), saveSwInternalToDB(), saveSwExternalToDB(),
saveCloudToDB(), saveSwUsersToDB(), saveLogsToDB(), saveUsersToDB()
]);
// 통합 갱신 (저장은 이미 개별 모달에서 처리됨)
async function refreshAllData() {
await loadMasterDataFromDB();
refreshView();
}
@@ -71,21 +68,15 @@ function initApp() {
try {
renderNavigation((tab) => {
if (tab === '대시보드') {
renderDashboard(mainContent);
} else {
renderSWTable(mainContent);
}
refreshView();
});
initHwModal(() => saveAllDataToDB(), closeAllModals);
initSwModal(() => saveAllDataToDB(), closeAllModals);
initHwModal(() => refreshAllData(), closeAllModals);
initSwModal(() => refreshAllData(), closeAllModals);
initSwUserModal(() => {
saveSwUsersToDB().then(() => {
loadMasterDataFromDB().then(() => refreshView());
});
}, closeAllModals);
initDomainModal(() => saveAllDataToDB(), closeAllModals);
initDomainModal(() => refreshAllData(), closeAllModals);
initDashboardDetailModal();
initGuide();