223 lines
10 KiB
TypeScript
223 lines
10 KiB
TypeScript
import { state } from '../../core/state';
|
|
import { SoftwareAsset } from '../../core/excelHandler';
|
|
import { openModal } from './BaseModal';
|
|
|
|
const SW_MODAL_HTML = `
|
|
<div id="sw-asset-modal" class="modal-overlay hidden">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2 id="sw-modal-title">S/W 상세 정보</h2>
|
|
<button id="btn-close-sw-modal" class="btn-icon" aria-label="닫기"><i data-lucide="x"></i></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="sw-asset-form" class="grid-form">
|
|
<input type="hidden" id="sw-asset-id" />
|
|
<input type="hidden" id="sw-asset-type" />
|
|
<div class="form-group">
|
|
<label for="sw-분야">분야</label>
|
|
<select id="sw-분야" required>
|
|
<option value="업무공통">업무공통</option>
|
|
<option value="개발S/W">개발S/W</option>
|
|
<option value="디자인">디자인</option>
|
|
<option value="설계S/W">설계S/W</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-법인">법인</label>
|
|
<select id="sw-법인" required>
|
|
<option value="한맥">한맥 (HM)</option>
|
|
<option value="삼안 (SM)">삼안 (SM)</option>
|
|
<option value="바론 (BR)">바론 (BR)</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-부서">부서</label>
|
|
<input type="text" id="sw-부서" placeholder="ex) 경영지원팀" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-제품명">제품명</label>
|
|
<input type="text" id="sw-제품명" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-구매일">구매일</label>
|
|
<input type="text" id="sw-구매일" placeholder="ex) 2024-01-01" />
|
|
</div>
|
|
<div class="form-group" id="sw-구독일-group">
|
|
<label for="sw-구독일">구독일(시작~끝)</label>
|
|
<input type="text" id="sw-구독일" placeholder="ex) 2024-01-01 ~ 2024-12-31" />
|
|
</div>
|
|
<div class="form-group" id="sw-유지보수-group" style="display:none;">
|
|
<label for="sw-유지보수여부">유지보수 여부</label>
|
|
<label style="display:flex; align-items:center; gap:0.5rem; height: 38px; cursor: pointer;">
|
|
<input type="checkbox" id="sw-유지보수여부" /> 대상 여부
|
|
</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-금액">금액</label>
|
|
<input type="text" id="sw-금액" placeholder="ex) 1,000,000" oninput="this.value = this.value.replace(/[^0-9]/g, '').replace(/\\B(?=(\\d{3})+(?!\d))/g, ',')" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-수량">수량 (보유량)</label>
|
|
<input type="number" id="sw-수량" min="1" value="1" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-계정명">계정명</label>
|
|
<input type="text" id="sw-계정명" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-납품업체">납품업체</label>
|
|
<input type="text" id="sw-납품업체" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sw-비고">비고</label>
|
|
<input type="text" id="sw-비고" />
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="btn-delete-sw-asset" class="btn btn-outline btn-danger">삭제</button>
|
|
<div class="footer-actions">
|
|
<button id="btn-revert-sw-edit" class="btn btn-outline hidden">수정 취소</button>
|
|
<button id="btn-close-sw-footer" class="btn btn-outline">닫기</button>
|
|
<button id="btn-save-sw-asset" class="btn btn-primary">수정</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
export function initSwModal(renderContent: () => void, closeModals: () => void) {
|
|
if (!document.getElementById('sw-asset-modal')) {
|
|
document.body.insertAdjacentHTML('beforeend', SW_MODAL_HTML);
|
|
}
|
|
|
|
const swForm = document.getElementById('sw-asset-form') as HTMLFormElement;
|
|
const btnRevertEdit = document.getElementById('btn-revert-sw-edit') as HTMLButtonElement;
|
|
const btnSaveSw = document.getElementById('btn-save-sw-asset') as HTMLButtonElement;
|
|
const btnDeleteSw = document.getElementById('btn-delete-sw-asset') as HTMLButtonElement;
|
|
const btnCloseHeader = document.getElementById('btn-close-sw-modal') as HTMLButtonElement;
|
|
const btnCloseFooter = document.getElementById('btn-close-sw-footer') as HTMLButtonElement;
|
|
|
|
let isEditMode = false;
|
|
let currentAsset: SoftwareAsset | null = null;
|
|
|
|
const setEditMode = (edit: boolean) => {
|
|
isEditMode = edit;
|
|
if (edit) {
|
|
swForm.classList.add('is-edit-mode');
|
|
swForm.classList.remove('is-view-mode');
|
|
btnSaveSw.textContent = '저장';
|
|
btnRevertEdit.classList.remove('hidden');
|
|
btnCloseFooter.classList.add('hidden');
|
|
} else {
|
|
swForm.classList.add('is-view-mode');
|
|
swForm.classList.remove('is-edit-mode');
|
|
btnSaveSw.textContent = '수정';
|
|
btnRevertEdit.classList.add('hidden');
|
|
btnCloseFooter.classList.remove('hidden');
|
|
if (currentAsset) fillFormData(currentAsset);
|
|
}
|
|
};
|
|
|
|
function fillFormData(asset: SoftwareAsset) {
|
|
(document.getElementById('sw-asset-id') as HTMLInputElement).value = asset.id;
|
|
(document.getElementById('sw-asset-type') as HTMLInputElement).value = asset.type;
|
|
(document.getElementById('sw-분야') as HTMLSelectElement).value = asset.분야 || '업무공통';
|
|
(document.getElementById('sw-법인') as HTMLSelectElement).value = asset.법인;
|
|
(document.getElementById('sw-부서') as HTMLInputElement).value = asset.부서 || '';
|
|
(document.getElementById('sw-제품명') as HTMLInputElement).value = asset.제품명;
|
|
(document.getElementById('sw-구매일') as HTMLInputElement).value = asset.구매일 || '';
|
|
(document.getElementById('sw-구독일') as HTMLInputElement).value = asset.구독일 || '';
|
|
(document.getElementById('sw-유지보수여부') as HTMLInputElement).checked = !!asset.유지보수여부;
|
|
(document.getElementById('sw-금액') as HTMLInputElement).value = asset.금액 || '';
|
|
(document.getElementById('sw-수량') as HTMLInputElement).value = String(asset.수량);
|
|
(document.getElementById('sw-계정명') as HTMLInputElement).value = asset.계정명 || '';
|
|
(document.getElementById('sw-납품업체') as HTMLInputElement).value = asset.납품업체 || '';
|
|
(document.getElementById('sw-비고') as HTMLInputElement).value = asset.비고 || '';
|
|
}
|
|
|
|
btnRevertEdit?.addEventListener('click', () => setEditMode(false));
|
|
btnCloseHeader?.addEventListener('click', closeModals);
|
|
btnCloseFooter?.addEventListener('click', closeModals);
|
|
|
|
btnSaveSw?.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
if (!isEditMode) {
|
|
setEditMode(true);
|
|
return;
|
|
}
|
|
|
|
if (!swForm.checkValidity()) { swForm.reportValidity(); return; }
|
|
|
|
const id = (document.getElementById('sw-asset-id') as HTMLInputElement).value;
|
|
const newAsset: SoftwareAsset = {
|
|
id: id || Math.random().toString(36).substring(2, 9),
|
|
type: (document.getElementById('sw-asset-type') as HTMLInputElement).value,
|
|
분야: (document.getElementById('sw-분야') as HTMLSelectElement).value,
|
|
법인: (document.getElementById('sw-법인') as HTMLSelectElement).value,
|
|
부서: (document.getElementById('sw-부서') as HTMLInputElement).value,
|
|
제품명: (document.getElementById('sw-제품명') as HTMLInputElement).value,
|
|
구매일: (document.getElementById('sw-구매일') as HTMLInputElement).value,
|
|
구독일: (document.getElementById('sw-구독일') as HTMLInputElement).value,
|
|
유지보수여부: (document.getElementById('sw-유지보수여부') as HTMLInputElement).checked,
|
|
금액: (document.getElementById('sw-금액') as HTMLInputElement).value,
|
|
수량: parseInt((document.getElementById('sw-수량') as HTMLInputElement).value || '1', 10),
|
|
계정명: (document.getElementById('sw-계정명') as HTMLInputElement).value,
|
|
납품업체: (document.getElementById('sw-납품업체') as HTMLInputElement).value,
|
|
비고: (document.getElementById('sw-비고') as HTMLInputElement).value,
|
|
};
|
|
|
|
if (id) {
|
|
const idx = state.masterData.sw.findIndex(a => a.id === id);
|
|
if(idx !== -1) state.masterData.sw[idx] = newAsset;
|
|
} else {
|
|
state.masterData.sw.push(newAsset);
|
|
}
|
|
|
|
closeModals();
|
|
renderContent();
|
|
});
|
|
|
|
btnDeleteSw?.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
const id = (document.getElementById('sw-asset-id') as HTMLInputElement).value;
|
|
if (confirm('삭제하시겠습니까?')) {
|
|
state.masterData.sw = state.masterData.sw.filter(a => a.id !== id);
|
|
closeModals();
|
|
renderContent();
|
|
}
|
|
});
|
|
}
|
|
|
|
export function openSwModal(asset?: SoftwareAsset) {
|
|
currentAsset = asset || null;
|
|
const swForm = document.getElementById('sw-asset-form') as HTMLFormElement;
|
|
const deleteBtn = document.getElementById('btn-delete-sw-asset')!;
|
|
|
|
openModal('sw-asset-modal');
|
|
swForm.reset();
|
|
|
|
const subGroup = document.getElementById('sw-구독일-group')!;
|
|
const permGroup = document.getElementById('sw-유지보수-group')!;
|
|
if (state.activeSubTab === '구독SW') {
|
|
subGroup.style.display = 'flex';
|
|
permGroup.style.display = 'none';
|
|
} else {
|
|
subGroup.style.display = 'none';
|
|
permGroup.style.display = 'flex';
|
|
}
|
|
|
|
if (asset) {
|
|
document.getElementById('sw-modal-title')!.textContent = `${state.activeSubTab} 상세 정보 수정`;
|
|
deleteBtn.style.display = 'block';
|
|
fillFormData(asset);
|
|
setEditMode(false);
|
|
} else {
|
|
document.getElementById('sw-modal-title')!.textContent = `신규 ${state.activeSubTab} 자산 추가`;
|
|
deleteBtn.style.display = 'none';
|
|
(document.getElementById('sw-asset-id') as HTMLInputElement).value = '';
|
|
(document.getElementById('sw-asset-type') as HTMLInputElement).value = state.activeSubTab;
|
|
setEditMode(true);
|
|
}
|
|
}
|