308 lines
11 KiB
Python
308 lines
11 KiB
Python
|
|
"""
|
||
|
|
Dashboard HTML templates for Calejo Control Adapter
|
||
|
|
"""
|
||
|
|
|
||
|
|
DASHBOARD_HTML = """
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>Calejo Control Adapter - Dashboard</title>
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
font-family: Arial, sans-serif;
|
||
|
|
margin: 0;
|
||
|
|
padding: 20px;
|
||
|
|
background-color: #f5f5f5;
|
||
|
|
}
|
||
|
|
.container {
|
||
|
|
max-width: 1200px;
|
||
|
|
margin: 0 auto;
|
||
|
|
background: white;
|
||
|
|
padding: 20px;
|
||
|
|
border-radius: 8px;
|
||
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
|
|
}
|
||
|
|
.header {
|
||
|
|
text-align: center;
|
||
|
|
margin-bottom: 30px;
|
||
|
|
border-bottom: 2px solid #007acc;
|
||
|
|
padding-bottom: 10px;
|
||
|
|
}
|
||
|
|
.status-grid {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
|
|
gap: 15px;
|
||
|
|
margin-bottom: 30px;
|
||
|
|
}
|
||
|
|
.status-card {
|
||
|
|
padding: 15px;
|
||
|
|
border-radius: 6px;
|
||
|
|
text-align: center;
|
||
|
|
background: #f8f9fa;
|
||
|
|
border-left: 4px solid #007acc;
|
||
|
|
}
|
||
|
|
.status-card.running { border-left-color: #28a745; }
|
||
|
|
.status-card.error { border-left-color: #dc3545; }
|
||
|
|
.status-card.warning { border-left-color: #ffc107; }
|
||
|
|
.config-section {
|
||
|
|
margin-bottom: 30px;
|
||
|
|
padding: 20px;
|
||
|
|
border: 1px solid #ddd;
|
||
|
|
border-radius: 6px;
|
||
|
|
}
|
||
|
|
.form-group {
|
||
|
|
margin-bottom: 15px;
|
||
|
|
}
|
||
|
|
label {
|
||
|
|
display: block;
|
||
|
|
margin-bottom: 5px;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
input, select {
|
||
|
|
width: 100%;
|
||
|
|
padding: 8px;
|
||
|
|
border: 1px solid #ddd;
|
||
|
|
border-radius: 4px;
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
button {
|
||
|
|
background: #007acc;
|
||
|
|
color: white;
|
||
|
|
padding: 10px 20px;
|
||
|
|
border: none;
|
||
|
|
border-radius: 4px;
|
||
|
|
cursor: pointer;
|
||
|
|
margin-right: 10px;
|
||
|
|
}
|
||
|
|
button:hover {
|
||
|
|
background: #005a9e;
|
||
|
|
}
|
||
|
|
.alert {
|
||
|
|
padding: 10px;
|
||
|
|
border-radius: 4px;
|
||
|
|
margin-bottom: 15px;
|
||
|
|
}
|
||
|
|
.alert.error {
|
||
|
|
background: #f8d7da;
|
||
|
|
color: #721c24;
|
||
|
|
border: 1px solid #f5c6cb;
|
||
|
|
}
|
||
|
|
.alert.warning {
|
||
|
|
background: #fff3cd;
|
||
|
|
color: #856404;
|
||
|
|
border: 1px solid #ffeaa7;
|
||
|
|
}
|
||
|
|
.alert.success {
|
||
|
|
background: #d4edda;
|
||
|
|
color: #155724;
|
||
|
|
border: 1px solid #c3e6cb;
|
||
|
|
}
|
||
|
|
.tab-container {
|
||
|
|
margin-bottom: 20px;
|
||
|
|
}
|
||
|
|
.tab-buttons {
|
||
|
|
display: flex;
|
||
|
|
border-bottom: 1px solid #ddd;
|
||
|
|
}
|
||
|
|
.tab-button {
|
||
|
|
padding: 10px 20px;
|
||
|
|
background: none;
|
||
|
|
border: none;
|
||
|
|
cursor: pointer;
|
||
|
|
border-bottom: 3px solid transparent;
|
||
|
|
}
|
||
|
|
.tab-button.active {
|
||
|
|
border-bottom-color: #007acc;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
.tab-content {
|
||
|
|
display: none;
|
||
|
|
padding: 20px 0;
|
||
|
|
}
|
||
|
|
.tab-content.active {
|
||
|
|
display: block;
|
||
|
|
}
|
||
|
|
.action-buttons {
|
||
|
|
margin-top: 20px;
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
.logs-container {
|
||
|
|
max-height: 400px;
|
||
|
|
overflow-y: auto;
|
||
|
|
border: 1px solid #ddd;
|
||
|
|
border-radius: 4px;
|
||
|
|
padding: 10px;
|
||
|
|
background: #f8f9fa;
|
||
|
|
}
|
||
|
|
.log-entry {
|
||
|
|
padding: 5px;
|
||
|
|
border-bottom: 1px solid #eee;
|
||
|
|
font-family: monospace;
|
||
|
|
font-size: 12px;
|
||
|
|
}
|
||
|
|
.log-entry.error {
|
||
|
|
color: #dc3545;
|
||
|
|
}
|
||
|
|
.log-entry.warning {
|
||
|
|
color: #856404;
|
||
|
|
}
|
||
|
|
.log-entry.info {
|
||
|
|
color: #007acc;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="container">
|
||
|
|
<div class="header">
|
||
|
|
<h1>Calejo Control Adapter Dashboard</h1>
|
||
|
|
<p>Configuration and Monitoring Interface</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="tab-container">
|
||
|
|
<div class="tab-buttons">
|
||
|
|
<button class="tab-button active" onclick="showTab('status')">Status</button>
|
||
|
|
<button class="tab-button" onclick="showTab('config')">Configuration</button>
|
||
|
|
<button class="tab-button" onclick="showTab('logs')">Logs</button>
|
||
|
|
<button class="tab-button" onclick="showTab('actions')">Actions</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Status Tab -->
|
||
|
|
<div id="status-tab" class="tab-content active">
|
||
|
|
<h2>System Status</h2>
|
||
|
|
<div class="status-grid" id="status-grid">
|
||
|
|
<!-- Status cards will be populated by JavaScript -->
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button onclick="refreshStatus()">Refresh Status</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Configuration Tab -->
|
||
|
|
<div id="config-tab" class="tab-content">
|
||
|
|
<h2>Configuration</h2>
|
||
|
|
<div id="alerts"></div>
|
||
|
|
|
||
|
|
<form id="config-form">
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>Database Configuration</h3>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="db_host">Host:</label>
|
||
|
|
<input type="text" id="db_host" name="db_host" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="db_port">Port:</label>
|
||
|
|
<input type="number" id="db_port" name="db_port" min="1" max="65535" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="db_name">Database Name:</label>
|
||
|
|
<input type="text" id="db_name" name="db_name" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="db_user">Username:</label>
|
||
|
|
<input type="text" id="db_user" name="db_user" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="db_password">Password:</label>
|
||
|
|
<input type="password" id="db_password" name="db_password">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>Protocol Configuration</h3>
|
||
|
|
<div class="form-group">
|
||
|
|
<label>
|
||
|
|
<input type="checkbox" id="opcua_enabled" name="opcua_enabled">
|
||
|
|
Enable OPC UA Server
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="opcua_port">OPC UA Port:</label>
|
||
|
|
<input type="number" id="opcua_port" name="opcua_port" min="1" max="65535">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-group">
|
||
|
|
<label>
|
||
|
|
<input type="checkbox" id="modbus_enabled" name="modbus_enabled">
|
||
|
|
Enable Modbus Server
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="modbus_port">Modbus Port:</label>
|
||
|
|
<input type="number" id="modbus_port" name="modbus_port" min="1" max="65535">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>REST API Configuration</h3>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="rest_api_host">Host:</label>
|
||
|
|
<input type="text" id="rest_api_host" name="rest_api_host">
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="rest_api_port">Port:</label>
|
||
|
|
<input type="number" id="rest_api_port" name="rest_api_port" min="1" max="65535">
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label>
|
||
|
|
<input type="checkbox" id="rest_api_cors_enabled" name="rest_api_cors_enabled">
|
||
|
|
Enable CORS
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>Monitoring Configuration</h3>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="health_monitor_port">Health Monitor Port:</label>
|
||
|
|
<input type="number" id="health_monitor_port" name="health_monitor_port" min="1" max="65535">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button type="button" onclick="loadConfiguration()">Load Current</button>
|
||
|
|
<button type="button" onclick="saveConfiguration()">Save Configuration</button>
|
||
|
|
<button type="button" onclick="validateConfiguration()">Validate</button>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Logs Tab -->
|
||
|
|
<div id="logs-tab" class="tab-content">
|
||
|
|
<h2>System Logs</h2>
|
||
|
|
<div class="logs-container" id="logs-container">
|
||
|
|
<!-- Logs will be populated by JavaScript -->
|
||
|
|
</div>
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button onclick="loadLogs()">Refresh Logs</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Actions Tab -->
|
||
|
|
<div id="actions-tab" class="tab-content">
|
||
|
|
<h2>System Actions</h2>
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>System Operations</h3>
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button onclick="restartSystem()" style="background: #dc3545;">Restart System</button>
|
||
|
|
<button onclick="createBackup()" style="background: #28a745;">Create Backup</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="config-section">
|
||
|
|
<h3>Health Checks</h3>
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button onclick="runHealthCheck()">Run Health Check</button>
|
||
|
|
<button onclick="viewMetrics()">View Metrics</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="/static/dashboard.js"></script>
|
||
|
|
</body>
|
||
|
|
</html>
|
||
|
|
"""
|