프로젝트 시스템 통합 및 전반적인 개선사항
- 솔루션 설정 및 프로젝트 파일 업데이트 - BaseController 최적화 (HtmlAgilityPack 의존성 제거) - CommonController 네비게이션 메뉴에 프로젝트 추가 - JobreportController 사용자 조회 기능 및 필터링 개선 - 모든 웹 화면 UI/UX 통합 및 일관성 개선 - 프로그램 시작 시 중복 실행 감지 개선 - 각종 폼 및 데이터셋 디자이너 업데이트 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -92,71 +92,95 @@
|
||||
select option:checked {
|
||||
background-color: #6366F1 !important;
|
||||
}
|
||||
|
||||
/* 테이블 셀 텍스트 오버플로우 처리 */
|
||||
.truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 값(문자열) 열 최대 너비 제한 */
|
||||
.svalue-cell {
|
||||
max-width: 128px; /* w-32 = 128px */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="gradient-bg min-h-screen">
|
||||
<body class="bg-gradient-to-br from-blue-900 via-purple-900 to-indigo-900 min-h-screen text-white">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<!-- 개발중 경고 메시지 -->
|
||||
<div class="bg-orange-500 rounded-lg p-4 mb-6 border-l-4 border-orange-700 animate-slide-up shadow-lg">
|
||||
<div class="flex items-center">
|
||||
<svg class="w-5 h-5 text-orange-900 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="text-white font-bold text-base">🚧 개발중인 기능입니다</p>
|
||||
<p class="text-orange-100 text-sm font-medium">일부 기능이 정상적으로 동작하지 않을 수 있습니다.</p>
|
||||
|
||||
<!-- 2열 구조 메인 컨테이너 -->
|
||||
<div class="flex gap-6 h-[calc(100vh-200px)]">
|
||||
<!-- 좌측: 코드그룹 리스트 -->
|
||||
<div class="w-80">
|
||||
<div class="glass-effect rounded-2xl h-full card-hover animate-slide-up flex flex-col">
|
||||
<div class="p-4 border-b border-white/10">
|
||||
<h3 class="text-lg font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14-7l-7 7-7-7M19 21l-7-7-7 7"></path>
|
||||
</svg>
|
||||
코드그룹 목록
|
||||
</h3>
|
||||
</div>
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar p-2">
|
||||
<div id="groupList" class="space-y-1">
|
||||
<!-- 그룹 목록이 여기에 표시됩니다 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 검색 및 필터 -->
|
||||
<div class="glass-effect rounded-2xl p-6 mb-6 card-hover animate-slide-up">
|
||||
<div class="flex flex-wrap gap-4 items-end">
|
||||
<div class="flex-1 min-w-0">
|
||||
<label class="block text-sm font-medium text-white/70 mb-2">코드그룹</label>
|
||||
<select id="grpFilter" class="w-full px-3 py-2 bg-white/20 backdrop-blur-sm border border-white/30 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-primary-400 transition-all">
|
||||
<!-- 동적으로 로드됩니다 -->
|
||||
</select>
|
||||
<!-- 우측: 상세 데이터 -->
|
||||
<div class="flex-1">
|
||||
<div class="glass-effect rounded-2xl h-full card-hover animate-slide-up flex flex-col">
|
||||
<!-- 상단 헤더 -->
|
||||
<div class="p-4 border-b border-white/10 flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
<span id="selectedGroupTitle">코드그룹을 선택하세요</span>
|
||||
</h3>
|
||||
<p class="text-white/70 text-sm mt-1">총 <span id="recordCount" class="text-white font-medium">0</span>건</p>
|
||||
</div>
|
||||
<button onclick="showAddModal()" class="bg-white/20 hover:bg-white/30 backdrop-blur-sm text-white px-4 py-2 rounded-lg transition-all border border-white/30 flex items-center text-sm">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
||||
</svg>
|
||||
추가
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 데이터 테이블 -->
|
||||
<div class="flex-1 overflow-x-auto overflow-y-auto custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="w-24 px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">코드</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">비고</th>
|
||||
<th class="w-32 px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(문자열)</th>
|
||||
<th class="w-20 px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(숫자)</th>
|
||||
<th class="w-20 px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(실수)</th>
|
||||
<th class="w-24 px-4 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dataTable" class="divide-y divide-white/10">
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-8 text-center text-white/70">
|
||||
<svg class="w-12 h-12 mx-auto mb-2 text-white/30" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
좌측에서 코드그룹을 선택하세요
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button onclick="loadData()" class="bg-white/20 hover:bg-white/30 backdrop-blur-sm text-white px-6 py-2 rounded-lg transition-all border border-white/30 flex items-center">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||
</svg>
|
||||
조회
|
||||
</button>
|
||||
<button onclick="showAddModal()" class="bg-white/20 hover:bg-white/30 backdrop-blur-sm text-white px-6 py-2 rounded-lg transition-all border border-white/30 flex items-center">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
||||
</svg>
|
||||
추가
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 데이터 테이블 -->
|
||||
<div class="glass-effect rounded-2xl overflow-hidden card-hover animate-slide-up">
|
||||
<div class="overflow-x-auto max-h-[calc(100vh-300px)] overflow-y-auto custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">코드</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">비고</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(문자열)</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(숫자)</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값(실수)</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">값2</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-white/70 uppercase tracking-wider">작업</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dataTable" class="divide-y divide-white/10">
|
||||
<!-- 데이터가 여기에 표시됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="px-6 py-3 border-t border-white/10 bg-white/5">
|
||||
<p class="text-white/70 text-sm text-center">총 <span id="recordCount" class="text-white font-medium">0</span>건</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -224,13 +248,21 @@
|
||||
</form>
|
||||
|
||||
<!-- 모달 푸터 -->
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-end gap-2">
|
||||
<button onclick="hideEditModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
취소
|
||||
</button>
|
||||
<button onclick="saveData()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
저장
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-between">
|
||||
<button onclick="deleteCurrentItem()" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors flex items-center">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
||||
</svg>
|
||||
삭제
|
||||
</button>
|
||||
<div class="flex gap-2">
|
||||
<button onclick="hideEditModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
취소
|
||||
</button>
|
||||
<button onclick="saveData()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
저장
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,7 +284,7 @@
|
||||
<p class="text-sm text-gray-500">이 작업은 되돌릴 수 없습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-700 mb-6">선택한 공용코드를 삭제하시겠습니까?</p>
|
||||
<p class="text-gray-700 mb-6">선택한 공용코드를 삭제하시겠습니까?<br><span class="text-sm text-gray-500">이 작업은 되돌릴 수 없습니다.</span></p>
|
||||
<div class="flex justify-end gap-2">
|
||||
<button onclick="hideDeleteModal()" class="bg-gray-300 hover:bg-gray-400 text-gray-700 px-4 py-2 rounded-lg transition-colors">
|
||||
취소
|
||||
@@ -331,22 +363,33 @@
|
||||
return `
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-xl font-bold text-white">GroupWare</h2>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center space-x-8">
|
||||
${visibleItems.map(item => this.getMenuItemHTML(item)).join('')}
|
||||
</div>
|
||||
<div class="md:hidden">
|
||||
<button id="mobile-menu-button" class="text-white/80 hover:text-white transition-colors p-2">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
||||
<div class="flex items-center space-x-8">
|
||||
<div class="flex items-center space-x-2">
|
||||
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="text-xl font-bold text-white">GroupWare</span>
|
||||
</div>
|
||||
<nav class="hidden md:flex space-x-1">
|
||||
${visibleItems.map(item => `
|
||||
<a href="${item.url}" class="px-3 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||
this.currentPage === item.key
|
||||
? 'bg-white/20 text-white'
|
||||
: 'text-white/60 hover:text-white hover:bg-white/10'
|
||||
}">
|
||||
<svg class="w-4 h-4 inline mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="${item.icon}"></path>
|
||||
</svg>
|
||||
${item.title}
|
||||
</a>
|
||||
`).join('')}
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="text-sm text-white/60">
|
||||
<span id="currentUser">사용자</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mobile-menu" class="md:hidden hidden border-t border-white/10 pt-4 pb-4">
|
||||
${visibleItems.map(item => this.getMobileMenuItemHTML(item)).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -396,6 +439,7 @@
|
||||
let currentData = [];
|
||||
let deleteTargetIdx = null;
|
||||
let groupData = [];
|
||||
let selectedGroupCode = null;
|
||||
|
||||
// 페이지 로드시 초기 데이터 로드
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -410,11 +454,8 @@
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
groupData = data || [];
|
||||
renderGroupSelects();
|
||||
|
||||
// 기본적으로 "99-전체" 선택
|
||||
document.getElementById('grpFilter').value = '99';
|
||||
loadData();
|
||||
renderGroupList();
|
||||
renderEditGroupSelect();
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -424,38 +465,64 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 셀렉트 박스들에 그룹 옵션 렌더링
|
||||
function renderGroupSelects() {
|
||||
const grpFilter = document.getElementById('grpFilter');
|
||||
// 좌측 그룹 리스트 렌더링
|
||||
function renderGroupList() {
|
||||
const groupList = document.getElementById('groupList');
|
||||
|
||||
if (groupData.length === 0) {
|
||||
groupList.innerHTML = '<div class="text-white/70 text-center py-4">그룹 데이터가 없습니다.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
groupList.innerHTML = groupData.map(group => `
|
||||
<div class="group-item cursor-pointer p-3 rounded-lg border border-white/20 hover:bg-white/10 transition-all ${selectedGroupCode === group.code ? 'bg-white/20' : ''}"
|
||||
onclick="selectGroup('${group.code}', '${group.memo}')">
|
||||
<div class="flex items-center">
|
||||
<div class="w-8 h-8 bg-white/20 rounded-full flex items-center justify-center mr-3">
|
||||
<span class="text-white text-sm font-medium">${group.code}</span>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white font-medium">${group.memo}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// 그룹 선택 처리
|
||||
function selectGroup(code, name) {
|
||||
selectedGroupCode = code;
|
||||
|
||||
// 선택된 그룹 하이라이트 업데이트
|
||||
document.querySelectorAll('.group-item').forEach(item => {
|
||||
item.classList.remove('bg-white/20');
|
||||
});
|
||||
event.target.closest('.group-item').classList.add('bg-white/20');
|
||||
|
||||
// 우측 제목 업데이트
|
||||
document.getElementById('selectedGroupTitle').textContent = `${code} - ${name}`;
|
||||
|
||||
// 해당 그룹의 데이터 로드
|
||||
loadDataByGroup(code);
|
||||
}
|
||||
|
||||
// 편집 모달용 그룹 셀렉트 렌더링
|
||||
function renderEditGroupSelect() {
|
||||
const editGrp = document.getElementById('editGrp');
|
||||
|
||||
// 필터 셀렉트박스 - "99-전체" 옵션 추가
|
||||
const filterOptions = [
|
||||
'<option value="99" class="bg-gray-800 text-white">99-전체</option>'
|
||||
].concat(
|
||||
groupData.map(group =>
|
||||
`<option value="${group.code}" class="bg-gray-800 text-white">${group.code}-${group.svalue}</option>`
|
||||
)
|
||||
);
|
||||
grpFilter.innerHTML = filterOptions.join('');
|
||||
|
||||
// 편집 모달 셀렉트박스
|
||||
editGrp.innerHTML = '<option value="" class="bg-gray-800 text-white">선택하세요</option>' +
|
||||
groupData.map(group =>
|
||||
`<option value="${group.code}" class="bg-gray-800 text-white">${group.code}-${group.svalue}</option>`
|
||||
`<option value="${group.code}" class="bg-gray-800 text-white">${group.code}-${group.memo}</option>`
|
||||
).join('');
|
||||
}
|
||||
|
||||
// 데이터 로드
|
||||
function loadData() {
|
||||
const grp = document.getElementById('grpFilter').value;
|
||||
// 특정 그룹의 데이터 로드
|
||||
function loadDataByGroup(grp) {
|
||||
showLoading();
|
||||
|
||||
let url = 'http://127.0.0.1:7979/Common/GetList';
|
||||
if (grp && grp !== '99') {
|
||||
if (grp) {
|
||||
url += '?grp=' + encodeURIComponent(grp);
|
||||
}
|
||||
// grp가 '99'이면 모든 그룹의 데이터를 가져옴 (파라미터 없음)
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
@@ -475,11 +542,18 @@
|
||||
function renderTable() {
|
||||
const tbody = document.getElementById('dataTable');
|
||||
const recordCount = document.getElementById('recordCount');
|
||||
const selectedGrp = document.getElementById('grpFilter').value;
|
||||
const showAllGroups = selectedGrp === '99';
|
||||
|
||||
if (currentData.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="px-6 py-4 text-center text-white/70">데이터가 없습니다.</td></tr>';
|
||||
tbody.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-8 text-center text-white/70">
|
||||
<svg class="w-12 h-12 mx-auto mb-2 text-white/30" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
${selectedGroupCode ? '데이터가 없습니다.' : '좌측에서 코드그룹을 선택하세요'}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
recordCount.textContent = '0';
|
||||
return;
|
||||
}
|
||||
@@ -487,35 +561,14 @@
|
||||
recordCount.textContent = currentData.length;
|
||||
|
||||
tbody.innerHTML = currentData.map(item => {
|
||||
// 전체 보기일 때는 코드에 그룹 정보도 표시
|
||||
let codeDisplay = item.code || '-';
|
||||
if (showAllGroups && item.grp) {
|
||||
// 그룹 데이터에서 해당 그룹의 이름 찾기
|
||||
const groupInfo = groupData.find(g => g.code === item.grp);
|
||||
const groupName = groupInfo ? groupInfo.svalue : item.grp;
|
||||
codeDisplay = `${item.grp}-${groupName}`;
|
||||
}
|
||||
|
||||
return `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">${codeDisplay}</td>
|
||||
<td class="px-6 py-4 text-sm text-white">${item.memo || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">${item.svalue || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">${item.ivalue || '0'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">${item.fvalue || '0.0'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">${item.svalue2 || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<button onclick="editItem(${item.idx})" class="text-blue-400 hover:text-blue-300 mr-2 transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button onclick="deleteItem(${item.idx})" class="text-red-400 hover:text-red-300 transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</td>
|
||||
<tr class="hover:bg-white/5 transition-colors cursor-pointer" onclick="editItem(${item.idx})">
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-white">${item.code || '-'}</td>
|
||||
<td class="px-4 py-4 text-sm text-white">${item.memo || '-'}</td>
|
||||
<td class="px-4 py-4 text-sm text-white svalue-cell" title="${item.svalue || '-'}">${item.svalue || '-'}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-white">${item.ivalue || '0'}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-white">${item.fvalue || '0.0'}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-white">${item.svalue2 || '-'}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
@@ -523,13 +576,24 @@
|
||||
|
||||
// 추가 모달 표시
|
||||
function showAddModal() {
|
||||
if (!selectedGroupCode) {
|
||||
showNotification('먼저 코드그룹을 선택하세요.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('modalTitle').textContent = '공용코드 추가';
|
||||
document.getElementById('editForm').reset();
|
||||
document.getElementById('editIdx').value = '';
|
||||
|
||||
// 현재 선택된 코드그룹을 자동 입력
|
||||
const selectedGrp = document.getElementById('grpFilter').value;
|
||||
document.getElementById('editGrp').value = selectedGrp;
|
||||
document.getElementById('editGrp').value = selectedGroupCode;
|
||||
|
||||
// 삭제 버튼 비활성화 (새로 추가하는 항목이므로)
|
||||
const deleteBtn = document.querySelector('#editModal button[onclick="deleteCurrentItem()"]');
|
||||
if (deleteBtn) {
|
||||
deleteBtn.disabled = true;
|
||||
deleteBtn.classList.add('opacity-50', 'cursor-not-allowed');
|
||||
}
|
||||
|
||||
document.getElementById('editModal').classList.remove('hidden');
|
||||
}
|
||||
@@ -549,6 +613,13 @@
|
||||
document.getElementById('editSvalue2').value = item.svalue2 || '';
|
||||
document.getElementById('editMemo').value = item.memo || '';
|
||||
|
||||
// 삭제 버튼 활성화 (기존 항목 편집이므로)
|
||||
const deleteBtn = document.querySelector('#editModal button[onclick="deleteCurrentItem()"]');
|
||||
if (deleteBtn) {
|
||||
deleteBtn.disabled = false;
|
||||
deleteBtn.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||
}
|
||||
|
||||
document.getElementById('editModal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
@@ -588,7 +659,10 @@
|
||||
if (data.Success) {
|
||||
showNotification(data.Message, 'success');
|
||||
hideDeleteModal();
|
||||
loadData(); // 데이터 새로고침
|
||||
// 현재 선택된 그룹의 데이터 새로고침
|
||||
if (selectedGroupCode) {
|
||||
loadDataByGroup(selectedGroupCode);
|
||||
}
|
||||
} else {
|
||||
showNotification(data.Message, 'error');
|
||||
}
|
||||
@@ -600,6 +674,19 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 편집 다이얼로그에서 현재 항목 삭제
|
||||
function deleteCurrentItem() {
|
||||
const editIdx = document.getElementById('editIdx').value;
|
||||
if (!editIdx) {
|
||||
showNotification('삭제할 항목이 없습니다.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
deleteTargetIdx = parseInt(editIdx);
|
||||
hideEditModal();
|
||||
document.getElementById('deleteModal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 데이터 저장
|
||||
function saveData() {
|
||||
const form = document.getElementById('editForm');
|
||||
@@ -634,7 +721,10 @@
|
||||
if (result.Success) {
|
||||
showNotification(result.Message, 'success');
|
||||
hideEditModal();
|
||||
loadData(); // 데이터 새로고침
|
||||
// 현재 선택된 그룹의 데이터 새로고침
|
||||
if (selectedGroupCode) {
|
||||
loadDataByGroup(selectedGroupCode);
|
||||
}
|
||||
} else {
|
||||
showNotification(result.Message, 'error');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user