338 lines
11 KiB
Markdown
338 lines
11 KiB
Markdown
|
|
# 그룹화 및 목록보기 옵션 저장 기능 가이드
|
||
|
|
|
||
|
|
## 📋 개요
|
||
|
|
|
||
|
|
사용자가 설정한 그룹화 컬럼과 목록보기 모드를 LocalStorage에 저장하고, 페이지를 다시 열 때 자동으로 복원하는 기능입니다.
|
||
|
|
|
||
|
|
## 🎯 주요 기능
|
||
|
|
|
||
|
|
1. **그룹화 컬럼 선택 저장**
|
||
|
|
- 사용자가 선택한 그룹화 기준(거래처, 상태 등)을 저장
|
||
|
|
- 페이지 재진입 시 자동으로 그룹화 적용
|
||
|
|
|
||
|
|
2. **목록보기 모드 저장**
|
||
|
|
- 펼쳐보기(expanded) 또는 목록보기(list) 모드 저장
|
||
|
|
- 페이지 재진입 시 저장된 모드로 표시
|
||
|
|
|
||
|
|
## 📦 필요한 컴포넌트
|
||
|
|
|
||
|
|
```html
|
||
|
|
<!-- 필수 CSS -->
|
||
|
|
<link rel="stylesheet" href="css/userOptions.css">
|
||
|
|
|
||
|
|
<!-- 필수 스크립트 -->
|
||
|
|
<script src="js/components/userOptions.js"></script>
|
||
|
|
<script src="js/components/groupBy.js"></script>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 구현 방법
|
||
|
|
|
||
|
|
### 1. 사용자옵션 모달 초기화
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// ========== 사용자옵션 모달 초기화 ==========
|
||
|
|
function initUserOptionsModal() {
|
||
|
|
const modalHtml = createUserOptionsModal({
|
||
|
|
pageId: 'shipmentPlan', // 페이지별 고유 ID (localStorage 키로 사용)
|
||
|
|
enableGrouping: true, // 그룹화 기능 활성화
|
||
|
|
groupingColumns: [ // 그룹화 가능한 컬럼 목록
|
||
|
|
{ key: 'customer', label: '거래처' },
|
||
|
|
{ key: 'status', label: '상태' },
|
||
|
|
{ key: 'itemCode', label: '품번' },
|
||
|
|
{ key: 'material', label: '재질' },
|
||
|
|
{ key: 'shippingPlanDate', label: '출하계획일' }
|
||
|
|
],
|
||
|
|
enableFreezeColumns: false, // 틀고정 비활성화 (선택사항)
|
||
|
|
enableGridLines: false, // 그리드선 비활성화 (선택사항)
|
||
|
|
enableViewMode: false, // 보기모드 비활성화 (선택사항)
|
||
|
|
onSave: () => {
|
||
|
|
console.log('✅ 사용자 옵션 저장됨');
|
||
|
|
// 저장된 옵션 즉시 적용
|
||
|
|
restoreGroupingOptions();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
document.body.insertAdjacentHTML('beforeend', modalHtml);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 저장된 옵션 복원 함수
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// ========== 저장된 그룹화 옵션 복원 ==========
|
||
|
|
function restoreGroupingOptions() {
|
||
|
|
if (typeof getGroupByColumn === 'function' && typeof getGroupListView === 'function') {
|
||
|
|
const savedColumn = getGroupByColumn('shipmentPlan'); // pageId와 동일하게
|
||
|
|
const savedListView = getGroupListView('shipmentPlan');
|
||
|
|
|
||
|
|
console.log('💾 저장된 그룹화 옵션:', { savedColumn, savedListView });
|
||
|
|
|
||
|
|
// 저장된 그룹화 컬럼이 있으면 적용
|
||
|
|
if (savedColumn && groupByInstance) {
|
||
|
|
setTimeout(() => {
|
||
|
|
groupByInstance.addGrouping(savedColumn);
|
||
|
|
|
||
|
|
// 목록보기 옵션 복원
|
||
|
|
if (savedListView) {
|
||
|
|
isGroupCollapsedView = true;
|
||
|
|
const checkbox = document.getElementById('collapseGroupsCheckbox');
|
||
|
|
if (checkbox) {
|
||
|
|
checkbox.checked = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
renderShipmentTable(); // 또는 해당 페이지의 테이블 렌더링 함수
|
||
|
|
console.log('✅ 그룹화 옵션 복원 완료');
|
||
|
|
}, 300);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 그룹 컴포넌트 초기화 시 복원 호출
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
function initGroupBy() {
|
||
|
|
try {
|
||
|
|
// DOM 요소 확인
|
||
|
|
const selectElement = document.getElementById('groupByField');
|
||
|
|
const tagsElement = document.getElementById('groupByTags');
|
||
|
|
|
||
|
|
if (!selectElement || !tagsElement) {
|
||
|
|
console.error('그룹화 DOM 요소를 찾을 수 없습니다.');
|
||
|
|
setTimeout(() => initGroupBy(), 200);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
groupByInstance = new GroupByComponent({
|
||
|
|
fields: {
|
||
|
|
'customer': '거래처',
|
||
|
|
'status': '상태',
|
||
|
|
'itemCode': '품번',
|
||
|
|
'material': '재질',
|
||
|
|
'shippingPlanDate': '출하계획일'
|
||
|
|
},
|
||
|
|
onGroupChange: () => {
|
||
|
|
// 그룹화 여부에 따라 목록보기 체크박스 표시/숨김
|
||
|
|
const toggleElement = document.getElementById('groupViewToggle');
|
||
|
|
if (toggleElement) {
|
||
|
|
if (groupByInstance.isGrouped()) {
|
||
|
|
toggleElement.style.display = 'flex';
|
||
|
|
} else {
|
||
|
|
toggleElement.style.display = 'none';
|
||
|
|
isGroupCollapsedView = false;
|
||
|
|
const checkbox = document.getElementById('collapseGroupsCheckbox');
|
||
|
|
if (checkbox) checkbox.checked = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
renderShipmentTable();
|
||
|
|
},
|
||
|
|
selectId: 'groupByField',
|
||
|
|
tagsId: 'groupByTags'
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log('✅ 그룹 컴포넌트 초기화 완료');
|
||
|
|
|
||
|
|
// 저장된 그룹화 옵션 복원
|
||
|
|
restoreGroupingOptions();
|
||
|
|
} catch (error) {
|
||
|
|
console.error('❌ 그룹 컴포넌트 초기화 실패:', error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. DOMContentLoaded 이벤트에서 초기화
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
|
// 검색 섹션 초기화
|
||
|
|
initSearchSection();
|
||
|
|
|
||
|
|
// 테이블 액션바 초기화
|
||
|
|
initActionBar();
|
||
|
|
|
||
|
|
// 그룹 컴포넌트 초기화 (ActionBar 이후에 초기화)
|
||
|
|
setTimeout(() => {
|
||
|
|
initGroupBy();
|
||
|
|
}, 100);
|
||
|
|
|
||
|
|
// 데이터 로드 및 렌더링
|
||
|
|
loadShipmentData();
|
||
|
|
renderShipmentTable();
|
||
|
|
|
||
|
|
// 사용자옵션 모달 초기화
|
||
|
|
initUserOptionsModal();
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## 💾 저장되는 데이터 구조
|
||
|
|
|
||
|
|
LocalStorage에 다음과 같이 저장됩니다:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// 그룹화 컬럼
|
||
|
|
localStorage.setItem('shipmentPlan_groupByColumn', 'customer');
|
||
|
|
|
||
|
|
// 목록보기 여부
|
||
|
|
localStorage.setItem('shipmentPlan_groupListView', 'true');
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔑 주요 함수
|
||
|
|
|
||
|
|
### userOptions.js에서 제공하는 함수
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// 그룹화 컬럼 가져오기
|
||
|
|
getGroupByColumn(pageId) // 반환: string (컬럼 키)
|
||
|
|
|
||
|
|
// 목록보기 모드 가져오기
|
||
|
|
getGroupListView(pageId) // 반환: boolean
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📝 HTML 구조 요구사항
|
||
|
|
|
||
|
|
### 테이블 액션바에 그룹화 UI 포함
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
leftExtraHtml: `
|
||
|
|
<select class="groupby-select" id="groupByField" onchange="window.addGroupBy && window.addGroupBy()">
|
||
|
|
<option value="">⚙️ Group by</option>
|
||
|
|
<option value="customer">거래처</option>
|
||
|
|
<option value="status">상태</option>
|
||
|
|
<option value="itemCode">품번</option>
|
||
|
|
<option value="material">재질</option>
|
||
|
|
<option value="shippingPlanDate">출하계획일</option>
|
||
|
|
</select>
|
||
|
|
<div class="groupby-tags" id="groupByTags"></div>
|
||
|
|
<label id="groupViewToggle" style="display: none; align-items: center; gap: 6px; margin-left: 12px; padding: 6px 12px; background: #f3f4f6; border-radius: 6px; cursor: pointer; font-size: 13px; user-select: none;">
|
||
|
|
<input type="checkbox" id="collapseGroupsCheckbox" onchange="toggleGroupView()" style="cursor: pointer;">
|
||
|
|
<span>📋 목록보기</span>
|
||
|
|
</label>
|
||
|
|
`
|
||
|
|
```
|
||
|
|
|
||
|
|
### 사용자옵션 버튼
|
||
|
|
|
||
|
|
```html
|
||
|
|
<button class="btn btn-secondary" onclick="openUserOptions()">⚙️ 사용자옵션</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎨 사용자 경험
|
||
|
|
|
||
|
|
### 저장 과정
|
||
|
|
1. 사용자가 "⚙️ 사용자옵션" 버튼 클릭
|
||
|
|
2. 모달에서 "기타옵션" 탭 선택
|
||
|
|
3. "📊 그룹화 설정" 섹션에서:
|
||
|
|
- 그룹화 컬럼 선택 (예: 거래처)
|
||
|
|
- 보기 모드 선택 (펼쳐보기 / 목록보기)
|
||
|
|
4. "💾 저장" 버튼 클릭
|
||
|
|
5. 옵션이 LocalStorage에 저장되고 즉시 적용됨
|
||
|
|
|
||
|
|
### 복원 과정
|
||
|
|
1. 페이지 로드 시 `DOMContentLoaded` 이벤트 발생
|
||
|
|
2. `initGroupBy()` 함수에서 `restoreGroupingOptions()` 호출
|
||
|
|
3. LocalStorage에서 저장된 옵션 읽기
|
||
|
|
4. 그룹화 컬럼이 있으면 자동으로 적용
|
||
|
|
5. 목록보기 모드가 true면 체크박스 체크 및 접힌 상태로 렌더링
|
||
|
|
|
||
|
|
## 🔍 디버깅
|
||
|
|
|
||
|
|
콘솔에서 다음과 같은 로그를 확인할 수 있습니다:
|
||
|
|
|
||
|
|
```
|
||
|
|
✅ 그룹 컴포넌트 초기화 완료
|
||
|
|
💾 저장된 그룹화 옵션: {savedColumn: "customer", savedListView: true}
|
||
|
|
✅ 그룹화 옵션 복원 완료
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📌 다른 메뉴에 적용하기
|
||
|
|
|
||
|
|
### 1단계: pageId 변경
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const modalHtml = createUserOptionsModal({
|
||
|
|
pageId: 'yourPageId', // 예: 'orderManagement', 'productInfo' 등
|
||
|
|
enableGrouping: true,
|
||
|
|
groupingColumns: [
|
||
|
|
// 해당 페이지의 그룹화 가능한 컬럼 정의
|
||
|
|
{ key: 'column1', label: '컬럼1' },
|
||
|
|
{ key: 'column2', label: '컬럼2' }
|
||
|
|
],
|
||
|
|
onSave: () => {
|
||
|
|
restoreGroupingOptions();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2단계: restoreGroupingOptions에서 pageId 일치시키기
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
function restoreGroupingOptions() {
|
||
|
|
const savedColumn = getGroupByColumn('yourPageId'); // pageId와 동일하게
|
||
|
|
const savedListView = getGroupListView('yourPageId');
|
||
|
|
// ... 복원 로직
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3단계: groupByInstance 필드 일치시키기
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
groupByInstance = new GroupByComponent({
|
||
|
|
fields: {
|
||
|
|
'column1': '컬럼1',
|
||
|
|
'column2': '컬럼2'
|
||
|
|
// groupingColumns의 key와 일치해야 함
|
||
|
|
},
|
||
|
|
// ...
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## ⚠️ 주의사항
|
||
|
|
|
||
|
|
1. **pageId 일관성**:
|
||
|
|
- `createUserOptionsModal`의 `pageId`
|
||
|
|
- `getGroupByColumn`의 인자
|
||
|
|
- `getGroupListView`의 인자
|
||
|
|
- 모두 동일한 값이어야 합니다.
|
||
|
|
|
||
|
|
2. **컬럼 키 일관성**:
|
||
|
|
- `groupingColumns`의 `key`
|
||
|
|
- `GroupByComponent`의 `fields` 키
|
||
|
|
- 테이블 액션바의 `<option value="">`
|
||
|
|
- 모두 일치해야 합니다.
|
||
|
|
|
||
|
|
3. **타이밍**:
|
||
|
|
- `restoreGroupingOptions`는 `groupByInstance`가 생성된 후 호출
|
||
|
|
- 보통 300ms 정도의 딜레이가 안전합니다.
|
||
|
|
|
||
|
|
4. **전역 변수**:
|
||
|
|
- `groupByInstance`: GroupByComponent 인스턴스
|
||
|
|
- `isGroupCollapsedView`: 목록보기 모드 플래그
|
||
|
|
|
||
|
|
## 🚀 완성된 예시
|
||
|
|
|
||
|
|
출하계획관리 페이지(`화면개발/출하계획관리.html`)를 참고하세요. 완전히 구현된 예시입니다.
|
||
|
|
|
||
|
|
## 📚 관련 파일
|
||
|
|
|
||
|
|
- `화면개발/js/components/userOptions.js` - 사용자옵션 컴포넌트
|
||
|
|
- `화면개발/js/components/groupBy.js` - 그룹화 컴포넌트
|
||
|
|
- `화면개발/css/userOptions.css` - 사용자옵션 스타일
|
||
|
|
- `화면개발/출하계획관리.html` - 구현 예시
|
||
|
|
|
||
|
|
## 📞 문의
|
||
|
|
|
||
|
|
이 기능에 대한 질문이나 문제가 있으면 AI 어시스턴트에게 문의하세요.
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|