415 lines
13 KiB
Plaintext
415 lines
13 KiB
Plaintext
<%@ page language="java" contentType="text/html; charset=utf-8"%>
|
|
<%@ page import="java.util.*" %>
|
|
<%@ page import="com.eactive.eai.rms.common.datasource.*" %>
|
|
|
|
<div class="dashboard-adapter-summary">
|
|
<div class="dashboard-header">
|
|
<div class="header-title-container">
|
|
<h2 class="section-title">회선 상태</h2>
|
|
<%--<div class="adapter-actions">
|
|
<button class="filter-btn view-socket-detail active">상세보기</button>
|
|
</div>--%>
|
|
</div>
|
|
</div>
|
|
<div class="card adapter-summary-card">
|
|
<div class="adapter-summary-container">
|
|
<div class="adapter-summary-header">
|
|
<div class="adapter-type-column">어댑터 유형</div>
|
|
<div class="adapter-status-column">
|
|
<div class="status-label error-label">에러</div>
|
|
<div class="status-label warning-label">경고</div>
|
|
<div class="status-label normal-label">정상</div>
|
|
<div class="status-label inactive-label">정지</div>
|
|
<div class="status-label total-label">합계</div>
|
|
</div>
|
|
</div>
|
|
<div class="adapter-summary-body">
|
|
<!-- 어댑터 요약 데이터가 동적으로 추가됩니다 -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 어댑터 요약 행 템플릿 -->
|
|
<template id="adapter-summary-row-template">
|
|
<div class="adapter-summary-row">
|
|
<div class="adapter-type-column">
|
|
<div class="adapter-type-info">
|
|
<span class="adapter-type-name">Socket</span>
|
|
<span class="status-badge adapter-status-normal">정상</span>
|
|
</div>
|
|
</div>
|
|
<div class="adapter-status-column">
|
|
<div class="status-count error-count">0</div>
|
|
<div class="status-count warning-count">0</div>
|
|
<div class="status-count normal-count">0</div>
|
|
<div class="status-count inactive-count">0</div>
|
|
<div class="status-count total-count">0</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- 소켓 상세 정보 모달 포함 -->
|
|
<jsp:include page="dashboard-socket-detail.jsp" />
|
|
|
|
<style>
|
|
/* 어댑터 섹션 */
|
|
.adapter-card {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.adapter-table-container {
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* 어댑터 탭 스타일 개선 */
|
|
.dashboard-adapters .card-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--color-gray-200);
|
|
background-color: var(--color-gray-50);
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.dashboard-adapters .tab-btn {
|
|
padding: 0.75rem 1.25rem;
|
|
font-size: 0.875rem;
|
|
font-weight: 500;
|
|
color: var(--color-gray-600);
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
border-bottom: 2px solid transparent;
|
|
}
|
|
|
|
.dashboard-adapters .tab-btn:hover {
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
.dashboard-adapters .tab-btn.active {
|
|
color: var(--color-primary);
|
|
border-bottom-color: var(--color-primary);
|
|
background-color: white;
|
|
}
|
|
|
|
.dashboard-adapters .tab-content {
|
|
display: none;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.dashboard-adapters .tab-content.active {
|
|
display: block;
|
|
}
|
|
|
|
/* 어댑터 섹션 스타일 조정 */
|
|
.adapters-container .card {
|
|
height: 100%;
|
|
min-height: 293px;
|
|
}
|
|
|
|
.dashboard-adapter-summary {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.adapter-summary-card {
|
|
padding: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.adapter-summary-container {
|
|
padding: 0.5rem 1rem;
|
|
}
|
|
|
|
.adapter-summary-header {
|
|
display: flex;
|
|
font-weight: bold;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
padding-bottom: 0.25rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.adapter-summary-body {
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.adapter-summary-row {
|
|
display: flex;
|
|
padding: 0.25rem 0;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.adapter-summary-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.adapter-type-column {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.adapter-type-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.adapter-type-name {
|
|
font-weight: bold;
|
|
margin-right: 0.5rem;
|
|
}
|
|
|
|
.adapter-status-column {
|
|
flex: 3;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.status-label, .status-count {
|
|
flex: 1;
|
|
text-align: center;
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.status-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0.15rem 0.4rem;
|
|
border-radius: 3px;
|
|
font-size: 0.7rem;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.adapter-status-normal {
|
|
background-color: rgba(76, 175, 80, 0.15);
|
|
color: #4caf50;
|
|
}
|
|
|
|
.adapter-status-warning {
|
|
background-color: rgba(255, 152, 0, 0.15);
|
|
color: #ff9800;
|
|
}
|
|
|
|
.adapter-status-error {
|
|
background-color: rgba(229, 57, 53, 0.15);
|
|
color: #e53935;
|
|
}
|
|
|
|
.adapter-status-inactive {
|
|
background-color: rgba(158, 158, 158, 0.15);
|
|
color: #9e9e9e;
|
|
}
|
|
|
|
.error-label, .error-count {
|
|
color: #e53935;
|
|
}
|
|
|
|
.warning-label, .warning-count {
|
|
color: #ff9800;
|
|
}
|
|
|
|
.normal-label, .normal-count {
|
|
color: #4caf50;
|
|
}
|
|
|
|
.inactive-label, .inactive-count {
|
|
color: #9e9e9e;
|
|
}
|
|
|
|
.total-label, .total-count {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.empty-data-message {
|
|
padding: 1rem;
|
|
text-align: center;
|
|
color: #757575;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* 어댑터 헤더 스타일 */
|
|
.adapter-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
/* 대시보드 헤더 스타일 */
|
|
.dashboard-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
/* 제목과 버튼을 한 줄에 나란히 표시하기 위한 컨테이너 */
|
|
.header-title-container {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.adapter-actions {
|
|
margin-left: 10px; /* 제목과 버튼 사이 간격 */
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.filter-btn:hover {
|
|
background-color: var(--color-gray-200);
|
|
color: var(--color-gray-800);
|
|
}
|
|
|
|
.filter-btn.active {
|
|
background-color: var(--color-primary);
|
|
color: white;
|
|
border-color: var(--color-primary);
|
|
}
|
|
|
|
.btn-primary {
|
|
background-color: #007bff;
|
|
color: white;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background-color: #0069d9;
|
|
opacity: 1 !important;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// 어댑터 요약 행 생성 함수
|
|
function createAdapterSummaryRow(adapterSummary) {
|
|
var template = document.getElementById('adapter-summary-row-template');
|
|
var clone = document.importNode(template.content, true);
|
|
|
|
// 어댑터 유형 설정
|
|
clone.querySelector('.adapter-type-name').textContent = adapterSummary.adapterType || '—';
|
|
|
|
// 상태 설정
|
|
var statusBadge = clone.querySelector('.status-badge');
|
|
statusBadge.className = 'status-badge';
|
|
|
|
if (adapterSummary.overallStatus === 'normal') {
|
|
statusBadge.classList.add('adapter-status-normal');
|
|
statusBadge.textContent = '정상';
|
|
} else if (adapterSummary.overallStatus === 'warning') {
|
|
statusBadge.classList.add('adapter-status-warning');
|
|
statusBadge.textContent = '경고';
|
|
} else if (adapterSummary.overallStatus === 'error') {
|
|
statusBadge.classList.add('adapter-status-error');
|
|
statusBadge.textContent = '오류';
|
|
} else if (adapterSummary.overallStatus === 'inactive') {
|
|
statusBadge.classList.add('adapter-status-inactive');
|
|
statusBadge.textContent = '정지';
|
|
} else {
|
|
statusBadge.classList.add('adapter-status-inactive');
|
|
statusBadge.textContent = '알 수 없음';
|
|
}
|
|
|
|
// 상태별 카운트 설정
|
|
clone.querySelector('.error-count').textContent = formatNumber(adapterSummary.errorCount || 0);
|
|
clone.querySelector('.warning-count').textContent = formatNumber(adapterSummary.warningCount || 0);
|
|
clone.querySelector('.normal-count').textContent = formatNumber(adapterSummary.normalCount || 0);
|
|
clone.querySelector('.inactive-count').textContent = formatNumber(adapterSummary.inactiveCount || 0);
|
|
clone.querySelector('.total-count').textContent = formatNumber(adapterSummary.totalCount || 0);
|
|
|
|
return clone;
|
|
}
|
|
|
|
// 어댑터 요약 테이블 업데이트 함수
|
|
function updateAdapterSummaryTable(data) {
|
|
if (!data || !data.serverAdapters) return;
|
|
|
|
// 어댑터 요약 컨테이너 찾기
|
|
var summaryBody = document.querySelector('.adapter-summary-body');
|
|
if (!summaryBody) return;
|
|
|
|
// 컨테이너 초기화
|
|
summaryBody.innerHTML = '';
|
|
|
|
// 모든 서버의 어댑터 요약 데이터 통합
|
|
var allAdapterSummaries = [];
|
|
data.serverAdapters.forEach(function(serverAdapter) {
|
|
if (serverAdapter.adapterSummaries && serverAdapter.adapterSummaries.length > 0) {
|
|
allAdapterSummaries = allAdapterSummaries.concat(serverAdapter.adapterSummaries);
|
|
}
|
|
});
|
|
|
|
// 어댑터 유형별로 그룹화
|
|
var adapterTypeMap = {};
|
|
allAdapterSummaries.forEach(function(summary) {
|
|
if (!adapterTypeMap[summary.adapterType]) {
|
|
adapterTypeMap[summary.adapterType] = summary;
|
|
} else {
|
|
// 기존 데이터에 카운트 누적
|
|
var existing = adapterTypeMap[summary.adapterType];
|
|
existing.errorCount = (existing.errorCount || 0) + (summary.errorCount || 0);
|
|
existing.warningCount = (existing.warningCount || 0) + (summary.warningCount || 0);
|
|
existing.normalCount = (existing.normalCount || 0) + (summary.normalCount || 0);
|
|
existing.inactiveCount = (existing.inactiveCount || 0) + (summary.inactiveCount || 0);
|
|
existing.totalCount = (existing.totalCount || 0) + (summary.totalCount || 0);
|
|
|
|
// 전체 상태 업데이트
|
|
if (summary.overallStatus === 'error' || existing.overallStatus === 'error') {
|
|
existing.overallStatus = 'error';
|
|
} else if (summary.overallStatus === 'warning' || existing.overallStatus === 'warning') {
|
|
existing.overallStatus = 'warning';
|
|
}
|
|
}
|
|
});
|
|
|
|
// 필터링된 어댑터 유형만 표시 (Socket, Socket2, HTTP)
|
|
var filteredAdapterTypes = Object.keys(adapterTypeMap).filter(function(type) {
|
|
return type === 'Socket' || type === 'Socket2' || type === 'HTTP';
|
|
});
|
|
|
|
if (filteredAdapterTypes.length > 0) {
|
|
// 어댑터 유형별로 행 추가
|
|
filteredAdapterTypes.forEach(function(type) {
|
|
var summaryRow = createAdapterSummaryRow(adapterTypeMap[type]);
|
|
summaryBody.appendChild(summaryRow);
|
|
});
|
|
} else {
|
|
// 데이터가 없는 경우 안내 메시지 표시
|
|
var emptyRow = document.createElement('div');
|
|
emptyRow.className = 'empty-data-message';
|
|
emptyRow.textContent = '표시할 어댑터 데이터가 없습니다.';
|
|
summaryBody.appendChild(emptyRow);
|
|
}
|
|
}
|
|
|
|
// 어댑터 요약 데이터 로드 함수
|
|
function loadAdapterSummaryData() {
|
|
// 어댑터 요약 데이터 API 호출
|
|
ModernDashboardApi.getAdapterStatus(null, function(data) {
|
|
if (data) {
|
|
updateAdapterSummaryTable(data);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 문서 로드 완료 시 초기화
|
|
$(document).ready(function() {
|
|
// 초기 데이터 로드
|
|
loadAdapterSummaryData();
|
|
|
|
// 소켓 어댑터 상세 보기 버튼 이벤트
|
|
$('.view-socket-detail').on('click', function() {
|
|
// 소켓 상세 정보 모달 열기
|
|
openSocketDetailModal();
|
|
});
|
|
|
|
// DashboardEventManager를 사용하여 새로고침 이벤트 구독
|
|
if (window.DashboardEventManager) {
|
|
window.DashboardEventManager.on('refresh', function() {
|
|
// 어댑터 요약 데이터 새로고침
|
|
loadAdapterSummaryData();
|
|
});
|
|
}
|
|
});
|
|
</script> |