Fix: Excel upload logic, field mapping for servers, and date format synchronization
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { state } from '../../core/state';
|
||||
import { closeModals, openModal } from './BaseModal';
|
||||
import { CORP_LIST } from './SharedData';
|
||||
import { generateOptionsHTML } from './ModalUtils';
|
||||
import { generateOptionsHTML, setEditLock } from './ModalUtils';
|
||||
import { createIcons, X, Save, Database, CalendarClock, Edit2 } from 'lucide';
|
||||
import { formatExcelDate } from '../../core/excelHandler';
|
||||
|
||||
let currentItem: any = null;
|
||||
|
||||
@@ -12,6 +13,7 @@ const DOMAIN_MODAL_HTML = `
|
||||
<div class="modal-header">
|
||||
<h2 id="domain-modal-title">도메인 정보</h2>
|
||||
<div style="display:flex; gap:0.5rem; align-items:center;">
|
||||
<button id="btn-edit-domain-header" class="btn-icon header-edit-btn" title="수정"><i data-lucide="edit-2"></i></button>
|
||||
<button id="btn-close-domain-modal" class="btn-icon"><i data-lucide="x"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -86,19 +88,23 @@ const DOMAIN_MODAL_HTML = `
|
||||
<!-- Group 3: 기타 (Additional) -->
|
||||
<div class="form-section-title" style="display:flex; align-items:center; gap:0.5rem; margin-top:1.5rem;">
|
||||
<i data-lucide="edit-2" style="width:16px; height:16px; color:var(--primary-color);"></i>
|
||||
기타 사항
|
||||
구매 정보
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width">
|
||||
<label>비고</label>
|
||||
<textarea id="domain-remarks" rows="3" style="width:100%; border:1px solid var(--border-color); border-radius:4px; padding:0.625rem;"></textarea>
|
||||
<label>구매업체</label>
|
||||
<textarea id="domain-remarks" rows="1" style="width:100%; border:1px solid var(--border-color); border-radius:4px; padding:0.625rem;"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="btn-cancel-domain" class="btn btn-outline">취소</button>
|
||||
<button id="btn-save-domain" class="btn btn-primary"><i data-lucide="save"></i> 저장하기</button>
|
||||
<button id="btn-delete-domain" class="btn btn-outline btn-danger">삭제</button>
|
||||
<div class="footer-actions">
|
||||
<button id="btn-revert-domain" class="btn btn-outline hidden">수정 취소</button>
|
||||
<button id="btn-cancel-domain" class="btn btn-outline">닫기</button>
|
||||
<button id="btn-save-domain" class="btn btn-primary"><i data-lucide="save"></i> 저장하기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -112,15 +118,47 @@ export function initDomainModal() {
|
||||
const modal = document.getElementById('domain-asset-modal')!;
|
||||
document.getElementById('btn-close-domain-modal')?.addEventListener('click', () => closeModals());
|
||||
document.getElementById('btn-cancel-domain')?.addEventListener('click', () => closeModals());
|
||||
document.getElementById('btn-save-domain')?.addEventListener('click', () => saveDomain());
|
||||
|
||||
const saveBtn = document.getElementById('btn-save-domain');
|
||||
const revertBtn = document.getElementById('btn-revert-domain');
|
||||
const deleteBtn = document.getElementById('btn-delete-domain');
|
||||
const headerEditBtn = document.getElementById('btn-edit-domain-header');
|
||||
|
||||
saveBtn?.addEventListener('click', () => {
|
||||
if (!currentItem) return;
|
||||
if (saveBtn.textContent === '수정') {
|
||||
setEditLock('domain-asset-form', 'edit', { saveBtnId: 'btn-save-domain', revertBtnId: 'btn-revert-domain' });
|
||||
return;
|
||||
}
|
||||
saveDomain();
|
||||
});
|
||||
|
||||
headerEditBtn?.addEventListener('click', () => {
|
||||
setEditLock('domain-asset-form', 'edit', { saveBtnId: 'btn-save-domain', revertBtnId: 'btn-revert-domain' });
|
||||
});
|
||||
|
||||
revertBtn?.addEventListener('click', () => {
|
||||
setEditLock('domain-asset-form', 'view', { saveBtnId: 'btn-save-domain', revertBtnId: 'btn-revert-domain' });
|
||||
if (currentItem) openDomainModal(currentItem);
|
||||
});
|
||||
|
||||
deleteBtn?.addEventListener('click', () => {
|
||||
if (currentItem && confirm('정말 삭제하시겠습니까?')) {
|
||||
state.masterData.domain = state.masterData.domain.filter(d => d.id !== currentItem.id);
|
||||
saveDomainBatch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function openDomainModal(item: any = null) {
|
||||
currentItem = item;
|
||||
const isEdit = !!item;
|
||||
const mode = isEdit ? 'view' : 'add';
|
||||
|
||||
const titleEl = document.getElementById('domain-modal-title');
|
||||
if (titleEl) titleEl.textContent = isEdit ? '도메인 정보 수정' : '신규 도메인 등록';
|
||||
if (titleEl) titleEl.textContent = isEdit ? '도메인 정보 상세' : '신규 도메인 등록';
|
||||
|
||||
setEditLock('domain-asset-form', mode, { saveBtnId: 'btn-save-domain', revertBtnId: 'btn-revert-domain' });
|
||||
|
||||
const setVal = (id: string, val: any) => {
|
||||
const el = document.getElementById(id) as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
||||
@@ -131,17 +169,40 @@ export function openDomainModal(item: any = null) {
|
||||
setVal('domain-corp', item?.corp || '');
|
||||
setVal('domain-service-name', item?.service_name || '');
|
||||
setVal('domain-name', item?.domain_name || '');
|
||||
setVal('domain-start-date', item?.start_date || '');
|
||||
setVal('domain-expiry-date', item?.expiry_date || '');
|
||||
setVal('domain-start-date', formatExcelDate(item?.start_date));
|
||||
setVal('domain-expiry-date', formatExcelDate(item?.expiry_date));
|
||||
setVal('domain-price', item?.price || '');
|
||||
setVal('domain-manager-main', item?.manager_main || '');
|
||||
setVal('domain-manager-sub', item?.manager_sub || '');
|
||||
setVal('domain-remarks', item?.remarks || '');
|
||||
|
||||
const deleteBtn = document.getElementById('btn-delete-domain');
|
||||
if (deleteBtn) deleteBtn.style.display = isEdit ? 'block' : 'none';
|
||||
|
||||
openModal('domain-asset-modal');
|
||||
createIcons({ icons: { X, Save, Database, CalendarClock, Edit2 } });
|
||||
}
|
||||
|
||||
async function saveDomainBatch() {
|
||||
try {
|
||||
const response = await fetch(`http://${location.hostname}:3000/api/ops/domain/batch`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(state.masterData.domain)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
closeModals();
|
||||
window.dispatchEvent(new CustomEvent('refresh-view'));
|
||||
} else {
|
||||
throw new Error('DB 저장 실패');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('저장 중 오류가 발생했습니다.');
|
||||
}
|
||||
}
|
||||
|
||||
async function saveDomain() {
|
||||
const getVal = (id: string) => (document.getElementById(id) as HTMLInputElement)?.value || '';
|
||||
|
||||
@@ -164,29 +225,17 @@ async function saveDomain() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentItem) {
|
||||
if (currentItem && currentItem.id.startsWith('DOM-')) {
|
||||
// 신규 추가 후 바로 수정하는 경우 등 대응
|
||||
const idx = state.masterData.domain.findIndex(d => d.id === currentItem.id);
|
||||
if (idx > -1) state.masterData.domain[idx] = newDomain;
|
||||
else state.masterData.domain.push(newDomain);
|
||||
} else if (currentItem) {
|
||||
const idx = state.masterData.domain.findIndex(d => d.id === currentItem.id);
|
||||
if (idx > -1) state.masterData.domain[idx] = newDomain;
|
||||
} else {
|
||||
state.masterData.domain.push(newDomain);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`http://${location.hostname}:3000/api/ops/domain/batch`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(state.masterData.domain)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// alert('성공적으로 저장되었습니다.');
|
||||
closeModals();
|
||||
window.dispatchEvent(new CustomEvent('refresh-view'));
|
||||
} else {
|
||||
throw new Error('DB 저장 실패');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('저장 중 오류가 발생했습니다.');
|
||||
}
|
||||
await saveDomainBatch();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user