255 lines
13 KiB
Plaintext
255 lines
13 KiB
Plaintext
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>DB Console - eLink Admin</title>
|
|
|
|
<!-- Bootstrap 5 -->
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/addon/bootstrap-5.3.2/css/bootstrap.min.css">
|
|
<!-- Bootstrap Icons -->
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/addon/bootstrap-icons-1.11.3/bootstrap-icons.min.css">
|
|
<!-- Monaco Editor CSS -->
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/addon/monaco/editor/editor.main.css">
|
|
<!-- AG Grid CSS -->
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/addon/ag-grid/ag-grid.min.css">
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/addon/ag-grid/ag-theme-alpine.min.css">
|
|
<!-- DB Console CSS -->
|
|
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/dbconsole/dbconsole.css">
|
|
</head>
|
|
<body>
|
|
<div class="dbconsole-container">
|
|
<!-- 헤더 -->
|
|
<div class="dbconsole-header">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="d-flex align-items-center gap-3">
|
|
<h5 class="mb-0"><i class="bi bi-terminal"></i> DB Console</h5>
|
|
<div id="connection-status" class="connection-status">
|
|
<span class="status-dot disconnected"></span>
|
|
<span class="status-text">연결 안됨</span>
|
|
</div>
|
|
<span id="transaction-indicator" class="transaction-indicator"></span>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="small text-muted">Admin 전용</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 본문 -->
|
|
<div class="dbconsole-body">
|
|
<!-- 사이드바: 스키마 탐색기 -->
|
|
<div class="dbconsole-sidebar">
|
|
<div class="dbconsole-sidebar-header">
|
|
<h6><i class="bi bi-folder-tree"></i> 스키마 탐색기</h6>
|
|
<small class="text-muted">테이블 더블클릭: SELECT 생성 / 우클릭: DDL</small>
|
|
</div>
|
|
<div class="dbconsole-sidebar-body">
|
|
<div id="schema-tree" class="schema-tree">
|
|
<div class="text-muted small">데이터소스에 연결하세요</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 리사이저 -->
|
|
<div class="dbconsole-resizer"></div>
|
|
|
|
<!-- 메인 영역 -->
|
|
<div class="dbconsole-main">
|
|
<!-- 에디터 영역 -->
|
|
<div class="dbconsole-editor-area">
|
|
<!-- 툴바 -->
|
|
<div class="dbconsole-editor-toolbar">
|
|
<!-- 데이터소스 선택 -->
|
|
<div class="toolbar-group">
|
|
<label class="toolbar-label">데이터소스:</label>
|
|
<select id="datasource-select" class="dbconsole-select">
|
|
<option value="">-- 선택 --</option>
|
|
</select>
|
|
<button id="btn-connect" class="btn btn-sm btn-outline-primary btn-toolbar">
|
|
<i class="bi bi-plug"></i> 연결
|
|
</button>
|
|
<button id="btn-disconnect" class="btn btn-sm btn-outline-secondary btn-toolbar" style="display:none;">
|
|
<i class="bi bi-plug"></i> 연결해제
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 직접 입력 영역 (숨김) -->
|
|
<div id="direct-input-area" class="toolbar-group" style="display:none;">
|
|
<input type="text" id="direct-jdbc-url" class="form-control form-control-sm" placeholder="JDBC URL" style="width:250px;">
|
|
<input type="text" id="direct-username" class="form-control form-control-sm" placeholder="Username" style="width:100px;">
|
|
<input type="password" id="direct-password" class="form-control form-control-sm" placeholder="Password" autocomplete="off" style="width:100px;">
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- 실행 버튼 -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-execute" class="btn btn-sm btn-execute btn-toolbar" disabled title="커서 위치 구문 실행 (Ctrl+Enter)">
|
|
<i class="bi bi-play-fill"></i> 실행
|
|
</button>
|
|
<button id="btn-execute-all" class="btn btn-sm btn-outline-success btn-toolbar" disabled title="전체 SQL 순차 실행 (Ctrl+Shift+Enter)">
|
|
<i class="bi bi-skip-end-fill"></i> Run All
|
|
</button>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- 트랜잭션 -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-commit" class="btn btn-sm btn-commit btn-toolbar" disabled>
|
|
<i class="bi bi-check-lg"></i> COMMIT
|
|
</button>
|
|
<button id="btn-rollback" class="btn btn-sm btn-rollback btn-toolbar" disabled>
|
|
<i class="bi bi-x-lg"></i> ROLLBACK
|
|
</button>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- Fetch Count -->
|
|
<div class="toolbar-group">
|
|
<label class="toolbar-label">Fetch:</label>
|
|
<select id="fetch-count" class="dbconsole-select" style="min-width:80px;">
|
|
<option value="100">100</option>
|
|
<option value="500">500</option>
|
|
<option value="1000" selected>1000</option>
|
|
<option value="5000">5000</option>
|
|
<option value="10000">10000</option>
|
|
<option value="all">All</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- 에디터 테마 -->
|
|
<div class="toolbar-group">
|
|
<label class="toolbar-label">테마:</label>
|
|
<select id="editor-theme" class="dbconsole-select" style="min-width:80px;">
|
|
<option value="vs-dark" selected>Dark</option>
|
|
<option value="vs">Light</option>
|
|
<option value="hc-black">High Contrast</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- 복호화 모드 -->
|
|
<div class="toolbar-group">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" id="chk-decrypt-mode">
|
|
<label class="form-check-label toolbar-label" for="chk-decrypt-mode" title="활성화시 암호화 데이터에 복호화 버튼 표시. 셀 우클릭으로도 복호화 가능.">복호화</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Monaco 에디터 -->
|
|
<div class="dbconsole-editor-container">
|
|
<div id="sql-editor"></div>
|
|
<div class="dbconsole-loading">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 결과 영역 -->
|
|
<div class="dbconsole-result-area">
|
|
<div class="dbconsole-result-header">
|
|
<div class="dbconsole-result-tabs">
|
|
<button class="dbconsole-result-tab active" data-target="result-grid-container">
|
|
<i class="bi bi-table"></i> 결과
|
|
</button>
|
|
<button class="dbconsole-result-tab" data-target="sql-log">
|
|
<i class="bi bi-journal-text"></i> SQL Log
|
|
</button>
|
|
</div>
|
|
<div class="dbconsole-result-actions">
|
|
<span id="result-message" class="small text-muted me-2"></span>
|
|
<button id="btn-export-csv" class="btn btn-sm btn-outline-secondary" title="CSV 내보내기">CSV</button>
|
|
<button id="btn-export-md" class="btn btn-sm btn-outline-secondary" title="Markdown 내보내기">MD</button>
|
|
<button id="btn-export-sql" class="btn btn-sm btn-outline-secondary" title="INSERT SQL 내보내기">SQL</button>
|
|
<button id="btn-export-json" class="btn btn-sm btn-outline-secondary" title="JSON 내보내기">JSON</button>
|
|
</div>
|
|
</div>
|
|
<div class="dbconsole-result-body">
|
|
<!-- AG Grid -->
|
|
<div id="result-grid-container" class="dbconsole-result-content active">
|
|
<div id="result-grid" class="ag-theme-alpine"></div>
|
|
</div>
|
|
<!-- SQL Log -->
|
|
<div id="sql-log" class="dbconsole-result-content"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- COMMIT 확인 모달 -->
|
|
<div class="modal fade dbconsole-modal" id="commit-modal" tabindex="-1">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><i class="bi bi-shield-lock"></i> COMMIT 확인</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p class="small text-muted">변경사항을 커밋하려면 비밀번호를 입력하세요.</p>
|
|
<input type="password" id="commit-password" class="form-control" placeholder="비밀번호" autocomplete="off">
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">취소</button>
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="DbConsole.commit()">COMMIT</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DDL 모달 -->
|
|
<div class="modal fade dbconsole-modal" id="ddl-modal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><i class="bi bi-code-square"></i> DDL</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<pre id="ddl-content" class="ddl-content"></pre>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">닫기</button>
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="navigator.clipboard.writeText($('#ddl-content').text()); alert('클립보드에 복사되었습니다.');">
|
|
<i class="bi bi-clipboard"></i> 복사
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- jQuery -->
|
|
<script src="${pageContext.request.contextPath}/js/jquery-1.12.1.min.js"></script>
|
|
<!-- Bootstrap 5 JS -->
|
|
<script src="${pageContext.request.contextPath}/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js"></script>
|
|
<!-- AG Grid (Monaco loader 전에 로드해야 AMD 충돌 방지) -->
|
|
<script src="${pageContext.request.contextPath}/addon/ag-grid/ag-grid-community.min.js"></script>
|
|
<!-- Monaco Editor Loader -->
|
|
<script src="${pageContext.request.contextPath}/addon/monaco/loader.js"></script>
|
|
<!-- DB Console JS -->
|
|
<script src="${pageContext.request.contextPath}/js/dbconsole/dbconsole.js"></script>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
// DB Console 초기화
|
|
DbConsole.init({
|
|
contextPath: '${pageContext.request.contextPath}',
|
|
sessionId: '${sessionId}',
|
|
datasources: ${datasourcesJson}
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|