/**
* domain_selector.js
*
* 도메인 지식 선택 시스템
* - 폴더 설정 직후 자동으로 도메인 선택 모달 표시
* - 체크박스로 도메인 선택 → 선택된 .txt 합쳐서 서버 전달
* - "세부 분야별" 선택 시 하위 항목 펼침
*/
// ===== 상태 =====
let domainConfig = null; // 서버에서 로드한 config
let selectedDomains = []; // 선택된 도메인 ID 배열
let domainLoaded = false;
// ===== 초기화 =====
async function loadDomainConfig() {
try {
const resp = await fetch('/api/domain-config');
if (!resp.ok) throw new Error('도메인 설정 로드 실패');
domainConfig = await resp.json();
domainLoaded = true;
console.log('[Domain] 설정 로드 완료:', domainConfig.categories.length, '카테고리');
} catch (e) {
console.error('[Domain] 설정 로드 실패:', e);
// fallback: 빈 config
domainConfig = { categories: [] };
}
}
// 페이지 로드 시 config 가져오기
document.addEventListener('DOMContentLoaded', loadDomainConfig);
// ===== 모달 열기/닫기 =====
function openDomainModal() {
if (!domainConfig || !domainConfig.categories) {
alert('도메인 설정을 불러오는 중입니다. 잠시 후 다시 시도해주세요.');
return;
}
renderDomainModal();
document.getElementById('domainModal').style.display = 'flex';
}
function closeDomainModal() {
document.getElementById('domainModal').style.display = 'none';
}
// ===== 모달 렌더링 =====
function renderDomainModal() {
const container = document.getElementById('domainCategoryList');
if (!container) return;
container.innerHTML = '';
domainConfig.categories.forEach(cat => {
const catDiv = document.createElement('div');
catDiv.className = 'domain-category';
catDiv.dataset.id = cat.id;
// 메인 체크박스 행
const isChecked = selectedDomains.includes(cat.id);
catDiv.innerHTML = `
`;
// 하위 항목이 있으면 서브 패널 추가
if (cat.children && cat.children.length > 0) {
const subPanel = document.createElement('div');
subPanel.className = 'domain-sub-panel';
subPanel.id = `sub_${cat.id}`;
subPanel.style.display = isChecked ? 'block' : 'none';
// 그룹별로 묶기
const groups = {};
cat.children.forEach(child => {
const g = child.group || '기타';
if (!groups[g]) groups[g] = [];
groups[g].push(child);
});
Object.entries(groups).forEach(([groupName, children]) => {
const groupDiv = document.createElement('div');
groupDiv.className = 'domain-sub-group';
groupDiv.innerHTML = `
${groupName}
`;
const chipsDiv = document.createElement('div');
chipsDiv.className = 'domain-sub-chips';
children.forEach(child => {
const childChecked = selectedDomains.includes(child.id);
chipsDiv.innerHTML += `
`;
});
groupDiv.appendChild(chipsDiv);
subPanel.appendChild(groupDiv);
});
catDiv.appendChild(subPanel);
}
container.appendChild(catDiv);
});
// 선택 요약 업데이트
updateDomainSummary();
}
// ===== 선택 로직 =====
function toggleDomainCategory(catId, checked) {
const cat = domainConfig.categories.find(c => c.id === catId);
if (!cat) return;
if (checked) {
// 카테고리 추가
if (!selectedDomains.includes(catId)) {
selectedDomains.push(catId);
}
// 하위 항목이 있으면 서브 패널 펼침
if (cat.children && cat.children.length > 0) {
const subPanel = document.getElementById(`sub_${catId}`);
if (subPanel) subPanel.style.display = 'block';
const expand = document.getElementById(`expand_${catId}`);
if (expand) expand.classList.add('open');
}
} else {
// 카테고리 제거
selectedDomains = selectedDomains.filter(d => d !== catId);
// 하위 항목도 전부 제거
if (cat.children) {
cat.children.forEach(child => {
selectedDomains = selectedDomains.filter(d => d !== child.id);
});
const subPanel = document.getElementById(`sub_${catId}`);
if (subPanel) subPanel.style.display = 'none';
const expand = document.getElementById(`expand_${catId}`);
if (expand) expand.classList.remove('open');
}
}
renderDomainModal();
}
function toggleDomainChild(parentId, childId, checked) {
if (checked) {
if (!selectedDomains.includes(childId)) {
selectedDomains.push(childId);
}
} else {
selectedDomains = selectedDomains.filter(d => d !== childId);
}
// 칩 UI 업데이트
renderDomainModal();
}
// ===== 선택 요약 =====
function updateDomainSummary() {
const summaryEl = document.getElementById('domainSummaryText');
if (!summaryEl) return;
if (selectedDomains.length === 0) {
summaryEl.textContent = '선택된 도메인이 없습니다. AI가 자동으로 분야를 판단합니다.';
summaryEl.className = 'domain-summary-text empty';
return;
}
// 선택된 항목 이름 수집
const names = [];
domainConfig.categories.forEach(cat => {
if (selectedDomains.includes(cat.id)) {
names.push(cat.label);
}
if (cat.children) {
cat.children.forEach(child => {
if (selectedDomains.includes(child.id)) {
names.push(child.label);
}
});
}
});
summaryEl.textContent = names.join(', ');
summaryEl.className = 'domain-summary-text';
}
// ===== 확인 (서버에 전달) =====
async function submitDomainSelection() {
if (selectedDomains.length === 0) {
// 선택 없으면 step3 자동 분석 모드
closeDomainModal();
updateDomainDisplay('자동 분석 (AI 판단)');
return;
}
try {
const resp = await fetch('/api/domain-combine', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ selected: selectedDomains })
});
const data = await resp.json();
if (data.success) {
closeDomainModal();
// 사이드바에 선택 결과 표시
const names = data.selected_names || selectedDomains;
updateDomainDisplay(names.join(', '));
console.log('[Domain] 도메인 지식 결합 완료:', data.combined_length, '자');
} else {
alert('도메인 지식 결합 실패: ' + (data.error || '알 수 없는 오류'));
}
} catch (e) {
console.error('[Domain] 서버 전달 실패:', e);
alert('서버 통신 오류가 발생했습니다.');
}
}
// ===== 사이드바 표시 업데이트 =====
function updateDomainDisplay(text) {
const el = document.getElementById('domainDisplayText');
if (el) {
el.textContent = text;
el.className = 'domain-display-text' + (text.includes('자동') ? ' auto' : ' selected');
}
}
// ===== 전체 선택/해제 =====
function selectAllDomains() {
selectedDomains = [];
domainConfig.categories.forEach(cat => {
selectedDomains.push(cat.id);
if (cat.children) {
cat.children.forEach(child => selectedDomains.push(child.id));
}
});
renderDomainModal();
}
function clearAllDomains() {
selectedDomains = [];
renderDomainModal();
}
// ===== 폴더 설정 후 자동 호출 =====
// 기존 submitFolder() 함수에서 성공 후 이 함수 호출
function onFolderSetComplete() {
// 약간의 딜레이 후 도메인 선택 모달 표시
setTimeout(() => {
openDomainModal();
}, 500);
}