forked from snxraven/peardock
Add restart to actions
This commit is contained in:
parent
964c6c60f3
commit
4f13281873
59
app.js
59
app.js
@ -105,27 +105,31 @@ function hideStatusIndicator() {
|
|||||||
// Show Alert
|
// Show Alert
|
||||||
function showAlert(type, message) {
|
function showAlert(type, message) {
|
||||||
const alertContainer = document.getElementById('alert-container');
|
const alertContainer = document.getElementById('alert-container');
|
||||||
|
|
||||||
|
// Create alert element
|
||||||
const alert = document.createElement('div');
|
const alert = document.createElement('div');
|
||||||
alert.className = `alert alert-${type} alert-dismissible fade show`;
|
alert.className = `alert ${type}`;
|
||||||
alert.role = 'alert';
|
|
||||||
alert.innerHTML = `
|
alert.innerHTML = `
|
||||||
${message}
|
<span>${message}</span>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
<button class="close-btn" aria-label="Close">×</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Add close button functionality
|
||||||
|
const closeButton = alert.querySelector('.close-btn');
|
||||||
|
closeButton.addEventListener('click', () => {
|
||||||
|
alert.remove(); // Remove alert on close
|
||||||
|
});
|
||||||
|
|
||||||
|
// Append alert to container
|
||||||
alertContainer.appendChild(alert);
|
alertContainer.appendChild(alert);
|
||||||
|
|
||||||
// Automatically hide the status indicator for errors or success
|
// Automatically remove alert after 5 seconds
|
||||||
if (type === 'danger' || type === 'success') {
|
|
||||||
hideStatusIndicator();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Automatically remove the alert after 5 seconds
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
alert.classList.remove('show');
|
alert.remove();
|
||||||
setTimeout(() => alert.remove(), 300); // Bootstrap's fade-out transition duration
|
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Collapse Sidebar Functionality
|
// Collapse Sidebar Functionality
|
||||||
const collapseSidebarBtn = document.getElementById('collapse-sidebar-btn');
|
const collapseSidebarBtn = document.getElementById('collapse-sidebar-btn');
|
||||||
collapseSidebarBtn.addEventListener('click', () => {
|
collapseSidebarBtn.addEventListener('click', () => {
|
||||||
@ -476,8 +480,11 @@ function renderContainers(containers) {
|
|||||||
<button class="btn btn-secondary btn-sm action-duplicate">
|
<button class="btn btn-secondary btn-sm action-duplicate">
|
||||||
<i class="fas fa-clone"></i>
|
<i class="fas fa-clone"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-info btn-sm action-restart" ${container.State !== 'running' ? 'disabled' : ''}>
|
||||||
|
<i class="fas fa-redo"></i>
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
containerList.appendChild(row);
|
containerList.appendChild(row);
|
||||||
|
|
||||||
// Add event listeners for action buttons
|
// Add event listeners for action buttons
|
||||||
@ -494,6 +501,7 @@ function addActionListeners(row, container) {
|
|||||||
const stopBtn = row.querySelector('.action-stop');
|
const stopBtn = row.querySelector('.action-stop');
|
||||||
const removeBtn = row.querySelector('.action-remove');
|
const removeBtn = row.querySelector('.action-remove');
|
||||||
const terminalBtn = row.querySelector('.action-terminal');
|
const terminalBtn = row.querySelector('.action-terminal');
|
||||||
|
const restartBtn = row.querySelector('.action-restart');
|
||||||
|
|
||||||
// Start Button
|
// Start Button
|
||||||
startBtn.addEventListener('click', async () => {
|
startBtn.addEventListener('click', async () => {
|
||||||
@ -543,6 +551,31 @@ function addActionListeners(row, container) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Restart Button
|
||||||
|
restartBtn.addEventListener('click', async () => {
|
||||||
|
showStatusIndicator(`Restarting container "${container.Names[0]}"...`);
|
||||||
|
sendCommand('restartContainer', { id: container.Id });
|
||||||
|
|
||||||
|
const expectedMessageFragment = `Container ${container.Id} restarted`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||||
|
console.log('[DEBUG] Restart container response:', response);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Remove Button
|
// Remove Button
|
||||||
removeBtn.addEventListener('click', async () => {
|
removeBtn.addEventListener('click', async () => {
|
||||||
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
||||||
|
68
index.html
68
index.html
@ -226,6 +226,74 @@
|
|||||||
|
|
||||||
#dashboard.hidden {
|
#dashboard.hidden {
|
||||||
display: none !important; /* Hide the dashboard completely when not needed */
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
@ -118,6 +118,12 @@ swarm.on('connection', (peer) => {
|
|||||||
response = { success: true, message: `Container ${parsedData.args.id} stopped` };
|
response = { success: true, message: `Container ${parsedData.args.id} stopped` };
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'restartContainer':
|
||||||
|
console.log(`[INFO] Handling 'restartContainer' command for container: ${parsedData.args.id}`);
|
||||||
|
await docker.getContainer(parsedData.args.id).restart();
|
||||||
|
response = { success: true, message: `Container ${parsedData.args.id} restarted` };
|
||||||
|
break;
|
||||||
|
|
||||||
case 'removeContainer':
|
case 'removeContainer':
|
||||||
console.log(`[INFO] Handling 'removeContainer' command for container: ${parsedData.args.id}`);
|
console.log(`[INFO] Handling 'removeContainer' command for container: ${parsedData.args.id}`);
|
||||||
await docker.getContainer(parsedData.args.id).remove({ force: true });
|
await docker.getContainer(parsedData.args.id).remove({ force: true });
|
||||||
|
Loading…
Reference in New Issue
Block a user