Update instances.html
This commit is contained in:
@@ -40,6 +40,15 @@
|
|||||||
background-color: #d1ecf1 !important;
|
background-color: #d1ecf1 !important;
|
||||||
border-color: #bee5eb !important;
|
border-color: #bee5eb !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge.bg-orange {
|
||||||
|
background-color: #fd7e14 !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.bg-orange:hover {
|
||||||
|
background-color: #e55a00 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -742,15 +751,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait a short moment to ensure the table is rendered
|
// Wait a short moment to ensure the table is rendered
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
// Check statuses on page load
|
// First fetch latest version information
|
||||||
|
await fetchLatestVersion();
|
||||||
|
|
||||||
|
// Then check statuses and fetch company names
|
||||||
checkAllInstanceStatuses();
|
checkAllInstanceStatuses();
|
||||||
|
|
||||||
// Fetch company names for all instances
|
|
||||||
fetchCompanyNames();
|
fetchCompanyNames();
|
||||||
|
|
||||||
// Fetch latest version information
|
|
||||||
fetchLatestVersion();
|
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
// Set up periodic status checks (every 30 seconds)
|
// Set up periodic status checks (every 30 seconds)
|
||||||
@@ -936,6 +943,49 @@ async function fetchInstanceStats(instanceUrl, instanceId, jwtToken) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to compare semantic versions and determine update type
|
||||||
|
function compareSemanticVersions(currentVersion, latestVersion) {
|
||||||
|
try {
|
||||||
|
// Parse versions into parts (handle cases like "1.0" or "1.0.0")
|
||||||
|
const parseVersion = (version) => {
|
||||||
|
const parts = version.split('.').map(part => {
|
||||||
|
const num = parseInt(part, 10);
|
||||||
|
return isNaN(num) ? 0 : num;
|
||||||
|
});
|
||||||
|
// Ensure we have at least 3 parts (major.minor.patch)
|
||||||
|
while (parts.length < 3) {
|
||||||
|
parts.push(0);
|
||||||
|
}
|
||||||
|
return parts.slice(0, 3); // Only take first 3 parts
|
||||||
|
};
|
||||||
|
|
||||||
|
const current = parseVersion(currentVersion);
|
||||||
|
const latest = parseVersion(latestVersion);
|
||||||
|
|
||||||
|
// Compare major version
|
||||||
|
if (current[0] < latest[0]) {
|
||||||
|
return 'major';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare minor version
|
||||||
|
if (current[1] < latest[1]) {
|
||||||
|
return 'minor';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare patch version
|
||||||
|
if (current[2] < latest[2]) {
|
||||||
|
return 'patch';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, current version is newer or equal
|
||||||
|
return 'up_to_date';
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error comparing semantic versions:', error);
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Function to fetch version information for an instance
|
// Function to fetch version information for an instance
|
||||||
async function fetchVersionInfo(instanceUrl, instanceId) {
|
async function fetchVersionInfo(instanceUrl, instanceId) {
|
||||||
const row = document.querySelector(`[data-instance-id="${instanceId}"]`).closest('tr');
|
const row = document.querySelector(`[data-instance-id="${instanceId}"]`).closest('tr');
|
||||||
@@ -984,7 +1034,23 @@ async function fetchVersionInfo(instanceUrl, instanceId) {
|
|||||||
if (appVersion !== 'unknown') {
|
if (appVersion !== 'unknown') {
|
||||||
// Get the latest version for comparison
|
// Get the latest version for comparison
|
||||||
const latestVersionBadge = document.getElementById('latestVersionBadge');
|
const latestVersionBadge = document.getElementById('latestVersionBadge');
|
||||||
const latestVersion = latestVersionBadge ? latestVersionBadge.textContent.replace('Loading...', '').trim() : null;
|
let latestVersion = latestVersionBadge ? latestVersionBadge.textContent.replace('Loading...', '').trim() : null;
|
||||||
|
|
||||||
|
// If latest version is not available yet, wait a bit and try again
|
||||||
|
if (!latestVersion || latestVersion === '') {
|
||||||
|
// Show loading state while waiting for latest version
|
||||||
|
versionCell.innerHTML = `
|
||||||
|
<span class="badge bg-secondary version-badge" data-bs-toggle="tooltip"
|
||||||
|
title="App Version: ${appVersion}<br>Git Commit: ${gitCommit}<br>Deployed: ${deployedAt}<br>Waiting for latest version...">
|
||||||
|
<i class="fas fa-spinner fa-spin me-1"></i>${appVersion.length > 8 ? appVersion.substring(0, 8) : appVersion}
|
||||||
|
</span>`;
|
||||||
|
|
||||||
|
// Wait a bit and retry the comparison
|
||||||
|
setTimeout(() => {
|
||||||
|
fetchVersionInfo(instanceUrl, instanceId);
|
||||||
|
}, 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine if this instance is up to date
|
// Determine if this instance is up to date
|
||||||
let badgeClass = 'bg-secondary';
|
let badgeClass = 'bg-secondary';
|
||||||
@@ -992,13 +1058,40 @@ async function fetchVersionInfo(instanceUrl, instanceId) {
|
|||||||
let tooltipText = `App Version: ${appVersion}<br>Git Commit: ${gitCommit}<br>Deployed: ${deployedAt}`;
|
let tooltipText = `App Version: ${appVersion}<br>Git Commit: ${gitCommit}<br>Deployed: ${deployedAt}`;
|
||||||
|
|
||||||
if (latestVersion && appVersion === latestVersion) {
|
if (latestVersion && appVersion === latestVersion) {
|
||||||
|
// Exact match - green
|
||||||
badgeClass = 'bg-success';
|
badgeClass = 'bg-success';
|
||||||
statusIcon = 'fas fa-check-circle';
|
statusIcon = 'fas fa-check-circle';
|
||||||
tooltipText += '<br><strong>✅ Up to date</strong>';
|
tooltipText += '<br><strong>✅ Up to date</strong>';
|
||||||
} else if (latestVersion && appVersion !== latestVersion) {
|
} else if (latestVersion && appVersion !== latestVersion) {
|
||||||
|
// Compare semantic versions
|
||||||
|
const versionComparison = compareSemanticVersions(appVersion, latestVersion);
|
||||||
|
|
||||||
|
switch (versionComparison) {
|
||||||
|
case 'patch':
|
||||||
|
// Only patch version different - yellow
|
||||||
|
badgeClass = 'bg-warning';
|
||||||
|
statusIcon = 'fas fa-exclamation-triangle';
|
||||||
|
tooltipText += `<br><strong>🟡 Patch update available (Latest: ${latestVersion})</strong>`;
|
||||||
|
break;
|
||||||
|
case 'minor':
|
||||||
|
// Minor version different - orange
|
||||||
|
badgeClass = 'bg-orange';
|
||||||
|
statusIcon = 'fas fa-exclamation-triangle';
|
||||||
|
tooltipText += `<br><strong>🟠 Minor update available (Latest: ${latestVersion})</strong>`;
|
||||||
|
break;
|
||||||
|
case 'major':
|
||||||
|
// Major version different - red
|
||||||
badgeClass = 'bg-danger';
|
badgeClass = 'bg-danger';
|
||||||
statusIcon = 'fas fa-exclamation-triangle';
|
statusIcon = 'fas fa-exclamation-triangle';
|
||||||
tooltipText += `<br><strong>⚠️ Outdated (Latest: ${latestVersion})</strong>`;
|
tooltipText += `<br><strong>🔴 Major update available (Latest: ${latestVersion})</strong>`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unknown format or comparison failed - red
|
||||||
|
badgeClass = 'bg-danger';
|
||||||
|
statusIcon = 'fas fa-exclamation-triangle';
|
||||||
|
tooltipText += `<br><strong>🔴 Outdated (Latest: ${latestVersion})</strong>`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
versionCell.innerHTML = `
|
versionCell.innerHTML = `
|
||||||
|
|||||||
Reference in New Issue
Block a user