Complete merge with cleaned main branch

This commit is contained in:
2026-04-23 10:22:08 +09:00

View File

@@ -21,24 +21,24 @@ let isEditMode = false;
const STATUS_LIST = ['사용중', '보관중', '수리중', '폐기예정', '기타']; const STATUS_LIST = ['사용중', '보관중', '수리중', '폐기예정', '기타'];
// 필드 ID ↔ 데이터 Key 매핑 (서버 전용 필드 포함) // 필드 ID ↔ 데이터 Key 매핑
const HW_FIELD_MAP: Record<string, string> = { const HW_FIELD_MAP: Record<string, string> = {
'유형': 'type', '유형': 'type',
'법인': '법인', '법인': '법인',
'자산코드': '자산코드', '자산코드': '자산코드',
'현사용조직': '실사용조직', '현사용조직': '실사용조직',
'이전사용조직': '이전사용조직', '이전사용조직': '이전사용조직',
'상세용도': '서버용도', // 서버 전용 '상세용도': '서버용도',
'모델명': '모델명', '모델명': '모델명',
'명칭': '명칭', '명칭': '명칭',
'보관위치': '보관위치', '보관위치': '보관위치',
'현재상태': '상태', '현재상태': '상태',
'IP주소': 'IP주소', 'IP주소': 'IP주소',
'IP2': 'IP2', // 서버 전용 'IP2': 'IP2',
'원격접속': '원격방법', // 서버 전용 '원격접속': '원격방법',
'서버ID': '서버ID', // 서버 전용 '서버ID': '서버ID',
'서버PW': '서버PW', // 서버 전용 '서버PW': '서버PW',
'모니터링': '모니터링', // 서버 전용 '모니터링': '모니터링',
'OS': 'OS', 'OS': 'OS',
'CPU': 'CPU', 'CPU': 'CPU',
'RAM': 'RAM', 'RAM': 'RAM',
@@ -53,7 +53,6 @@ const HW_FIELD_MAP: Record<string, string> = {
}; };
const HW_FORM_HTML = ` const HW_FORM_HTML = `
<!-- Group 1: 기본 정보 -->
<div class="form-section-title">기본 정보 (Identity)</div> <div class="form-section-title">기본 정보 (Identity)</div>
<div class="form-group"> <div class="form-group">
<label for="hw-법인">구매법인</label> <label for="hw-법인">구매법인</label>
@@ -131,7 +130,6 @@ const HW_FORM_HTML = `
<div class="form-group full-width"><label for="hw-비고">비고</label><textarea id="hw-비고" rows="2"></textarea></div> <div class="form-group full-width"><label for="hw-비고">비고</label><textarea id="hw-비고" rows="2"></textarea></div>
`; `;
<<<<<<< HEAD
function renderHwHistory(assetId: string) { function renderHwHistory(assetId: string) {
const container = document.getElementById('hw-history-list'); const container = document.getElementById('hw-history-list');
if (!container) return; if (!container) return;
@@ -144,27 +142,6 @@ function renderHwHistory(assetId: string) {
<div class="history-details">${l.details.replace(/\n/g, '<br>')}</div> <div class="history-details">${l.details.replace(/\n/g, '<br>')}</div>
</div> </div>
`).join(''); `).join('');
=======
export function openHwModal(asset: HardwareAsset, mode: 'view' | 'add' | 'edit' = 'view') {
currentAsset = asset;
const modal = document.getElementById('hw-asset-modal')!;
// 1. 잠금 상태 통합 제어 (데이터 유무가 아닌 호출 mode에만 의존)
setEditLock('hw-asset-form', mode, {
saveBtnId: 'btn-save-hw-asset',
revertBtnId: 'btn-revert-hw-edit',
generateBtnId: 'btn-generate-hw-code'
});
isEditMode = (mode === 'add' || mode === 'edit');
// 2. 데이터 바인딩
fillHwFormData(asset);
modal.classList.remove('hidden');
applyTypeSpecificUI(asset.type);
createIcons({ icons: { Paperclip } });
>>>>>>> origin/SW_Table
} }
function applyTypeSpecificUI(type: string) { function applyTypeSpecificUI(type: string) {
@@ -192,7 +169,6 @@ function applyTypeSpecificUI(type: string) {
const opOnly = document.querySelectorAll('.op-only'); const opOnly = document.querySelectorAll('.op-only');
const standardLoc = document.querySelectorAll('.loc-standard'); const standardLoc = document.querySelectorAll('.loc-standard');
// 초기화
serverOnly.forEach(el => (el as HTMLElement).style.display = 'none'); serverOnly.forEach(el => (el as HTMLElement).style.display = 'none');
nonServer.forEach(el => (el as HTMLElement).style.display = 'none'); nonServer.forEach(el => (el as HTMLElement).style.display = 'none');
opOnly.forEach(el => (el as HTMLElement).style.display = 'none'); opOnly.forEach(el => (el as HTMLElement).style.display = 'none');
@@ -223,7 +199,6 @@ function applyTypeSpecificUI(type: string) {
if (groups.model) groups.model.style.display = 'flex'; if (groups.model) groups.model.style.display = 'flex';
if (groups.hwSpec) groups.hwSpec.style.display = 'flex'; if (groups.hwSpec) groups.hwSpec.style.display = 'flex';
} else { } else {
// 기본값: 전체 필드 표시
nonServer.forEach(el => (el as HTMLElement).style.display = 'flex'); nonServer.forEach(el => (el as HTMLElement).style.display = 'flex');
if (groups.specTitle) groups.specTitle.style.display = 'flex'; if (groups.specTitle) groups.specTitle.style.display = 'flex';
['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'hwSpec'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; }); ['model', 'os', 'cpu', 'ram', 'ssd1', 'ssd2', 'hwSpec'].forEach(k => { if (groups[k]) groups[k]!.style.display = 'flex'; });
@@ -242,13 +217,8 @@ export function openHwModal(asset: HardwareAsset, mode: 'view' | 'add' = 'view')
}); });
isEditMode = (mode === 'add'); isEditMode = (mode === 'add');
// 데이터 채우기 (자동 매핑)
autoFillForm('hw', asset, HW_FIELD_MAP); autoFillForm('hw', asset, HW_FIELD_MAP);
// 위치 정보 처리
parseAndSetLocation(asset., 'hw-위치-빌딩', 'hw-위치-상세', 'hw-위치-기타-group', 'hw-위치-기타'); parseAndSetLocation(asset., 'hw-위치-빌딩', 'hw-위치-상세', 'hw-위치-기타-group', 'hw-위치-기타');
applyTypeSpecificUI(asset.type); applyTypeSpecificUI(asset.type);
renderHwHistory(asset.id); renderHwHistory(asset.id);
@@ -264,7 +234,6 @@ export function initHwModal(onSave: () => void, closeModalsCb: () => void) {
}); });
document.body.insertAdjacentHTML('beforeend', html); document.body.insertAdjacentHTML('beforeend', html);
// 이력 추가 모달
const logModalHTML = ` const logModalHTML = `
<div id="hw-log-modal" class="modal-overlay hidden" style="z-index: 1100;"> <div id="hw-log-modal" class="modal-overlay hidden" style="z-index: 1100;">
<div class="modal-content" style="max-width: 400px;"> <div class="modal-content" style="max-width: 400px;">
@@ -282,7 +251,6 @@ export function initHwModal(onSave: () => void, closeModalsCb: () => void) {
document.body.insertAdjacentHTML('beforeend', logModalHTML); document.body.insertAdjacentHTML('beforeend', logModalHTML);
} }
const form = document.getElementById('hw-asset-form') as HTMLFormElement;
const saveBtn = document.getElementById('btn-save-hw-asset')!; const saveBtn = document.getElementById('btn-save-hw-asset')!;
const revertBtn = document.getElementById('btn-revert-hw-edit')!; const revertBtn = document.getElementById('btn-revert-hw-edit')!;
const deleteBtn = document.getElementById('btn-delete-hw-asset')!; const deleteBtn = document.getElementById('btn-delete-hw-asset')!;
@@ -340,15 +308,12 @@ export function initHwModal(onSave: () => void, closeModalsCb: () => void) {
return; return;
} }
// 데이터 추출 (자동 매핑)
const extracted = autoExtractForm('hw', HW_FIELD_MAP); const extracted = autoExtractForm('hw', HW_FIELD_MAP);
if (!extracted.) { if (!extracted.) {
alert('자산번호가 없습니다. [생성] 버튼을 눌러 자산번호를 부여해주세요.'); alert('자산번호가 없습니다. [생성] 버튼을 눌러 자산번호를 부여해주세요.');
return; return;
} }
// 변경 이력 자동 생성
const diffLogs: string[] = []; const diffLogs: string[] = [];
const compareFields = [ const compareFields = [
{ key: '실사용조직', label: '실사용조직' }, { key: '실사용조직', label: '실사용조직' },