init tools repo
This commit is contained in:
134
asf-cloud-server/TBM_devbench/views/layout.ejs
Normal file
134
asf-cloud-server/TBM_devbench/views/layout.ejs
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DevBench Manager</title>
|
||||
<link rel="icon" type="image/png" href="/images/tbm-icon.png">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="/css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/images/tbm-icon.png" alt="TBM" class="tbm-icon me-2" style="height: 32px; width: 32px;">
|
||||
<img src="/images/nabd-logo-white.svg" alt="NABD Solutions" class="company-logo">
|
||||
DevBench Manager
|
||||
</a>
|
||||
<div class="navbar-nav ms-auto">
|
||||
<% if (typeof username !== 'undefined') { %>
|
||||
<a class="nav-link" href="/help" title="Help">
|
||||
<i class="fas fa-question-circle"></i> Help
|
||||
</a>
|
||||
<span class="navbar-text me-3">Welcome, <%= username %></span>
|
||||
<a class="nav-link" href="/logout">
|
||||
<i class="fas fa-sign-out-alt"></i> Logout
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<%- body %>
|
||||
</div>
|
||||
|
||||
<!-- Theme Toggle Button -->
|
||||
<button class="theme-toggle" id="themeToggle" title="Toggle Dark/Light Theme">
|
||||
<i class="fas fa-moon" id="themeIcon"></i>
|
||||
</button>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
// Theme Toggle Functionality
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
const themeIcon = document.getElementById('themeIcon');
|
||||
const body = document.body;
|
||||
|
||||
// Load saved theme preference
|
||||
const savedTheme = localStorage.getItem('theme') || 'light';
|
||||
if (savedTheme === 'dark') {
|
||||
body.classList.add('dark-theme');
|
||||
themeIcon.classList.remove('fa-moon');
|
||||
themeIcon.classList.add('fa-sun');
|
||||
}
|
||||
|
||||
// Toggle theme
|
||||
themeToggle.addEventListener('click', () => {
|
||||
body.classList.toggle('dark-theme');
|
||||
|
||||
if (body.classList.contains('dark-theme')) {
|
||||
themeIcon.classList.remove('fa-moon');
|
||||
themeIcon.classList.add('fa-sun');
|
||||
localStorage.setItem('theme', 'dark');
|
||||
} else {
|
||||
themeIcon.classList.remove('fa-sun');
|
||||
themeIcon.classList.add('fa-moon');
|
||||
localStorage.setItem('theme', 'light');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// WebSocket connection for real-time updates
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const ws = new WebSocket(`${protocol}//${window.location.host}`);
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log('WebSocket connected');
|
||||
// Register this connection with user ID if available
|
||||
<% if (typeof username !== 'undefined') { %>
|
||||
// Get user ID from session (we'll need to pass this from server)
|
||||
fetch('/api/user-info')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.userId) {
|
||||
ws.send(JSON.stringify({
|
||||
type: 'register',
|
||||
userId: data.userId
|
||||
}));
|
||||
console.log('Registered WebSocket for user:', data.userId);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error getting user info:', error));
|
||||
<% } %>
|
||||
};
|
||||
|
||||
ws.onmessage = function(event) {
|
||||
const message = JSON.parse(event.data);
|
||||
console.log('WebSocket message received:', message);
|
||||
handleWebSocketMessage(message);
|
||||
};
|
||||
|
||||
ws.onerror = function(error) {
|
||||
console.error('WebSocket error:', error);
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
console.log('WebSocket disconnected');
|
||||
};
|
||||
|
||||
function handleWebSocketMessage(message) {
|
||||
if (message.type === 'script_output') {
|
||||
const logElement = document.getElementById(`log-${message.devbenchId}`);
|
||||
if (logElement) {
|
||||
logElement.textContent += message.data;
|
||||
logElement.scrollTop = logElement.scrollHeight;
|
||||
}
|
||||
} else if (message.type === 'script_complete') {
|
||||
console.log('Script completed with exit code:', message.exitCode);
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 3000);
|
||||
} else if (message.type === 'status_update') {
|
||||
const statusElement = document.getElementById(`status-${message.devbenchId}`);
|
||||
if (statusElement) {
|
||||
statusElement.className = `badge bg-${message.status === 'active' ? 'success' : 'danger'}`;
|
||||
statusElement.textContent = message.status;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user