/** * GUARDiA ITSM 화면별 도움말 시스템 (GS인증 사용성 요구사항) * - 각 화면/기능의 ? 버튼 → 팝업 도움말 * - F1 키 → 현재 화면 도움말 * - 검색 가능한 도움말 DB */ (function GUARDiAHelp() { 'use strict'; // ── 도움말 데이터베이스 ──────────────────────────────────── const HELP_DB = { 'dashboard': { title: '대시보드', icon: '📊', content: `

통합 대시보드

GUARDiA ITSM의 모든 운영 현황을 한눈에 확인할 수 있는 화면입니다.

탭 구성

KPI 카드

상단 숫자 카드를 클릭하면 해당 상세 목록으로 이동합니다.

단축키

`, }, 'tasks': { title: 'SR 서비스 요청', icon: '📋', content: `

SR 서비스 요청 관리

IT 서비스 요청(SR)을 접수·처리·추적하는 화면입니다.

SR 상태 흐름

접수 → 파싱 → 승인대기 → 승인 → 진행중 → PM검증 → 완료

주요 기능

봇 명령어

/sr <제목> - 메신저에서 즉시 접수
/sla - SLA 위반 목록 조회 `, }, 'cmdb': { title: 'CMDB 형상관리', icon: '🖥️', content: `

CMDB (Configuration Management Database)

관리하는 모든 IT 자산(서버·소프트웨어·네트워크)을 등록·관리합니다.

서버 등록 방법

  1. 서버 관리 → 서버 등록 버튼 클릭
  2. 서버명, IP, OS, SSH 계정 입력
  3. SSH 비밀번호는 AES-256 암호화 저장

CI 의존관계

서버 간 의존관계를 등록하면 배포 영향도 자동 분석에 활용됩니다.

보안 주의사항

⚠️ root 계정 SSH 직접 접속 금지 — opsagent 계정 사용

`, }, 'incidents': { title: '인시던트 관리', icon: '🚨', content: `

인시던트(장애) 관리

IT 서비스 장애를 신속하게 탐지·대응·복구하는 프로세스입니다.

장애 등급

AI 자동 RCA

인시던트 종료 시 Ollama AI가 근본원인 초안을 자동 생성합니다.

봇 명령어

/incident <제목> P1 - 즉시 P1 인시던트 등록
/rca INC-XXXX - AI RCA 분석 요청 `, }, 'si': { title: 'PMS 프로젝트 관리', icon: '🏗️', content: `

PMS (Project Management System)

SI 프로젝트의 전체 생명주기를 관리합니다.

관리 항목

자동 보고서

매일 18:00 일일 보고서, 매주 금요일 주간 보고서가 운영팀에 자동 발송됩니다.

`, }, 'license': { title: '라이선스 관리', icon: '🔏', content: `

라이선스 관리

에디션 비교

에디션기관사용자기능
COMMUNITY110기본
STANDARD50200전체
ENTERPRISE무제한무제한전체+APM

체험판

무료 체험 시작 버튼으로 30일 체험판을 즉시 활성화할 수 있습니다.

라이선스 갱신

만료 30일 전부터 알림이 발송됩니다. 갱신 키를 입력하여 연장하세요.

`, }, 'agents': { title: 'AI 에이전트', icon: '🤖', content: `

AI 에이전트 시스템

GUARDiA의 AI 에이전트는 온프레미스 Ollama LLM을 사용합니다. 외부 API 호출 없음.

에이전트 역할

Ollama 상태 확인

상단 Ollama 상태 표시가 🟢이면 AI 기능 사용 가능합니다.

`, }, 'default': { title: 'GUARDiA ITSM 도움말', icon: '❓', content: `

GUARDiA ITSM v2.0

AI 기반 레거시 인프라 자율 운영 플랫폼

빠른 시작

메신저 봇 명령어

기술 지원

📧 support@zioinfo.co.kr | 📞 02-000-0000

`, }, }; // ── 현재 뷰 감지 ─────────────────────────────────────────── function getCurrentView() { const path = location.pathname; const viewEl = document.querySelector('[data-view].active'); const viewId = viewEl?.dataset?.view; if (viewId) return viewId; if (path.includes('/si')) return 'si'; if (path.includes('/incidents')) return 'incidents'; if (path.includes('/license')) return 'license'; if (path.includes('/agents')) return 'agents'; return 'default'; } // ── 팝업 HTML 빌드 ───────────────────────────────────────── function buildPopup() { if (document.getElementById('grd-help-popup')) return; const overlay = document.createElement('div'); overlay.id = 'grd-help-overlay'; overlay.innerHTML = ` `; const style = document.createElement('style'); style.id = 'grd-help-style'; style.textContent = ` #grd-help-overlay { position: fixed; inset: 0; z-index: 10000; background: rgba(0,0,0,.6); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; animation: fadeIn .15s ease; } @keyframes fadeIn { from{opacity:0} to{opacity:1} } #grd-help-popup { background: var(--surface, #1e2333); border: 1px solid var(--border, rgba(255,255,255,.1)); border-radius: 16px; width: min(680px, 95vw); max-height: 80vh; display: flex; flex-direction: column; box-shadow: 0 24px 80px rgba(0,0,0,.5); animation: slideUp .2s ease; } @keyframes slideUp { from{transform:translateY(20px);opacity:0} to{transform:translateY(0);opacity:1} } #grd-help-header { display: flex; align-items: center; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--border, rgba(255,255,255,.08)); flex-shrink: 0; } #grd-help-icon { font-size: 24px; } #grd-help-title { flex: 1; font-size: 18px; font-weight: 700; color: var(--text-bright, #f1f5f9); margin: 0; } #grd-help-close { width: 32px; height: 32px; border-radius: 8px; background: rgba(255,255,255,.08); border: none; color: var(--text-muted, #64748b); cursor: pointer; font-size: 16px; display: flex; align-items: center; justify-content: center; transition: all .15s; } #grd-help-close:hover { background: rgba(255,255,255,.15); color: #fff; } #grd-help-search-area { padding: 12px 20px; border-bottom: 1px solid var(--border, rgba(255,255,255,.08)); flex-shrink: 0; } #grd-help-search { width: 100%; padding: 8px 14px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1); border-radius: 8px; color: var(--text-bright, #f1f5f9); font-size: 14px; outline: none; box-sizing: border-box; } #grd-help-search:focus { border-color: #818cf8; } #grd-help-body { flex: 1; overflow-y: auto; padding: 20px; color: var(--text-bright, #e2e8f0); line-height: 1.7; font-size: 14px; scrollbar-width: thin; } #grd-help-body h3 { font-size: 18px; color: #818cf8; margin: 0 0 12px; } #grd-help-body h4 { font-size: 14px; font-weight: 700; color: #a5b4fc; margin: 16px 0 6px; } #grd-help-body ul,ol { padding-left: 20px; margin: 6px 0; } #grd-help-body li { margin: 4px 0; } #grd-help-body code { background: rgba(255,255,255,.1); padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 13px; } #grd-help-body kbd { background: rgba(255,255,255,.15); padding: 1px 6px; border-radius: 4px; font-size: 12px; border: 1px solid rgba(255,255,255,.2); } .help-flow { background: rgba(129,140,248,.1); border-left: 3px solid #818cf8; padding: 10px 14px; border-radius: 0 8px 8px 0; margin: 8px 0; font-family: monospace; font-size: 13px; } .help-table { border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 13px; } .help-table th { background: rgba(255,255,255,.08); padding: 6px 10px; text-align: left; } .help-table td { padding: 5px 10px; border-bottom: 1px solid rgba(255,255,255,.05); } #grd-help-nav { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 20px; border-top: 1px solid rgba(255,255,255,.08); flex-shrink: 0; } .grd-help-topic { padding: 5px 12px; border-radius: 20px; font-size: 12px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1); color: var(--text-muted, #64748b); cursor: pointer; transition: all .15s; } .grd-help-topic:hover, .grd-help-topic.active { background: rgba(129,140,248,.2); border-color: #818cf8; color: #818cf8; } #grd-help-footer { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; border-top: 1px solid rgba(255,255,255,.05); font-size: 11px; color: var(--text-muted, #64748b); flex-shrink: 0; } #grd-help-footer a { color: #818cf8; } /* 화면별 ? 버튼 */ .grd-help-btn { width: 28px; height: 28px; border-radius: 50%; background: rgba(129,140,248,.15); border: 1px solid rgba(129,140,248,.3); color: #818cf8; cursor: pointer; font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; transition: all .15s; line-height: 1; } .grd-help-btn:hover { background: rgba(129,140,248,.3); transform: scale(1.1); } `; document.head.appendChild(style); document.body.appendChild(overlay); // 이벤트 overlay.addEventListener('click', e => { if (e.target === overlay) closeHelp(); }); document.getElementById('grd-help-close').onclick = closeHelp; document.getElementById('grd-help-search').oninput = searchHelp; document.querySelectorAll('.grd-help-topic').forEach(btn => { btn.onclick = () => showTopic(btn.dataset.topic); }); } // ── 도움말 표시 ──────────────────────────────────────────── function showHelp(topicId) { buildPopup(); const topic = topicId || getCurrentView(); showTopic(topic); document.getElementById('grd-help-overlay').style.display = 'flex'; document.getElementById('grd-help-search').focus(); } function showTopic(topicId) { const data = HELP_DB[topicId] || HELP_DB['default']; document.getElementById('grd-help-icon').textContent = data.icon; document.getElementById('grd-help-title').textContent = data.title; document.getElementById('grd-help-body').innerHTML = data.content; document.querySelectorAll('.grd-help-topic').forEach(b => b.classList.toggle('active', b.dataset.topic === topicId)); } function closeHelp() { const ol = document.getElementById('grd-help-overlay'); if (ol) { ol.style.display = 'none'; } document.getElementById('grd-help-search').value = ''; } function searchHelp() { const q = this.value.toLowerCase(); if (!q) { showTopic(getCurrentView()); return; } let results = ''; for (const [id, data] of Object.entries(HELP_DB)) { if (id === 'default') continue; const text = data.content.replace(/<[^>]+>/g, '').toLowerCase(); if (text.includes(q) || data.title.toLowerCase().includes(q)) { results += `

${data.icon} ${data.title}

${data.content.replace(/<[^>]+>/g,'').substring(0,150)}...

`; } } document.getElementById('grd-help-body').innerHTML = results || `

"${q}"에 대한 결과가 없습니다.

`; } // ── ? 버튼 자동 삽입 ─────────────────────────────────────── function injectHelpButtons() { const targets = [ { selector: '.card-header', topic: null }, { selector: '.section-header', topic: null }, { selector: '.page-hero-title', topic: null }, { selector: '#grd-ob-header', topic: 'default', skip: true }, ]; targets.forEach(({ selector, topic, skip }) => { if (skip) return; document.querySelectorAll(selector).forEach(el => { if (el.querySelector('.grd-help-btn')) return; const btn = document.createElement('button'); btn.className = 'grd-help-btn'; btn.textContent = '?'; btn.title = '도움말 (F1)'; btn.setAttribute('aria-label', '도움말'); btn.onclick = e => { e.stopPropagation(); showHelp(topic); }; el.style.position = 'relative'; el.appendChild(btn); }); }); } // ── 전역 ? 도움말 버튼 ───────────────────────────────────── function buildGlobalHelpBtn() { if (document.getElementById('grd-global-help')) return; const btn = document.createElement('button'); btn.id = 'grd-global-help'; btn.textContent = '?'; btn.title = 'GUARDiA 도움말 (F1)'; btn.setAttribute('aria-label', '도움말'); btn.style.cssText = ` position:fixed; right:70px; bottom:20px; z-index:8999; width:44px; height:44px; border-radius:50%; background:#4f46e5; color:#fff; border:none; font-size:18px; font-weight:700; cursor:pointer; box-shadow:0 4px 16px rgba(79,70,229,.4); display:flex; align-items:center; justify-content:center; transition:transform .2s; `; btn.onmouseover = () => btn.style.transform = 'scale(1.1)'; btn.onmouseout = () => btn.style.transform = ''; btn.onclick = () => showHelp(); document.body.appendChild(btn); } // ── 키보드 단축키 ────────────────────────────────────────── document.addEventListener('keydown', e => { if (e.key === 'F1') { e.preventDefault(); showHelp(); } if (e.key === 'Escape') { const ol = document.getElementById('grd-help-overlay'); if (ol && ol.style.display !== 'none') closeHelp(); } }); // ── 초기화 ───────────────────────────────────────────────── function init() { buildGlobalHelpBtn(); injectHelpButtons(); // SPA 뷰 변화 시 버튼 재삽입 new MutationObserver(() => injectHelpButtons()) .observe(document.body, { childList: true, subtree: true }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { setTimeout(init, 300); } // 전역 노출 window.GUARDiAHelp = { show: showHelp, close: closeHelp }; })();