Merge origin/main into HW_Dashboard and resolve conflicts

This commit is contained in:
2026-06-10 09:13:23 +09:00
54 changed files with 4220 additions and 1735 deletions

View File

@@ -39,6 +39,7 @@ export interface AppState {
activeSubTab: string;
masterData: MasterAssetData;
activeCharts: any[];
currentUserRole: 'admin' | 'user';
}
// 초기 상태
@@ -46,6 +47,7 @@ export const state: AppState = {
activeCategory: 'hw',
activeSubTab: '대시보드',
activeCharts: [],
currentUserRole: 'user',
masterData: {
users: [],
pc: [], server: [], storage: [], network: [],
@@ -59,27 +61,20 @@ export const state: AppState = {
};
/**
* 신규 14개 테이블 구조에 맞춘 데이터 로드 (Dummy Data)
* 통합 V2 스키마에 맞춘 데이터 로드
*/
export async function loadMasterDataFromDB() {
try {
state.masterData.pc = dummyPCs || [];
state.masterData.server = dummyServers || [];
state.masterData.storage = dummyStorages || [];
state.masterData.network = dummyEquips || []; // dummy fallback
state.masterData.survey = [];
state.masterData.pcParts = [];
state.masterData.equipment = dummyEquips || [];
state.masterData.officeSupplies = [];
state.masterData.swInternal = dummyPermSw || [];
state.masterData.swExternal = dummySubSw || [];
state.masterData.cloud = dummyCloud || [];
state.masterData.domain = dummyDomain || [];
state.masterData.cost = [];
state.masterData.vip = [];
state.masterData.swUsers = dummySwUsers || [];
state.masterData.logs = dummyLogs || [];
state.masterData.users = [];
const response = await fetch(`${API_BASE_URL}/api/assets/master`);
if (!response.ok) throw new Error('Failed to fetch master data');
const data = await response.json();
// 전역 상태 업데이트
state.masterData = {
...state.masterData,
...data
};
// Mapping for backward compatibility
state.masterData.equip = state.masterData.equipment;
@@ -101,10 +96,10 @@ export async function loadMasterDataFromDB() {
state.masterData.sw = [
...state.masterData.swInternal,
...state.masterData.swExternal,
...state.masterData.cloud
...(state.masterData.cloud || [])
];
console.log('✅ All dummy data loaded and unified');
console.log('✅ V2 Normalized data loaded successfully');
return true;
} catch (err) {
console.warn('⚠️ Dummy 로드 실패:', err);
@@ -117,18 +112,21 @@ export function updateState(newState: Partial<AppState>) {
}
/**
* 자산 저장 (Dummy API)
* 자산 저장 (V2 Normalized API)
*/
export async function saveAsset(category: string, asset: any) {
try {
const currentList = [...(state.masterData as any)[category]];
const idx = currentList.findIndex(a => a.id === asset.id);
const url = `${API_BASE_URL}/api/asset/${category}/save`;
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(asset)
});
if (idx > -1) currentList[idx] = asset;
else currentList.push(asset);
(state.masterData as any)[category] = currentList;
return true;
if (response.ok) {
await loadMasterDataFromDB(); // 전역 상태 갱신
return true;
}
} catch (err) {
console.error('자산 저장 실패:', err);
}
@@ -136,14 +134,17 @@ export async function saveAsset(category: string, asset: any) {
}
/**
* 자산 삭제 (Dummy API)
* 자산 삭제 (V2 API)
*/
export async function deleteAsset(category: string, assetId: string) {
try {
const currentList = [...(state.masterData as any)[category]];
const filteredList = currentList.filter(a => a.id !== assetId);
(state.masterData as any)[category] = filteredList;
return true;
const url = `${API_BASE_URL}/api/asset/${category}/${assetId}`;
const response = await fetch(url, { method: 'DELETE' });
if (response.ok) {
await loadMasterDataFromDB(); // 전역 상태 갱신
return true;
}
} catch (err) {
console.error('자산 삭제 실패:', err);
}