v7:UI 보완_20260130
This commit is contained in:
@@ -303,6 +303,103 @@
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
/* 템플릿 리스트 */
|
||||
.template-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.template-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
background: var(--ui-panel);
|
||||
border: 1px solid var(--ui-border);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.template-item:hover {
|
||||
background: var(--ui-hover);
|
||||
border-color: var(--ui-dim);
|
||||
}
|
||||
|
||||
.template-item.selected {
|
||||
border-color: var(--ui-accent);
|
||||
background: rgba(0, 200, 83, 0.1);
|
||||
}
|
||||
|
||||
.template-item input[type="radio"] {
|
||||
accent-color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.template-item .label {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.template-item .delete-btn {
|
||||
opacity: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--ui-dim);
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.template-item:hover .delete-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.template-item .delete-btn:hover {
|
||||
color: var(--ui-error);
|
||||
}
|
||||
|
||||
/* 템플릿 요소 체크박스 */
|
||||
.template-elements {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
background: var(--ui-bg);
|
||||
border: 1px solid var(--ui-border);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.elements-title {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: var(--ui-dim);
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.elements-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.element-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--ui-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.element-checkbox input[type="checkbox"] {
|
||||
accent-color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.element-checkbox .element-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 사용자 템플릿 프리뷰 */
|
||||
.user-template-preview {
|
||||
display: none;
|
||||
@@ -494,7 +591,7 @@
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
|
||||
.section-title {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
@@ -503,7 +600,7 @@
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
|
||||
/* 참고 파일 확인 */
|
||||
.file-check-box {
|
||||
background: var(--ui-panel);
|
||||
@@ -572,7 +669,72 @@
|
||||
border-color: var(--ui-accent);
|
||||
color: var(--ui-accent);
|
||||
}
|
||||
|
||||
|
||||
/* 작성 방식 선택 (가로 탭) */
|
||||
.write-mode-box {
|
||||
background: var(--ui-panel);
|
||||
border: 1px solid var(--ui-border);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.write-mode-tabs {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.write-mode-tab {
|
||||
flex: 1;
|
||||
padding: 10px 8px;
|
||||
border: 1px solid var(--ui-border);
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.write-mode-tab:hover {
|
||||
background: var(--ui-hover);
|
||||
border-color: var(--ui-dim);
|
||||
}
|
||||
|
||||
.write-mode-tab.selected {
|
||||
background: rgba(0, 200, 83, 0.15);
|
||||
border-color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.write-mode-tab input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.write-mode-icon {
|
||||
font-size: 16px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.write-mode-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--ui-text);
|
||||
}
|
||||
|
||||
.write-mode-tab.selected .write-mode-label {
|
||||
color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.write-mode-notice {
|
||||
margin-top: 8px;
|
||||
padding: 6px 8px;
|
||||
background: rgba(255, 152, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
color: var(--ui-warning);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
/* 진행 상태 */
|
||||
.step-list {
|
||||
display: flex;
|
||||
@@ -756,6 +918,45 @@
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 목차 확인 액션바 */
|
||||
.toc-action-bar {
|
||||
background: var(--ui-panel);
|
||||
border-top: 1px solid var(--ui-border);
|
||||
padding: 12px 20px;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
.toc-action-bar.show { display: flex; }
|
||||
|
||||
.toc-action-btn {
|
||||
padding: 10px 24px;
|
||||
border-radius: 6px;
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.toc-action-btn.primary {
|
||||
background: var(--ui-accent);
|
||||
color: #003300;
|
||||
}
|
||||
.toc-action-btn.primary:hover {
|
||||
background: #00e676;
|
||||
}
|
||||
.toc-action-btn.secondary {
|
||||
background: var(--ui-hover);
|
||||
color: var(--ui-text);
|
||||
border: 1px solid var(--ui-border);
|
||||
}
|
||||
.toc-action-btn.secondary:hover {
|
||||
border-color: var(--ui-accent);
|
||||
color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.feedback-bar.show { display: flex; }
|
||||
|
||||
.feedback-input {
|
||||
@@ -1437,14 +1638,14 @@
|
||||
<!-- 좌측 사이드바: 입력 -->
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<div class="sidebar-title">입력</div>
|
||||
<div class="sidebar-title">문서 업로드</div>
|
||||
<button class="sidebar-btn" onclick="openFolderModal()">
|
||||
<span class="icon">📁</span>
|
||||
<span>폴더 위치</span>
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="openLinkModal()">
|
||||
<span class="icon">🔗</span>
|
||||
<span>참고 링크</span>
|
||||
<span>외부 링크</span>
|
||||
</button>
|
||||
<button class="sidebar-btn" onclick="openHtmlModal()">
|
||||
<span class="icon">📋</span>
|
||||
@@ -1456,7 +1657,7 @@
|
||||
<div class="sidebar-content">
|
||||
<!-- 참고 파일 확인 -->
|
||||
<div>
|
||||
<div class="section-title">참고 파일 확인</div>
|
||||
<div class="section-title">업로드 파일 검토</div>
|
||||
<div class="file-check-box">
|
||||
<div class="file-path empty" id="folderPathDisplay">폴더 경로가 설정되지 않음</div>
|
||||
<div class="file-check-row">
|
||||
@@ -1488,12 +1689,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 초안 생성 버튼 -->
|
||||
<button class="sidebar-generate-btn" id="generateBtnSide" onclick="generate()" disabled>
|
||||
🚀 초안 생성하기
|
||||
</button>
|
||||
|
||||
|
||||
<!-- 작성 방식 -->
|
||||
<div>
|
||||
<div class="section-title">업로드 자료 활용 범위</div>
|
||||
<div class="write-mode-box">
|
||||
<div class="write-mode-tabs">
|
||||
<label class="write-mode-tab" onclick="selectWriteMode('format')">
|
||||
<input type="radio" name="writeMode" value="format">
|
||||
<div class="write-mode-icon">📄</div>
|
||||
<div class="write-mode-label">형식만 <br>변경</div>
|
||||
</label>
|
||||
<label class="write-mode-tab selected" onclick="selectWriteMode('restructure')">
|
||||
<input type="radio" name="writeMode" value="restructure" checked>
|
||||
<div class="write-mode-icon">🔄</div>
|
||||
<div class="write-mode-label">내용의<br>재구성</div>
|
||||
</label>
|
||||
<label class="write-mode-tab" onclick="selectWriteMode('new')">
|
||||
<input type="radio" name="writeMode" value="new">
|
||||
<div class="write-mode-icon">✨</div>
|
||||
<div class="write-mode-label">문서 참고 <br> 신규 작성</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="write-mode-notice">
|
||||
<span>⚠️</span>
|
||||
<span>문서 유형에 적합하지 않은 콘텐츠 업로드시,<br> 자동 재구성 및 신규 콘텐츠 작성 </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 진행 상태 -->
|
||||
<div>
|
||||
<div class="section-title">진행 상태</div>
|
||||
@@ -1560,7 +1784,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 목차 확인 액션바 -->
|
||||
<div class="toc-action-bar" id="tocActionBar">
|
||||
<button class="toc-action-btn secondary" onclick="editToc()">✏️ 편집</button>
|
||||
<button class="toc-action-btn primary" id="approveBtn" onclick="approveToc()">✅ 승인 & 생성하기</button>
|
||||
</div>
|
||||
|
||||
<!-- 하단 피드백 바 -->
|
||||
<div class="feedback-bar" id="feedbackBar">
|
||||
<input type="text" class="feedback-input" id="feedbackInput" placeholder="수정 요청사항을 입력하세요... (예: 5 Step을 첨부로 이동해줘)">
|
||||
@@ -1577,9 +1807,8 @@
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">문서 설정</span>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<!-- 문서 유형 선택 -->
|
||||
<!-- ===== 문서 유형 ===== -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">문서 유형</div>
|
||||
<div class="doc-type-list">
|
||||
@@ -1587,65 +1816,13 @@
|
||||
<div class="doc-type-item selected" data-type="briefing" onclick="selectDocType('briefing')">
|
||||
<input type="radio" name="docType" checked>
|
||||
<span class="label">📋 기획서</span>
|
||||
|
||||
<!-- 플로팅 프리뷰 -->
|
||||
<div class="doc-type-preview">
|
||||
<div class="preview-thumbnail briefing">
|
||||
<div class="page">
|
||||
<div class="page-header"></div>
|
||||
<div class="page-title"></div>
|
||||
<div class="page-divider"></div>
|
||||
<div class="page-lead"></div>
|
||||
<div class="page-body"></div>
|
||||
<div class="page-body" style="width:80%"></div>
|
||||
<div class="page-body" style="width:90%"></div>
|
||||
<div class="page-bottom"></div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<div class="page-header"></div>
|
||||
<div class="page-attach">[첨부]</div>
|
||||
<div class="page-body"></div>
|
||||
<div class="page-body" style="width:85%"></div>
|
||||
<div class="page-body"></div>
|
||||
<div class="page-body" style="width:75%"></div>
|
||||
<div class="page-bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-title">기획서 (보고자료)</div>
|
||||
<div class="preview-desc">임원보고용 정형화된 1~2페이지 문서</div>
|
||||
<div class="preview-features">
|
||||
<div class="preview-feature"><span class="icon">📄</span> 1p 본문만 / 1p+1p첨부 / 1p+np첨부</div>
|
||||
<div class="preview-feature"><span class="icon">🎨</span> Navy 양식 (A4 인쇄 최적화)</div>
|
||||
<div class="preview-feature"><span class="icon">✍️</span> 개조식 자동 변환</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 프리뷰 생략 -->
|
||||
</div>
|
||||
|
||||
<!-- 보고서 -->
|
||||
<div class="doc-type-item" data-type="report" onclick="selectDocType('report')">
|
||||
<input type="radio" name="docType">
|
||||
<span class="label">📄 보고서</span>
|
||||
|
||||
<div class="doc-type-preview">
|
||||
<div class="preview-thumbnail report">
|
||||
<div class="line h1"></div>
|
||||
<div class="line body"></div>
|
||||
<div class="line body" style="width:90%"></div>
|
||||
<div class="line body" style="width:85%"></div>
|
||||
<div class="line h2"></div>
|
||||
<div class="line body"></div>
|
||||
<div class="line body" style="width:92%"></div>
|
||||
<div class="line h2"></div>
|
||||
<div class="line body" style="width:88%"></div>
|
||||
</div>
|
||||
<div class="preview-title">보고서 (HWP)</div>
|
||||
<div class="preview-desc">RAG 기반 장문 보고서 → HWPX 출력</div>
|
||||
<div class="preview-features">
|
||||
<div class="preview-feature"><span class="icon">🏷️</span> AI 스타일 자동 태깅</div>
|
||||
<div class="preview-feature"><span class="icon">📝</span> 대제목/중제목/소제목/본문</div>
|
||||
<div class="preview-feature"><span class="icon">✨</span> 한글에서 스타일 일괄 변경</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="doc-type-item" data-type="report" onclick="selectDocType('report')">
|
||||
<input type="radio" name="docType">
|
||||
<span class="label">📄 보고서</span>
|
||||
</div>
|
||||
|
||||
<!-- 발표자료 -->
|
||||
@@ -1653,73 +1830,35 @@
|
||||
<input type="radio" name="docType" disabled>
|
||||
<span class="label">📊 발표자료</span>
|
||||
<span class="badge">준비중</span>
|
||||
|
||||
<div class="doc-type-preview">
|
||||
<div class="preview-thumbnail ppt">
|
||||
<div class="slide">
|
||||
<div class="slide-title">제목</div>
|
||||
<div class="slide-body"></div>
|
||||
<div class="slide-body"></div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<div class="slide-title">본문</div>
|
||||
<div class="slide-body"></div>
|
||||
<div class="slide-body"></div>
|
||||
<div class="slide-body"></div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<div class="slide-title">결론</div>
|
||||
<div class="slide-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-title">발표자료 (PPT)</div>
|
||||
<div class="preview-desc">프레젠테이션 형식 슬라이드</div>
|
||||
<div class="preview-features">
|
||||
<div class="preview-feature"><span class="icon">📊</span> 슬라이드 자동 구성</div>
|
||||
<div class="preview-feature"><span class="icon">🎯</span> 핵심 내용 추출</div>
|
||||
<div class="preview-feature"><span class="icon">🖼️</span> 도식화 자동 생성</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 추가 문서 유형 (동적) -->
|
||||
<div id="customDocTypesArea"></div>
|
||||
</div>
|
||||
|
||||
<div id="userTemplatesArea" style="display: none;">
|
||||
<div class="template-divider"></div>
|
||||
<div class="user-templates-section" id="userTemplatesList">
|
||||
<!-- 동적으로 추가됨 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 템플릿 추가 버튼 -->
|
||||
<button class="add-template-btn" onclick="openTemplateModal()">+ 템플릿 추가</button>
|
||||
|
||||
<!-- 문서 유형 추가 버튼 -->
|
||||
<button class="add-template-btn" onclick="openDocTypeModal()">+ 문서 유형 추가</button>
|
||||
</div>
|
||||
|
||||
<!-- 기획서 옵션 -->
|
||||
<!-- ===== 문서 유형별 옵션 (기존 유지) ===== -->
|
||||
<div id="briefingOptions">
|
||||
<!-- 페이지 구성 -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">페이지 구성</div>
|
||||
<div class="option-group">
|
||||
<div class="option-item" onclick="selectPageOption('1')">
|
||||
<input type="radio" name="pages" value="1" id="page1">
|
||||
<label for="page1"> (본문) 1p</label>
|
||||
<label for="page1">(본문) 1p</label>
|
||||
</div>
|
||||
<div class="option-item selected" onclick="selectPageOption('2')">
|
||||
<input type="radio" name="pages" value="2" id="page2" checked>
|
||||
<label for="page2"> (본문) 1p + (첨부) 1p</label>
|
||||
<label for="page2">(본문) 1p + (첨부) 1p</label>
|
||||
</div>
|
||||
<div class="option-item" onclick="selectPageOption('n')">
|
||||
<input type="radio" name="pages" value="n" id="pageN">
|
||||
<label for="pageN"> (본문) 1p + (첨부) np</label>
|
||||
<label for="pageN">(본문) 1p + (첨부) np</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 요청사항 -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">요청사항</div>
|
||||
<textarea class="request-textarea" id="instructionInput" placeholder="예: 세무 리스크 중심으로 작성해줘 예: 표를 더 상세하게 만들어줘"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 보고서 옵션 -->
|
||||
@@ -1746,33 +1885,55 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 템플릿 옵션 (요청사항만) -->
|
||||
<div id="templateOptions" style="display:none;">
|
||||
<div class="option-section">
|
||||
<div class="option-title">요청사항</div>
|
||||
<textarea class="request-textarea" id="templateInstructionInput" placeholder="예: 요약을 상세하게 작성해줘 예: 특정 섹션 강조"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 요청사항 -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">요청사항</div>
|
||||
<textarea class="request-textarea" id="reportInstructionInput" placeholder="예: 요약을 상세하게 작성해줘 예: 표지에 로고 추가"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="templateOptions" style="display:none;">
|
||||
<div class="option-section">
|
||||
<div class="option-title">요청사항</div>
|
||||
<textarea class="request-textarea" id="templateInstructionInput"
|
||||
placeholder="예: 요약을 상세하게 작성해줘 예: 특정 섹션 강조"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 생성 버튼 -->
|
||||
<!-- ===== 템플릿 선택 (새로 추가) ===== -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">템플릿</div>
|
||||
<div class="template-list">
|
||||
<!-- 기본 템플릿 -->
|
||||
<div class="template-item selected" data-template="default" onclick="selectTemplate('default')">
|
||||
<input type="radio" name="template" checked>
|
||||
<span class="label">📄 기본 템플릿</span>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 템플릿 (동적) -->
|
||||
<div id="userTemplatesListNew"></div>
|
||||
</div>
|
||||
|
||||
<!-- 템플릿 추가 버튼 -->
|
||||
<button class="add-template-btn" onclick="openTemplateModal()">+ 템플릿 추가</button>
|
||||
|
||||
<!-- 선택된 템플릿 옵션 (AI 분석 결과) -->
|
||||
<div id="templateElementOptions" class="template-elements" style="display:none;">
|
||||
<div class="elements-title">적용 요소</div>
|
||||
<div class="elements-list">
|
||||
<!-- 동적으로 채워짐 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 요청사항 ===== -->
|
||||
<div class="option-section">
|
||||
<div class="option-title">요청사항</div>
|
||||
<textarea class="request-textarea" id="globalInstructionInput"
|
||||
placeholder="예: 표를 더 상세하게 예: 전문 용어 풀어서 설명"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- ===== 생성 버튼 ===== -->
|
||||
<button class="generate-btn" id="generateBtn" onclick="generate()" disabled>
|
||||
<span id="generateBtnText">🚀 생성하기</span>
|
||||
<div class="loading-spinner" id="generateSpinner" style="display:none;"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1837,9 +1998,14 @@
|
||||
let generatedHTML = '';
|
||||
let currentDocType = 'briefing';
|
||||
let currentPageOption = '2';
|
||||
let currentWriteMode = 'restructure'; // format, restructure, new
|
||||
let currentZoom = 100;
|
||||
let folderPath = '';
|
||||
let referenceLinks = [];
|
||||
let customDocTypes = []; // [{id, name, structure, created_at}, ...]
|
||||
let currentTemplate = 'default';
|
||||
let templateElements = {}; // {templateId: {cover: true, divider: false, ...}}
|
||||
|
||||
|
||||
// ===== AI 부분 수정 관련 =====
|
||||
let selectedText = '';
|
||||
@@ -2069,6 +2235,121 @@
|
||||
document.getElementById('briefingOptions').style.display = isBriefing ? 'block' : 'none';
|
||||
document.getElementById('reportOptions').style.display = isReport ? 'block' : 'none';
|
||||
document.getElementById('templateOptions').style.display = isTemplate ? 'block' : 'none';
|
||||
const generateBtnText = document.getElementById('generateBtnText');
|
||||
|
||||
if (type === 'report' || type === 'presentation') {
|
||||
generateBtnText.textContent = '📋 목차 확인하기';
|
||||
} else {
|
||||
generateBtnText.textContent = '🚀 생성하기';
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 문서 유형 추가 모달 =====
|
||||
function openDocTypeModal() {
|
||||
document.getElementById('docTypeModal').classList.add('active');
|
||||
}
|
||||
|
||||
function closeDocTypeModal() {
|
||||
document.getElementById('docTypeModal').classList.remove('active');
|
||||
}
|
||||
|
||||
// ===== 템플릿 선택 =====
|
||||
function selectTemplate(templateId) {
|
||||
currentTemplate = templateId;
|
||||
|
||||
// 모든 템플릿 선택 해제
|
||||
document.querySelectorAll('.template-item').forEach(item => {
|
||||
item.classList.remove('selected');
|
||||
const radio = item.querySelector('input[type="radio"]');
|
||||
if (radio) radio.checked = false;
|
||||
});
|
||||
|
||||
// 선택한 템플릿 활성화
|
||||
const selectedItem = document.querySelector(`.template-item[data-template="${templateId}"]`);
|
||||
if (selectedItem) {
|
||||
selectedItem.classList.add('selected');
|
||||
const radio = selectedItem.querySelector('input[type="radio"]');
|
||||
if (radio) radio.checked = true;
|
||||
}
|
||||
|
||||
// 템플릿 요소 옵션 표시/숨김
|
||||
const elementsPanel = document.getElementById('templateElementOptions');
|
||||
if (templateId === 'default') {
|
||||
elementsPanel.style.display = 'none';
|
||||
} else {
|
||||
showTemplateElements(templateId);
|
||||
elementsPanel.style.display = 'block';
|
||||
}
|
||||
|
||||
console.log('템플릿 선택:', templateId);
|
||||
}
|
||||
|
||||
// ===== 템플릿 요소 표시 (AI 분석 결과) =====
|
||||
function showTemplateElements(templateId) {
|
||||
const template = userTemplates.find(t => t.id === templateId);
|
||||
if (!template || !template.elements) return;
|
||||
|
||||
const container = document.querySelector('#templateElementOptions .elements-list');
|
||||
container.innerHTML = template.elements.map(el => `
|
||||
<label class="element-checkbox">
|
||||
<input type="checkbox"
|
||||
data-element="${el.type}"
|
||||
${el.default ? 'checked' : ''}
|
||||
onchange="toggleTemplateElement('${templateId}', '${el.type}', this.checked)">
|
||||
<span class="element-icon">${el.icon}</span>
|
||||
<span>${el.name}</span>
|
||||
</label>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// ===== 템플릿 요소 토글 =====
|
||||
function toggleTemplateElement(templateId, elementType, checked) {
|
||||
if (!templateElements[templateId]) {
|
||||
templateElements[templateId] = {};
|
||||
}
|
||||
templateElements[templateId][elementType] = checked;
|
||||
console.log('템플릿 요소 변경:', templateId, elementType, checked);
|
||||
}
|
||||
|
||||
// ===== 사용자 템플릿 렌더링 (수정) =====
|
||||
function renderUserTemplates() {
|
||||
const container = document.getElementById('userTemplatesListNew');
|
||||
|
||||
if (userTemplates.length === 0) {
|
||||
container.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = userTemplates.map(tpl => `
|
||||
<div class="template-item" data-template="${tpl.id}" onclick="selectTemplate('${tpl.id}')">
|
||||
<input type="radio" name="template">
|
||||
<span class="label">📑 ${tpl.name}</span>
|
||||
<button class="delete-btn" onclick="event.stopPropagation(); deleteTemplate('${tpl.id}')" title="삭제">✕</button>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ===== 작성 방식 선택 =====
|
||||
function selectWriteMode(mode) {
|
||||
currentWriteMode = mode;
|
||||
|
||||
// 모든 탭 선택 해제
|
||||
document.querySelectorAll('.write-mode-tab').forEach(tab => {
|
||||
tab.classList.remove('selected');
|
||||
tab.querySelector('input[type="radio"]').checked = false;
|
||||
});
|
||||
|
||||
// 선택한 탭 활성화
|
||||
const selectedTab = document.querySelector(`.write-mode-tab input[value="${mode}"]`);
|
||||
if (selectedTab) {
|
||||
selectedTab.checked = true;
|
||||
selectedTab.closest('.write-mode-tab').classList.add('selected');
|
||||
}
|
||||
|
||||
console.log('작성 방식 선택:', mode);
|
||||
}
|
||||
|
||||
// ===== HWP 추출 =====
|
||||
@@ -2351,7 +2632,6 @@
|
||||
|
||||
// 생성 버튼 활성화 (HTML 입력이 있거나, 폴더/링크가 있으면)
|
||||
const canGenerate = hasHtml || hasFolder || hasLinks;
|
||||
document.getElementById('generateBtnSide').disabled = !canGenerate;
|
||||
document.getElementById('generateBtn').disabled = !canGenerate;
|
||||
|
||||
// Step 0 상태 업데이트
|
||||
@@ -2503,11 +2783,118 @@
|
||||
async function generate() {
|
||||
if (currentDocType === 'briefing') {
|
||||
await generateBriefing();
|
||||
} else if (currentDocType === 'report') {
|
||||
await generateReport();
|
||||
} else if (currentDocType === 'report' || currentDocType === 'presentation') {
|
||||
await generateDraft(); // ← 목차 확인 플로우
|
||||
} else if (currentDocType.startsWith('template_')) {
|
||||
// ⭐ 사용자 템플릿: 보고서와 동일하게 처리
|
||||
await generateBriefing(); // 템플릿은 바로 생성
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== 초안/목차 생성 (보고서/발표자료용) =====
|
||||
async function generateDraft() {
|
||||
if (!folderPath && !inputContent && referenceLinks.length === 0) {
|
||||
alert('먼저 폴더 위치, 참고 링크, 또는 HTML을 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = document.getElementById('generateBtn');
|
||||
const btnText = document.getElementById('generateBtnText');
|
||||
const spinner = document.getElementById('generateSpinner');
|
||||
|
||||
btn.disabled = true;
|
||||
btnText.textContent = '분석 중...';
|
||||
spinner.style.display = 'block';
|
||||
resetSteps();
|
||||
updateStep(0, 'done');
|
||||
setStatus('목차 생성 중...', true);
|
||||
|
||||
try {
|
||||
// Step 1~7 실행
|
||||
for (let i = 1; i <= 7; i++) {
|
||||
updateStep(i, 'running');
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
updateStep(i, 'done');
|
||||
}
|
||||
|
||||
// 목차 테이블 표시
|
||||
document.getElementById('placeholder').style.display = 'none';
|
||||
const frame = document.getElementById('previewFrame');
|
||||
frame.classList.remove('active');
|
||||
|
||||
let tocContainer = document.getElementById('tocContainer');
|
||||
if (!tocContainer) {
|
||||
tocContainer = document.createElement('div');
|
||||
tocContainer.id = 'tocContainer';
|
||||
document.getElementById('a4Preview').appendChild(tocContainer);
|
||||
}
|
||||
|
||||
const tableContent = document.getElementById('embedded-table-context');
|
||||
if (tableContent) {
|
||||
tocContainer.innerHTML = tableContent.innerHTML;
|
||||
tocContainer.style.display = 'block';
|
||||
}
|
||||
|
||||
// 액션바 표시
|
||||
document.getElementById('tocActionBar').classList.add('show');
|
||||
document.getElementById('feedbackBar').classList.remove('show');
|
||||
|
||||
setStatus('목차 생성 완료 - 확인 후 승인해주세요', true);
|
||||
|
||||
} catch (error) {
|
||||
alert('목차 생성 오류: ' + error.message);
|
||||
setStatus('오류 발생', false);
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btnText.textContent = '📋 목차 확인하기';
|
||||
spinner.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 목차 편집 =====
|
||||
function editToc() {
|
||||
const tocContainer = document.getElementById('tocContainer');
|
||||
if (tocContainer) {
|
||||
tocContainer.contentEditable = true;
|
||||
tocContainer.style.outline = '2px solid var(--ui-accent)';
|
||||
}
|
||||
setStatus('목차 편집 모드 - 직접 수정 가능합니다', true);
|
||||
}
|
||||
|
||||
// ===== 목차 승인 & 최종 생성 =====
|
||||
async function approveToc() {
|
||||
const btn = document.getElementById('approveBtn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⏳ 생성 중...';
|
||||
|
||||
document.getElementById('tocActionBar').classList.remove('show');
|
||||
setStatus('최종 문서 생성 중...', true);
|
||||
|
||||
// 목차 컨테이너 숨기기
|
||||
const tocContainer = document.getElementById('tocContainer');
|
||||
if (tocContainer) {
|
||||
tocContainer.style.display = 'none';
|
||||
tocContainer.contentEditable = false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Step 8~9 실행
|
||||
for (let i = 8; i <= 9; i++) {
|
||||
updateStep(i, 'running');
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
updateStep(i, 'done');
|
||||
}
|
||||
|
||||
// TODO: 실제 API 호출 (generateReport 로직 활용)
|
||||
// 지금은 generateReport() 호출
|
||||
await generateReport();
|
||||
|
||||
} catch (error) {
|
||||
alert('문서 생성 오류: ' + error.message);
|
||||
setStatus('오류 발생', false);
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '✅ 승인 & 생성하기';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2522,10 +2909,8 @@
|
||||
const btn = document.getElementById('generateBtn');
|
||||
const btnText = document.getElementById('generateBtnText');
|
||||
const spinner = document.getElementById('generateSpinner');
|
||||
const sideBtn = document.getElementById('generateBtnSide');
|
||||
|
||||
btn.disabled = true;
|
||||
sideBtn.disabled = true;
|
||||
btnText.textContent = '생성 중...';
|
||||
spinner.style.display = 'block';
|
||||
resetSteps();
|
||||
@@ -2588,7 +2973,6 @@
|
||||
}
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
sideBtn.disabled = false;
|
||||
btnText.textContent = '🚀 생성하기';
|
||||
spinner.style.display = 'none';
|
||||
}
|
||||
@@ -2971,5 +3355,47 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="embedded-table-context" style="display:none;">
|
||||
<!-- 목차 테이블 HTML (나중에 첨부파일 내용으로 대체) -->
|
||||
<div style="padding: 15mm; font-family: 'Noto Sans KR', sans-serif;">
|
||||
<div style="text-align:center; margin-bottom:20px;">
|
||||
<div style="font-size:18pt; font-weight:800; color:#006400;">목차 확인</div>
|
||||
<div style="font-size:10pt; color:#666; margin-top:5px;">체크박스로 포함/제외를 선택하세요</div>
|
||||
</div>
|
||||
<!-- 실제 목차 테이블은 API 응답으로 동적 생성 -->
|
||||
<p style="color:#888; text-align:center;">목차 데이터 로딩 중...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 문서 유형 추가 모달 -->
|
||||
<div class="template-modal" id="docTypeModal">
|
||||
<div class="template-modal-content">
|
||||
<div class="template-modal-header">
|
||||
<div class="template-modal-title">📁 문서 유형 추가</div>
|
||||
<button class="template-modal-close" onclick="closeDocTypeModal()">✕</button>
|
||||
</div>
|
||||
|
||||
<div class="template-input-group">
|
||||
<label class="template-input-label">유형 이름</label>
|
||||
<input type="text" class="template-name-input" id="docTypeNameInput"
|
||||
placeholder="예: 제안서, 기술보고서, 회의록">
|
||||
</div>
|
||||
|
||||
<div class="template-input-group">
|
||||
<label class="template-input-label">샘플 문서 (선택)</label>
|
||||
<div class="template-dropzone" id="docTypeDropzone">
|
||||
<div class="template-dropzone-icon">📄</div>
|
||||
<div class="template-dropzone-text">샘플 문서를 업로드하면 AI가 구조를 분석합니다</div>
|
||||
<div class="template-dropzone-hint">HWPX, HWP, PDF, DOCX 지원</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="template-submit-btn" id="docTypeSubmitBtn" onclick="submitDocType()">
|
||||
<span id="docTypeSpinner" class="spinner"></span>
|
||||
<span id="docTypeSubmitText">✨ 분석 및 추가</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user