Files
ITAM/src/components/Modal/DomainModal.ts

189 lines
8.4 KiB
TypeScript

import { state, saveAsset, deleteAsset } from '../../core/state';
import { BaseModal } from './BaseModal';
import { CORP_LIST } from './SharedData';
import { generateOptionsHTML, setFieldValue, getFieldValue } from './ModalUtils';
import { createIcons, X, Save, Database, CalendarClock, Edit2, History, Plus } from 'lucide';
import { formatExcelDate } from '../../core/excelHandler';
import { UI_TEXT } from '../../core/schema';
class DomainAssetModal extends BaseModal {
constructor() {
super('domain', '도메인 정보');
}
protected renderFrameHTML(): string {
return `
<div id="domain-asset-modal" class="modal-overlay hidden">
<div class="modal-content wide">
<div class="modal-header">
<h2 id="domain-modal-title">${this.title}</h2>
<button id="btn-close-domain-modal" class="btn-icon" aria-label="닫기"><i data-lucide="x"></i></button>
</div>
<div class="modal-body">
<div class="modal-body-split">
<div class="modal-form-area">
<form id="domain-asset-form" class="grid-form">
<input type="hidden" id="domain-id" name="id" />
<div class="form-section-title">기본 정보</div>
<div class="form-group">
<label>구분</label>
<select id="domain-type" name="type">
<option value="호스팅">호스팅</option>
<option value="도메인">도메인</option>
<option value="기타">기타</option>
</select>
</div>
<div class="form-group">
<label>관리법인</label>
<select id="domain-corp" name="corp">${generateOptionsHTML(CORP_LIST)}</select>
</div>
<div class="form-group full-width">
<label>서비스명</label>
<input type="text" id="domain-service-name" name="service_name" required />
</div>
<div class="form-group full-width">
<label>관리도메인</label>
<input type="text" id="domain-name" name="domain_name" required />
</div>
<div class="form-section-title">계약 및 비용</div>
<div class="form-group">
<label>계약시작일</label>
<input type="date" id="domain-start-date" name="start_date" />
</div>
<div class="form-group">
<label>만료예정일</label>
<input type="date" id="domain-expiry-date" name="expiry_date" />
</div>
<div class="form-group">
<label>비용 (연간/월간)</label>
<input type="text" id="domain-price" name="price" oninput="this.value = this.value.replace(/[^0-9]/g, '').replace(/\\\\B(?=(\\\\d{3})+(?!\\\\d))/g, ',')" />
</div>
<div class="form-section-title">담당자 및 비고</div>
<div class="form-group">
<label>정담당자</label>
<input type="text" id="domain-manager-main" name="manager_main" />
</div>
<div class="form-group">
<label>부담당자</label>
<input type="text" id="domain-manager-sub" name="manager_sub" />
</div>
<div class="form-group full-width">
<label>비고</label>
<textarea id="domain-remarks" name="remarks" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-history-area">
<div class="history-header">
<h3><i data-lucide="history" style="width:16px; height:16px;"></i> 변경 이력</h3>
<button type="button" id="btn-add-domain-log" class="btn btn-outline btn-sm">
이력 추가 <i data-lucide="plus" style="width:14px; height:14px;"></i>
</button>
</div>
<div id="domain-history-list" class="history-timeline"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="btn-delete-domain-asset" class="btn btn-outline btn-danger">삭제</button>
<div class="footer-actions">
<button id="btn-revert-domain-edit" class="btn btn-outline hidden">수정 취소</button>
<button id="btn-cancel-domain-modal" class="btn btn-outline">닫기</button>
<button id="btn-save-domain-asset" class="btn btn-primary">수정</button>
</div>
</div>
</div>
</div>
`;
}
protected initChildLogic(onSave: () => void, closeModals: () => void): void {
const saveBtn = document.getElementById('btn-save-domain-asset')!;
const revertBtn = document.getElementById('btn-revert-domain-edit')!;
const deleteBtn = document.getElementById('btn-delete-domain-asset')!;
saveBtn.addEventListener('click', async () => {
if (!this.currentAsset) return;
if (!this.isEditMode) {
this.setEditLockMode('edit');
this.isEditMode = true;
return;
}
const formData = new FormData(this.formEl!);
const updated = { ...this.currentAsset };
formData.forEach((value, key) => { updated[key] = value; });
if (!updated.service_name || !updated.domain_name) {
alert('서비스명과 관리도메인은 필수 입력 사항입니다.');
return;
}
if (await saveAsset('domain', updated)) {
alert(UI_TEXT.MESSAGES.SAVE_SUCCESS);
onSave(); this.close(); closeModals();
}
});
revertBtn.addEventListener('click', () => {
this.setEditLockMode('view');
if (this.currentAsset) this.fillFormData(this.currentAsset);
});
deleteBtn.addEventListener('click', async () => {
if (!this.currentAsset || !confirm(UI_TEXT.MESSAGES.CONFIRM_DELETE)) return;
if (await deleteAsset('domain', this.currentAsset.id)) {
alert('성공적으로 삭제되었습니다.');
onSave(); this.close(); closeModals();
}
});
createIcons({ icons: { History, Plus, Save, CalendarClock, Database } });
}
protected fillFormData(asset: any): void {
setFieldValue('domain-id', asset.id);
setFieldValue('domain-type', asset.type || '호스팅');
setFieldValue('domain-corp', asset.corp || '');
setFieldValue('domain-service-name', asset.service_name || '');
setFieldValue('domain-name', asset.domain_name || '');
setFieldValue('domain-start-date', formatExcelDate(asset.start_date));
setFieldValue('domain-expiry-date', formatExcelDate(asset.expiry_date));
setFieldValue('domain-price', asset.price || '');
setFieldValue('domain-manager-main', asset.manager_main || '');
setFieldValue('domain-manager-sub', asset.manager_sub || '');
setFieldValue('domain-remarks', asset.remarks || '');
this.renderHistory(asset.id);
}
protected onAfterOpen(asset: any, mode: string): void {
const titleEl = document.getElementById('domain-modal-title');
if (titleEl) titleEl.textContent = (mode === 'add') ? '신규 도메인 등록' : '도메인 정보 상세';
const deleteBtn = document.getElementById('btn-delete-domain-asset');
if (deleteBtn) deleteBtn.style.display = (mode === 'add') ? 'none' : 'block';
}
private renderHistory(assetId: string) {
const container = document.getElementById('domain-history-list');
if (!container) return;
const logs = (state.masterData.logs || []).filter(l => l.assetId === assetId);
if (logs.length === 0) { container.innerHTML = '<div class="empty-history">이력이 없습니다.</div>'; return; }
container.innerHTML = logs.map(l => `<div class=\"history-item\"><div class=\"history-date\">${l.date}</div><div class=\"history-user\">${l.user}</div><div class=\"history-details\">${l.details}</div></div>`).join('');
}
}
export const domainModal = new DomainAssetModal();
export function initDomainModal(onSave: () => void, closeModals: () => void) {
domainModal.init(onSave, closeModals);
}
export function openDomainModal(asset: any, mode: 'view' | 'edit' | 'add' = 'view') {
domainModal.open(asset, mode);
}