250 lines
9.6 KiB
TypeScript
250 lines
9.6 KiB
TypeScript
import { state } from '../../core/state';
|
|
import { SoftwareAsset, SWUser } from '../../core/excelHandler';
|
|
import { openModal } from './BaseModal';
|
|
import { createIcons, Edit2, X, Paperclip } from 'lucide';
|
|
import { CORP_LIST, ORG_LIST } from './SharedData';
|
|
import { generateOptionsHTML, setFieldValue, getFieldValue } from './ModalUtils';
|
|
|
|
let currentSwUserAsset: SoftwareAsset | null = null;
|
|
let tempSwUsers: SWUser[] = [];
|
|
|
|
const SW_USER_MODAL_HTML = `
|
|
<div id="sw-user-modal" class="modal-overlay hidden">
|
|
<div class="modal-content wide">
|
|
<div class="modal-header">
|
|
<h2 id="sw-user-title">소프트웨어 사용자 관리</h2>
|
|
<button id="btn-close-sw-user-modal" class="btn-icon"><i data-lucide="x"></i></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="sw-info-summary" id="sw-user-sw-info"></div>
|
|
|
|
<div class="user-list-toolbar" style="display:flex; justify-content:space-between; margin-bottom:1rem; align-items:center;">
|
|
<h3 style="font-size:1rem; font-weight:600;">할당된 사용자 목록</h3>
|
|
<button type="button" id="btn-open-add-user" class="btn btn-primary btn-sm"><i data-lucide="plus"></i> 사용자 추가</button>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>구매법인</th>
|
|
<th>부서/팀</th>
|
|
<th>직위</th>
|
|
<th>이름</th>
|
|
<th>사용기간</th>
|
|
<th>신청서</th>
|
|
<th>관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="sw-user-table-body"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="btn-cancel-sw-user" class="btn btn-outline">취소</button>
|
|
<button id="btn-save-sw-user" class="btn btn-primary">저장</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 사용자 추가/수정 서브 모달 -->
|
|
<div id="sw-user-edit-modal" class="modal-overlay hidden" style="z-index:1100;">
|
|
<div class="modal-content" style="width:400px;">
|
|
<div class="modal-header">
|
|
<h3 id="sw-user-edit-title">사용자 정보</h3>
|
|
<button id="btn-close-user-edit" class="btn-icon"><i data-lucide="x"></i></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="sw-user-edit-form" class="grid-form" style="grid-template-columns: 1fr;">
|
|
<input type="hidden" id="edit-user-index" value="-1" />
|
|
<div class="form-group">
|
|
<label>구매법인</label>
|
|
<select id="new-user-법인">${generateOptionsHTML(CORP_LIST)}</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>부서/팀</label>
|
|
<select id="new-user-부서">${generateOptionsHTML(ORG_LIST)}</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>직위</label>
|
|
<input type="text" id="new-user-직위" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>이름</label>
|
|
<input type="text" id="new-user-이름" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>사용기간</label>
|
|
<input type="text" id="new-user-사용기간" placeholder="ex) 2024-01-01 ~ 2024-12-31" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>신청서 (증빙)</label>
|
|
<input type="file" id="new-user-신청서" />
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="btn-close-user-sub" class="btn btn-outline">취소</button>
|
|
<button id="btn-confirm-user-edit" class="btn btn-primary">확인</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
export function openSwUserModal(asset: SoftwareAsset) {
|
|
currentSwUserAsset = asset;
|
|
const modal = document.getElementById('sw-user-modal')!;
|
|
|
|
const swInfo = document.getElementById('sw-user-sw-info')!;
|
|
swInfo.innerHTML = `
|
|
<div style="background:var(--bg-light); padding:1rem; border-radius:6px; margin-bottom:1.5rem;">
|
|
<div style="font-size:0.8rem; color:var(--text-muted); margin-bottom:0.25rem;">${asset.법인} | ${asset.자산번호}</div>
|
|
<div style="font-size:1.1rem; font-weight:700; color:var(--primary-color);">${asset.제품명}</div>
|
|
</div>
|
|
`;
|
|
|
|
// 기존 사용자 데이터 복사 (원본 보호를 위해 temp 사용)
|
|
const existingMapping = state.masterData.swUsers.find(u => u.sw_id === asset.id);
|
|
tempSwUsers = existingMapping ? JSON.parse(JSON.stringify(existingMapping.userDataList || [])) : [];
|
|
|
|
renderUserList();
|
|
modal.classList.remove('hidden');
|
|
createIcons({ icons: { Edit2, X, Paperclip } });
|
|
}
|
|
|
|
function renderUserList() {
|
|
const tbody = document.getElementById('sw-user-table-body')!;
|
|
tbody.innerHTML = '';
|
|
|
|
if (tempSwUsers.length === 0) {
|
|
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center; padding:2rem; color:var(--text-muted);">할당된 사용자가 없습니다.</td></tr>';
|
|
return;
|
|
}
|
|
|
|
tempSwUsers.forEach((user, idx) => {
|
|
const tr = document.createElement('tr');
|
|
tr.innerHTML = `
|
|
<td>${user.구매법인 || user.법인 || ''}</td>
|
|
<td>${user.부서 || ''}</td>
|
|
<td>${user.직위 || ''}</td>
|
|
<td>${user.이름 || ''}</td>
|
|
<td>${user.사용기간 || ''}</td>
|
|
<td style="text-align:center;">${user.신청서명 ? '<i data-lucide="paperclip" class="text-primary"></i>' : '-'}</td>
|
|
<td>
|
|
<div style="display:flex; gap:0.5rem;">
|
|
<button class="btn btn-outline btn-sm btn-edit-user" data-idx="${idx}">수정</button>
|
|
<button class="btn btn-outline btn-sm btn-danger btn-del-user" data-idx="${idx}">삭제</button>
|
|
</div>
|
|
`;
|
|
tbody.appendChild(tr);
|
|
});
|
|
|
|
// 이벤트 연결
|
|
tbody.querySelectorAll('.btn-edit-user').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const idx = parseInt((e.currentTarget as HTMLElement).getAttribute('data-idx')!);
|
|
openUserEditSubModal(idx);
|
|
});
|
|
});
|
|
|
|
tbody.querySelectorAll('.btn-del-user').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const idx = parseInt((e.currentTarget as HTMLElement).getAttribute('data-idx')!);
|
|
if (confirm('사용자 할당을 삭제하시겠습니까?')) {
|
|
tempSwUsers.splice(idx, 1);
|
|
renderUserList();
|
|
}
|
|
});
|
|
});
|
|
|
|
createIcons({ icons: { Paperclip } });
|
|
}
|
|
|
|
function openUserEditSubModal(idx: number = -1) {
|
|
const subModal = document.getElementById('sw-user-edit-modal')!;
|
|
const form = document.getElementById('sw-user-edit-form') as HTMLFormElement;
|
|
form.reset();
|
|
|
|
setFieldValue('edit-user-index', idx);
|
|
|
|
if (idx > -1) {
|
|
const user = tempSwUsers[idx];
|
|
setFieldValue('new-user-법인', user.구매법인 || user.법인);
|
|
setFieldValue('new-user-부서', user.부서);
|
|
setFieldValue('new-user-직위', user.직위);
|
|
setFieldValue('new-user-이름', user.이름);
|
|
setFieldValue('new-user-사용기간', user.사용기간);
|
|
} else {
|
|
setFieldValue('new-user-법인', currentSwUserAsset?.법인);
|
|
}
|
|
|
|
subModal.classList.remove('hidden');
|
|
}
|
|
|
|
export function initSwUserModal(onSave: () => void, closeModals: () => void) {
|
|
if (!document.getElementById('sw-user-modal')) {
|
|
document.body.insertAdjacentHTML('beforeend', SW_USER_MODAL_HTML);
|
|
}
|
|
|
|
const mainSaveBtn = document.getElementById('btn-save-sw-user')!;
|
|
const addUserBtn = document.getElementById('btn-open-add-user')!;
|
|
const confirmUserBtn = document.getElementById('btn-confirm-user-edit')!;
|
|
|
|
addUserBtn.addEventListener('click', () => openUserEditSubModal());
|
|
|
|
confirmUserBtn.addEventListener('click', () => {
|
|
saveUserDataToList();
|
|
});
|
|
|
|
mainSaveBtn.addEventListener('click', () => {
|
|
if (!currentSwUserAsset) return;
|
|
|
|
// 전역 상태 업데이트
|
|
const existingIdx = state.masterData.swUsers.findIndex(u => u.sw_id === currentSwUserAsset!.id);
|
|
const newMapping = {
|
|
sw_id: currentSwUserAsset!.id,
|
|
userDataList: tempSwUsers
|
|
};
|
|
|
|
if (existingIdx > -1) state.masterData.swUsers[existingIdx] = newMapping as any;
|
|
else state.masterData.swUsers.push(newMapping as any);
|
|
|
|
onSave();
|
|
document.getElementById('sw-user-modal')?.classList.add('hidden');
|
|
});
|
|
|
|
document.getElementById('btn-close-sw-user-modal')?.addEventListener('click', () => {
|
|
document.getElementById('sw-user-modal')?.classList.add('hidden');
|
|
});
|
|
document.getElementById('btn-cancel-sw-user')?.addEventListener('click', () => {
|
|
document.getElementById('sw-user-modal')?.classList.add('hidden');
|
|
});
|
|
document.getElementById('btn-close-user-edit')?.addEventListener('click', () => {
|
|
document.getElementById('sw-user-edit-modal')?.classList.add('hidden');
|
|
});
|
|
document.getElementById('btn-close-user-sub')?.addEventListener('click', () => {
|
|
document.getElementById('sw-user-edit-modal')?.classList.add('hidden');
|
|
});
|
|
}
|
|
|
|
function saveUserDataToList() {
|
|
const idx = parseInt(getFieldValue('edit-user-index'));
|
|
const 신청서Input = document.getElementById('new-user-신청서') as HTMLInputElement;
|
|
const 신청서명 = 신청서Input.files && 신청서Input.files.length > 0 ? 신청서Input.files[0].name : (idx > -1 ? tempSwUsers[idx].신청서명 : '');
|
|
|
|
const userData: any = {
|
|
구매법인: getFieldValue('new-user-법인'),
|
|
부서: getFieldValue('new-user-부서'),
|
|
직위: getFieldValue('new-user-직위'),
|
|
이름: getFieldValue('new-user-이름'),
|
|
사용기간: getFieldValue('new-user-사용기간'),
|
|
신청서명
|
|
};
|
|
|
|
if (idx === -1) tempSwUsers.push(userData);
|
|
else tempSwUsers[idx] = userData;
|
|
|
|
document.getElementById('sw-user-edit-modal')?.classList.add('hidden');
|
|
renderUserList();
|
|
}
|