Spaces:
Sleeping
Sleeping
Commit ·
1ab323c
1
Parent(s): 0383b17
restart sleeping
Browse files- templates/dashboard.html +88 -0
templates/dashboard.html
CHANGED
|
@@ -506,6 +506,7 @@
|
|
| 506 |
<nav class="navbar">
|
| 507 |
<h1>Spaces Dashboard</h1>
|
| 508 |
<div class="user-info">
|
|
|
|
| 509 |
{% if user.avatar_url %}
|
| 510 |
<img src="{{ user.avatar_url }}" alt="" class="avatar">
|
| 511 |
{% endif %}
|
|
@@ -632,6 +633,29 @@
|
|
| 632 |
{% endif %}
|
| 633 |
</main>
|
| 634 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 635 |
<script>
|
| 636 |
document.querySelectorAll('.space-toggle').forEach(el => {
|
| 637 |
el.addEventListener('click', () => {
|
|
@@ -640,6 +664,70 @@
|
|
| 640 |
details.classList.toggle('open');
|
| 641 |
});
|
| 642 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 643 |
</script>
|
| 644 |
</body>
|
| 645 |
</html>
|
|
|
|
| 506 |
<nav class="navbar">
|
| 507 |
<h1>Spaces Dashboard</h1>
|
| 508 |
<div class="user-info">
|
| 509 |
+
<button class="utils-btn" id="utils-btn">Utils</button>
|
| 510 |
{% if user.avatar_url %}
|
| 511 |
<img src="{{ user.avatar_url }}" alt="" class="avatar">
|
| 512 |
{% endif %}
|
|
|
|
| 633 |
{% endif %}
|
| 634 |
</main>
|
| 635 |
</div>
|
| 636 |
+
<div class="modal-overlay" id="modal-overlay">
|
| 637 |
+
<div class="modal">
|
| 638 |
+
<div class="modal-header">
|
| 639 |
+
<h3 class="modal-title">Utils</h3>
|
| 640 |
+
<button class="modal-close" id="modal-close">×</button>
|
| 641 |
+
</div>
|
| 642 |
+
<div class="util-item">
|
| 643 |
+
<div class="util-item-header">
|
| 644 |
+
<span class="util-name">Wake All Sleeping Spaces</span>
|
| 645 |
+
<button class="util-btn" id="wake-all-btn">Wake</button>
|
| 646 |
+
</div>
|
| 647 |
+
<div class="util-desc">Restart all spaces that are currently sleeping</div>
|
| 648 |
+
<div class="progress-container" id="wake-progress">
|
| 649 |
+
<div class="progress-bar">
|
| 650 |
+
<div class="progress-fill" id="wake-progress-fill"></div>
|
| 651 |
+
</div>
|
| 652 |
+
<div class="progress-text" id="wake-progress-text">Starting...</div>
|
| 653 |
+
<div class="progress-results" id="wake-results"></div>
|
| 654 |
+
</div>
|
| 655 |
+
</div>
|
| 656 |
+
</div>
|
| 657 |
+
</div>
|
| 658 |
+
|
| 659 |
<script>
|
| 660 |
document.querySelectorAll('.space-toggle').forEach(el => {
|
| 661 |
el.addEventListener('click', () => {
|
|
|
|
| 664 |
details.classList.toggle('open');
|
| 665 |
});
|
| 666 |
});
|
| 667 |
+
|
| 668 |
+
const modalOverlay = document.getElementById('modal-overlay');
|
| 669 |
+
const utilsBtn = document.getElementById('utils-btn');
|
| 670 |
+
const modalClose = document.getElementById('modal-close');
|
| 671 |
+
|
| 672 |
+
utilsBtn.addEventListener('click', () => {
|
| 673 |
+
modalOverlay.classList.add('open');
|
| 674 |
+
});
|
| 675 |
+
|
| 676 |
+
modalClose.addEventListener('click', () => {
|
| 677 |
+
modalOverlay.classList.remove('open');
|
| 678 |
+
});
|
| 679 |
+
|
| 680 |
+
modalOverlay.addEventListener('click', (e) => {
|
| 681 |
+
if (e.target === modalOverlay) {
|
| 682 |
+
modalOverlay.classList.remove('open');
|
| 683 |
+
}
|
| 684 |
+
});
|
| 685 |
+
|
| 686 |
+
const wakeAllBtn = document.getElementById('wake-all-btn');
|
| 687 |
+
const wakeProgress = document.getElementById('wake-progress');
|
| 688 |
+
const wakeProgressFill = document.getElementById('wake-progress-fill');
|
| 689 |
+
const wakeProgressText = document.getElementById('wake-progress-text');
|
| 690 |
+
const wakeResults = document.getElementById('wake-results');
|
| 691 |
+
|
| 692 |
+
wakeAllBtn.addEventListener('click', async () => {
|
| 693 |
+
wakeAllBtn.disabled = true;
|
| 694 |
+
wakeProgress.classList.add('active');
|
| 695 |
+
wakeProgressFill.style.width = '0%';
|
| 696 |
+
wakeProgressText.textContent = 'Waking spaces...';
|
| 697 |
+
wakeResults.innerHTML = '';
|
| 698 |
+
|
| 699 |
+
try {
|
| 700 |
+
const resp = await fetch('/api/wake-all', { method: 'POST' });
|
| 701 |
+
const data = await resp.json();
|
| 702 |
+
|
| 703 |
+
if (data.error) {
|
| 704 |
+
wakeProgressText.textContent = 'Error: ' + data.error;
|
| 705 |
+
wakeProgressFill.style.background = '#ef4444';
|
| 706 |
+
wakeProgressFill.style.width = '100%';
|
| 707 |
+
} else if (data.total === 0) {
|
| 708 |
+
wakeProgressText.textContent = 'No sleeping spaces found';
|
| 709 |
+
wakeProgressFill.style.width = '100%';
|
| 710 |
+
} else {
|
| 711 |
+
const succeeded = data.results.filter(r => r.success).length;
|
| 712 |
+
const failed = data.results.filter(r => !r.success).length;
|
| 713 |
+
wakeProgressFill.style.width = '100%';
|
| 714 |
+
wakeProgressText.textContent = `Done: ${succeeded} succeeded, ${failed} failed`;
|
| 715 |
+
|
| 716 |
+
data.results.forEach(r => {
|
| 717 |
+
const div = document.createElement('div');
|
| 718 |
+
div.className = 'progress-result ' + (r.success ? 'success' : 'error');
|
| 719 |
+
div.innerHTML = `<span>${r.id.split('/')[1]}</span><span>${r.success ? 'OK' : 'Failed'}</span>`;
|
| 720 |
+
wakeResults.appendChild(div);
|
| 721 |
+
});
|
| 722 |
+
}
|
| 723 |
+
} catch (err) {
|
| 724 |
+
wakeProgressText.textContent = 'Error: ' + err.message;
|
| 725 |
+
wakeProgressFill.style.background = '#ef4444';
|
| 726 |
+
wakeProgressFill.style.width = '100%';
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
wakeAllBtn.disabled = false;
|
| 730 |
+
});
|
| 731 |
</script>
|
| 732 |
</body>
|
| 733 |
</html>
|