fix
This commit is contained in:
parent
0a31b03601
commit
7728e5e5b7
85
app.js
85
app.js
@ -191,7 +191,7 @@ addConnectionForm.addEventListener('submit', (e) => {
|
||||
// Function to add a new connection
|
||||
function addConnection(topicHex) {
|
||||
console.log(`[DEBUG] Adding connection with topic: ${topicHex}`);
|
||||
|
||||
|
||||
if (Object.keys(connections).length === 0) {
|
||||
console.log('[DEBUG] Hiding welcome page after first connection');
|
||||
hideWelcomePage(); // Hide the welcome page when the first connection is added
|
||||
@ -490,7 +490,7 @@ function renderContainers(containers) {
|
||||
|
||||
// Add event listeners for action buttons
|
||||
addActionListeners(row, container);
|
||||
// Add event listener for duplicate button
|
||||
// Add event listener for duplicate button
|
||||
const duplicateBtn = row.querySelector('.action-duplicate');
|
||||
duplicateBtn.addEventListener('click', () => openDuplicateModal(container));
|
||||
|
||||
@ -508,15 +508,15 @@ function addActionListeners(row, container) {
|
||||
startBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Starting container "${container.Names[0]}"...`);
|
||||
sendCommand('startContainer', { id: container.Id });
|
||||
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} started`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Start container response:', response);
|
||||
|
||||
|
||||
showAlert('success', response.message);
|
||||
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
} catch (error) {
|
||||
@ -531,15 +531,15 @@ function addActionListeners(row, container) {
|
||||
stopBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Stopping container "${container.Names[0]}"...`);
|
||||
sendCommand('stopContainer', { id: container.Id });
|
||||
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} stopped`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Stop container response:', response);
|
||||
|
||||
|
||||
showAlert('success', response.message);
|
||||
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
} catch (error) {
|
||||
@ -553,41 +553,41 @@ function addActionListeners(row, container) {
|
||||
|
||||
|
||||
// Restart Button
|
||||
restartBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Restarting container "${container.Names[0]}"...`);
|
||||
sendCommand('restartContainer', { id: container.Id });
|
||||
restartBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Restarting container "${container.Names[0]}"...`);
|
||||
sendCommand('restartContainer', { id: container.Id });
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} restarted`;
|
||||
const expectedMessageFragment = `Container ${container.Id} restarted`;
|
||||
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Restart container response:', response);
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Restart container response:', response);
|
||||
|
||||
showAlert('success', response.message);
|
||||
showAlert('success', response.message);
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
} catch (error) {
|
||||
console.error('[ERROR] Failed to restart container:', error.message);
|
||||
showAlert('danger', error.message || 'Failed to restart container.');
|
||||
} finally {
|
||||
console.log('[DEBUG] Hiding status indicator in restartBtn finally block');
|
||||
hideStatusIndicator();
|
||||
}
|
||||
});
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
} catch (error) {
|
||||
console.error('[ERROR] Failed to restart container:', error.message);
|
||||
showAlert('danger', error.message || 'Failed to restart container.');
|
||||
} finally {
|
||||
console.log('[DEBUG] Hiding status indicator in restartBtn finally block');
|
||||
hideStatusIndicator();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Remove Button
|
||||
removeBtn.addEventListener('click', async () => {
|
||||
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
||||
deleteModal.show();
|
||||
|
||||
|
||||
const confirmDeleteBtn = document.getElementById('confirm-delete-btn');
|
||||
confirmDeleteBtn.onclick = async () => {
|
||||
deleteModal.hide();
|
||||
|
||||
|
||||
showStatusIndicator(`Deleting container "${container.Names[0]}"...`);
|
||||
|
||||
|
||||
// Check if the container has active terminals
|
||||
if (window.openTerminals[container.Id]) {
|
||||
console.log(`[INFO] Closing active terminals for container: ${container.Id}`);
|
||||
@ -600,24 +600,29 @@ restartBtn.addEventListener('click', async () => {
|
||||
});
|
||||
delete window.openTerminals[container.Id];
|
||||
}
|
||||
|
||||
|
||||
// Hide the terminal modal if it is active
|
||||
const terminalModal = document.getElementById('terminal-modal');
|
||||
if (terminalModal.style.display === 'flex') {
|
||||
console.log(`[INFO] Hiding terminal modal for container: ${container.Id}`);
|
||||
terminalModal.style.display = 'none';
|
||||
}
|
||||
|
||||
|
||||
|
||||
terminalModal.addEventListener('shown.bs.modal', () => {
|
||||
terminal.focus();
|
||||
});
|
||||
|
||||
sendCommand('removeContainer', { id: container.Id });
|
||||
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} removed`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Remove container response:', response);
|
||||
|
||||
|
||||
showAlert('success', response.message);
|
||||
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
} catch (error) {
|
||||
@ -629,7 +634,7 @@ restartBtn.addEventListener('click', async () => {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
terminalBtn.addEventListener('click', () => {
|
||||
console.log(`[DEBUG] Opening terminal for container ID: ${container.Id}`);
|
||||
@ -675,7 +680,7 @@ function openDuplicateModal(container) {
|
||||
console.log(`[INFO] Opening Duplicate Modal for container: ${container.Id}`);
|
||||
|
||||
showStatusIndicator('Fetching container configuration...');
|
||||
|
||||
|
||||
// Send a command to inspect the container
|
||||
sendCommand('inspectContainer', { id: container.Id });
|
||||
|
||||
|
237
index.html
237
index.html
@ -22,10 +22,9 @@
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#titlebar {
|
||||
-webkit-app-region: drag;
|
||||
@ -79,18 +78,14 @@
|
||||
}
|
||||
|
||||
#content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* Keep vertical stacking for child elements */
|
||||
margin-left: 250px;
|
||||
/* Leave space for the sidebar */
|
||||
flex: 1;
|
||||
/* Allow the content to grow */
|
||||
padding: 30px;
|
||||
overflow-y: auto;
|
||||
/* Allow scrolling if content overflows */
|
||||
position: relative;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column; /* Keep vertical stacking for child elements */
|
||||
margin-left: 250px; /* Leave space for the sidebar */
|
||||
flex: 1; /* Allow the content to grow */
|
||||
padding: 30px;
|
||||
overflow-y: auto; /* Allow scrolling if content overflows */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#sidebar.collapsed~#content {
|
||||
margin-left: 50px;
|
||||
@ -175,42 +170,18 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
/* Enable smooth scrolling on touch devices */
|
||||
}
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
white-space: nowrap;
|
||||
/* Prevent table cells from wrapping text */
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
font-size: 0.9rem;
|
||||
/* Adjust font size for smaller screens */
|
||||
padding: 0.5rem;
|
||||
/* Reduce padding */
|
||||
}
|
||||
}
|
||||
|
||||
#status-indicator {
|
||||
display: none;
|
||||
/* Ensure it's hidden by default */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
z-index: 1050;
|
||||
}
|
||||
display: none; /* Ensure it's hidden by default */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
z-index: 1050;
|
||||
}
|
||||
|
||||
#status-indicator .spinner-border {
|
||||
width: 3rem;
|
||||
@ -224,146 +195,40 @@
|
||||
}
|
||||
|
||||
#welcome-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* Stack child elements vertically */
|
||||
justify-content: center;
|
||||
/* Center content vertically */
|
||||
align-items: center;
|
||||
/* Center content horizontally */
|
||||
text-align: center;
|
||||
/* Center-align text */
|
||||
position: absolute;
|
||||
/* Overlay it over the content area */
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/* Center it perfectly in the content */
|
||||
max-width: 800px;
|
||||
/* Restrict the width of the welcome page */
|
||||
width: 100%;
|
||||
/* Allow it to scale */
|
||||
padding: 20px;
|
||||
background-color: transparent;
|
||||
/* Match the theme */
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column; /* Stack child elements vertically */
|
||||
justify-content: center; /* Center content vertically */
|
||||
align-items: center; /* Center content horizontally */
|
||||
text-align: center; /* Center-align text */
|
||||
position: absolute; /* Overlay it over the content area */
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); /* Center it perfectly in the content */
|
||||
max-width: 800px; /* Restrict the width of the welcome page */
|
||||
width: 100%; /* Allow it to scale */
|
||||
padding: 20px;
|
||||
background-color: transparent; /* Match the theme */
|
||||
}
|
||||
|
||||
#welcome-page.hidden {
|
||||
display: none !important;
|
||||
/* Completely hide when not needed */
|
||||
}
|
||||
#welcome-page.hidden {
|
||||
display: none !important; /* Completely hide when not needed */
|
||||
}
|
||||
|
||||
#dashboard {
|
||||
display: flex;
|
||||
/* Use flex layout for content within the dashboard */
|
||||
flex-direction: column;
|
||||
/* Stack elements vertically */
|
||||
flex: 1;
|
||||
/* Ensure it uses all available space */
|
||||
width: 100%;
|
||||
/* Take up the full width of the content area */
|
||||
padding: 0;
|
||||
/* Remove extra padding */
|
||||
overflow-y: auto;
|
||||
/* Allow vertical scrolling if needed */
|
||||
position: relative;
|
||||
/* Prevent overlap with other elements */
|
||||
}
|
||||
#dashboard {
|
||||
display: flex; /* Use flex layout for content within the dashboard */
|
||||
flex-direction: column; /* Stack elements vertically */
|
||||
flex: 1; /* Ensure it uses all available space */
|
||||
width: 100%; /* Take up the full width of the content area */
|
||||
padding: 0; /* Remove extra padding */
|
||||
overflow-y: auto; /* Allow vertical scrolling if needed */
|
||||
position: relative; /* Prevent overlap with other elements */
|
||||
}
|
||||
|
||||
#dashboard.hidden {
|
||||
display: none !important;
|
||||
/* Hide the dashboard completely when not needed */
|
||||
}
|
||||
|
||||
#alert-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 1055;
|
||||
/* Ensure it overlays other elements */
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
/* Stack alerts upwards */
|
||||
gap: 10px;
|
||||
/* Add space between alerts */
|
||||
}
|
||||
|
||||
.alert {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
max-width: 80%;
|
||||
/* Ensure the alert doesn't stretch too wide */
|
||||
padding: 12px 20px;
|
||||
/* Adjust padding for a more balanced look */
|
||||
background-color: #2b2b2b;
|
||||
/* Slightly lighter background for better contrast */
|
||||
color: #e0e0e0;
|
||||
/* Softer white text for readability */
|
||||
border-radius: 6px;
|
||||
/* Round corners for a modern look */
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
|
||||
/* Add subtle shadow for depth */
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
/* Adjust font size for readability */
|
||||
animation: fadeIn 0.3s ease-out, fadeOut 4.5s ease-in forwards;
|
||||
white-space: nowrap;
|
||||
/* Prevent text wrapping */
|
||||
overflow: hidden;
|
||||
/* Hide overflow for long text */
|
||||
text-overflow: ellipsis;
|
||||
/* Add ellipsis for overflowed text */
|
||||
}
|
||||
|
||||
.alert.success {
|
||||
border-left: 6px solid #28a745;
|
||||
/* Green border for success */
|
||||
}
|
||||
|
||||
.alert.danger {
|
||||
border-left: 6px solid #dc3545;
|
||||
/* Red border for danger */
|
||||
}
|
||||
|
||||
.alert .close-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #e0e0e0;
|
||||
/* Use the same text color for consistency */
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
margin-left: 15px;
|
||||
/* Space between text and close button */
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
90% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
}
|
||||
#dashboard.hidden {
|
||||
display: none !important; /* Hide the dashboard completely when not needed */
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
Loading…
Reference in New Issue
Block a user