242 lines
11 KiB
TypeScript
242 lines
11 KiB
TypeScript
import { state } from '../../core/state';
|
|
import { SoftwareAsset, SWUser } from '../../core/excelHandler';
|
|
import { openModal } from './BaseModal';
|
|
import { createIcons, Edit2, X, Paperclip } from 'lucide';
|
|
|
|
let currentSwUserAssetId: string = '';
|
|
let tempSwUsers: SWUser[] = [];
|
|
|
|
const SW_USER_MODAL_HTML = `
|
|
<!-- S/W 할당 사용자 목록 모달 -->
|
|
<div id="sw-user-modal" class="modal-overlay hidden">
|
|
<div class="modal-content" style="max-width: 800px;">
|
|
<div class="modal-header">
|
|
<h2 id="sw-user-modal-title">S/W 할당 사용자 목록</h2>
|
|
<button id="btn-close-sw-user-modal" class="btn-icon" aria-label="닫기"><i data-lucide="x"></i></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<input type="hidden" id="sw-user-asset-id" />
|
|
<div style="text-align: right; margin-bottom: 0.75rem;">
|
|
<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 style="width:100%;">
|
|
<thead>
|
|
<tr>
|
|
<th>법인</th>
|
|
<th>부서/팀</th>
|
|
<th>직위</th>
|
|
<th>이름</th>
|
|
<th>사용기간</th>
|
|
<th>증빙</th>
|
|
<th style="text-align:center;">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="user-list-body"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<div></div>
|
|
<div class="footer-actions">
|
|
<button id="btn-save-sw-user-mapping" class="btn btn-primary">변경사항 저장</button>
|
|
<button id="btn-cancel-sw-user-modal" class="btn btn-outline">닫기</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 사용자 추가/수정 서브 모달 -->
|
|
<div id="sw-user-edit-modal" class="modal-overlay hidden" style="z-index: 1100;">
|
|
<div class="modal-content" style="max-width: 500px;">
|
|
<div class="modal-header">
|
|
<h2 id="sw-user-edit-modal-title">사용자 정보</h2>
|
|
<button id="btn-close-sw-user-edit" class="btn-icon"><i data-lucide="x"></i></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<input type="hidden" id="edit-user-idx" />
|
|
<div class="grid-form" style="grid-template-columns: 1fr;">
|
|
<div class="form-group">
|
|
<label>법인</label>
|
|
<select id="new-user-법인">
|
|
<option value="한맥">한맥</option><option value="삼안">삼안</option><option value="바론">바론</option>
|
|
</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-팀" />
|
|
</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 ~ 2024.12" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>신청서 (증빙파일)</label>
|
|
<input type="file" id="new-user-신청서" />
|
|
<span id="new-user-신청서명" style="font-size:0.75rem; color:var(--text-muted);"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="btn-cancel-sw-user-edit" class="btn btn-outline">취소</button>
|
|
<button id="btn-save-edit-user" class="btn btn-primary">확인</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
export function initSwUserModal(renderContent: () => void, closeModals: () => void) {
|
|
if (!document.getElementById('sw-user-modal')) {
|
|
document.body.insertAdjacentHTML('beforeend', SW_USER_MODAL_HTML);
|
|
}
|
|
|
|
const btnOpenAddUser = document.getElementById('btn-open-add-user');
|
|
const btnSaveEditUser = document.getElementById('btn-save-edit-user');
|
|
const btnSaveSwUserMapping = document.getElementById('btn-save-sw-user-mapping');
|
|
const btnCancelUserEdit = document.getElementById('btn-cancel-sw-user-edit');
|
|
const btnCloseUserEdit = document.getElementById('btn-close-sw-user-edit');
|
|
const btnCancelUserModal = document.getElementById('btn-cancel-sw-user-modal');
|
|
const btnCloseUserModal = document.getElementById('btn-close-sw-user-modal');
|
|
|
|
btnOpenAddUser?.addEventListener('click', () => openUserEditModal(-1));
|
|
btnSaveEditUser?.addEventListener('click', () => saveUserEdit());
|
|
|
|
btnSaveSwUserMapping?.addEventListener('click', () => {
|
|
state.masterData.swUsers = state.masterData.swUsers.filter(u => u.swId !== currentSwUserAssetId);
|
|
state.masterData.swUsers.push(...tempSwUsers);
|
|
document.getElementById('sw-user-modal')?.classList.add('hidden');
|
|
renderContent();
|
|
});
|
|
|
|
btnCancelUserEdit?.addEventListener('click', () => document.getElementById('sw-user-edit-modal')?.classList.add('hidden'));
|
|
btnCloseUserEdit?.addEventListener('click', () => document.getElementById('sw-user-edit-modal')?.classList.add('hidden'));
|
|
btnCancelUserModal?.addEventListener('click', () => document.getElementById('sw-user-modal')?.classList.add('hidden'));
|
|
btnCloseUserModal?.addEventListener('click', () => document.getElementById('sw-user-modal')?.classList.add('hidden'));
|
|
}
|
|
|
|
function renderUserList() {
|
|
const tbody = document.getElementById('user-list-body')!;
|
|
tbody.innerHTML = '';
|
|
if (tempSwUsers.length === 0) {
|
|
tbody.innerHTML = '<tr><td colspan="7" style="padding: 2rem; text-align: center; color: var(--text-muted);">할당된 사용자가 없습니다.</td></tr>';
|
|
return;
|
|
}
|
|
|
|
tempSwUsers.forEach((user, idx) => {
|
|
const tr = document.createElement('tr');
|
|
const deptTeam = [user.부서, user.팀].filter(Boolean).join(' / ') || '-';
|
|
const attachIcon = user.신청서명 ? `<i data-lucide="paperclip" class="text-primary" style="width:16px; height:16px;" title="${user.신청서명}"></i>` : '-';
|
|
|
|
tr.innerHTML = `
|
|
<td>${user.법인}</td>
|
|
<td>${deptTeam}</td>
|
|
<td>${user.직위 || '-'}</td>
|
|
<td><strong>${user.이름}</strong></td>
|
|
<td style="text-align:center;">${user.사용기간 || '-'}</td>
|
|
<td style="text-align:center;">${attachIcon}</td>
|
|
<td style="text-align:center;">
|
|
<button type="button" class="btn-icon btn-edit-user" data-idx="${idx}" style="color: var(--primary-color);"><i data-lucide="edit-2" style="width:14px; height:14px;"></i></button>
|
|
<button type="button" class="btn-icon btn-remove-user" data-idx="${idx}" style="color: var(--danger);"><i data-lucide="x" style="width:14px; height:14px;"></i></button>
|
|
</td>
|
|
`;
|
|
tbody.appendChild(tr);
|
|
});
|
|
|
|
createIcons({ icons: { Edit2, X, Paperclip } });
|
|
|
|
tbody.querySelectorAll('.btn-edit-user').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const idx = parseInt((e.currentTarget as HTMLElement).getAttribute('data-idx')!);
|
|
openUserEditModal(idx);
|
|
});
|
|
});
|
|
|
|
tbody.querySelectorAll('.btn-remove-user').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const idx = parseInt((e.currentTarget as HTMLButtonElement).getAttribute('data-idx')!);
|
|
tempSwUsers.splice(idx, 1);
|
|
renderUserList();
|
|
});
|
|
});
|
|
}
|
|
|
|
export function openSwUserModal(asset: SoftwareAsset) {
|
|
openModal('sw-user-modal');
|
|
currentSwUserAssetId = asset.id;
|
|
tempSwUsers = state.masterData.swUsers.filter(u => u.swId === asset.id).map(u => ({...u}));
|
|
renderUserList();
|
|
}
|
|
|
|
function openUserEditModal(idx: number) {
|
|
const editModal = document.getElementById('sw-user-edit-modal')!;
|
|
editModal.classList.remove('hidden');
|
|
(document.getElementById('edit-user-idx') as HTMLInputElement).value = String(idx);
|
|
|
|
if (idx === -1) {
|
|
document.getElementById('sw-user-edit-modal-title')!.innerText = '새 사용자 추가';
|
|
(document.getElementById('new-user-법인') as HTMLSelectElement).value = '한맥';
|
|
(document.getElementById('new-user-부서') as HTMLInputElement).value = '';
|
|
(document.getElementById('new-user-팀') as HTMLInputElement).value = '';
|
|
(document.getElementById('new-user-직위') as HTMLInputElement).value = '';
|
|
(document.getElementById('new-user-이름') as HTMLInputElement).value = '';
|
|
(document.getElementById('new-user-사용기간') as HTMLInputElement).value = '';
|
|
(document.getElementById('new-user-신청서') as HTMLInputElement).value = '';
|
|
document.getElementById('new-user-신청서명')!.innerText = '';
|
|
} else {
|
|
document.getElementById('sw-user-edit-modal-title')!.innerText = '사용자 정보 수정';
|
|
const u = tempSwUsers[idx];
|
|
(document.getElementById('new-user-법인') as HTMLSelectElement).value = u.법인;
|
|
(document.getElementById('new-user-부서') as HTMLInputElement).value = u.부서;
|
|
(document.getElementById('new-user-팀') as HTMLInputElement).value = u.팀;
|
|
(document.getElementById('new-user-직위') as HTMLInputElement).value = u.직위;
|
|
(document.getElementById('new-user-이름') as HTMLInputElement).value = u.이름;
|
|
(document.getElementById('new-user-사용기간') as HTMLInputElement).value = u.사용기간;
|
|
(document.getElementById('new-user-신청서') as HTMLInputElement).value = '';
|
|
document.getElementById('new-user-신청서명')!.innerText = u.신청서명 ? `첨부: ${u.신청서명}` : '';
|
|
}
|
|
}
|
|
|
|
function saveUserEdit() {
|
|
const idx = parseInt((document.getElementById('edit-user-idx') as HTMLInputElement).value);
|
|
const 이름 = (document.getElementById('new-user-이름') as HTMLInputElement).value.trim();
|
|
if (!이름) { alert('이름을 입력해주세요.'); return; }
|
|
|
|
const fileInput = document.getElementById('new-user-신청서') as HTMLInputElement;
|
|
let 신청서명 = '';
|
|
if (fileInput.files && fileInput.files.length > 0) {
|
|
신청서명 = fileInput.files[0].name;
|
|
} else if (idx !== -1) {
|
|
신청서명 = tempSwUsers[idx].신청서명;
|
|
}
|
|
|
|
const userData: SWUser = {
|
|
id: idx === -1 ? Math.random().toString(36).substring(2, 9) : tempSwUsers[idx].id,
|
|
swId: currentSwUserAssetId,
|
|
법인: (document.getElementById('new-user-법인') as HTMLSelectElement).value,
|
|
부서: (document.getElementById('new-user-부서') as HTMLInputElement).value,
|
|
팀: (document.getElementById('new-user-팀') as HTMLInputElement).value,
|
|
직위: (document.getElementById('new-user-직위') as HTMLInputElement).value,
|
|
이름,
|
|
사용기간: (document.getElementById('new-user-사용기간') as HTMLInputElement).value,
|
|
신청서명
|
|
};
|
|
|
|
if (idx === -1) tempSwUsers.push(userData);
|
|
else tempSwUsers[idx] = userData;
|
|
|
|
document.getElementById('sw-user-edit-modal')?.classList.add('hidden');
|
|
renderUserList();
|
|
}
|