mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-22 12:19:24 +00:00
get updates advanced (#4124)
# Description of Changes This pull request introduces a comprehensive update to the application's update notification and modal system, enhancing both the backend logic and the user interface for update alerts. The changes include a new modal dialog for update details, improved internationalization (i18n) support, dynamic fetching of update information, and context-aware download links. These improvements make update notifications clearer, more informative, and tailored to the user's installation type. **Key changes:** **1. Update Notification and Modal System Overhaul** - Added a new modal dialog (`showUpdateModal`) that displays detailed update information, including current, latest, and latest stable versions, update priority, breaking changes, migration guides, and a list of available updates. The modal dynamically fetches and displays full update details and adapts to dark mode. ([[app/core/src/main/resources/static/js/githubVersion.jsR206-R387](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aR206-R387)]) - Enhanced the update button logic to reflect update priority visually (e.g., urgent/normal/minor), store summary data, and trigger the modal on click. ([[app/core/src/main/resources/static/js/githubVersion.jsL74-R190](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aL74-R190)]) - Improved the update check process to use a new summary API endpoint and handle missing or failed update data gracefully. [[1]](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aL19-R108)], [[2]](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aL74-R190)]) **2. Context-Aware Download Links** - Introduced `getDownloadUrl()` to generate download links based on the user's machine type and security configuration, ensuring only relevant installers or jars are offered. ([[app/core/src/main/resources/static/js/githubVersion.jsL19-R108](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aL19-R108)]) **3. Internationalization (i18n) Enhancements** - Added new i18n keys for all update-related modal and notification strings in `messages_en_GB.properties`. ([[app/core/src/main/resources/messages_en_GB.propertiesR369-R400](diffhunk://#diff-ee1c6999a33498cfa3abba4a384e73a8b8269856899438de80560c965079a9fdR369-R400)]) - Injected all necessary i18n constants into the frontend via `navbar.html` for use in the modal and notifications. ([[app/core/src/main/resources/templates/fragments/navbar.htmlR14-R51](diffhunk://#diff-e7ef383033ea52a00c96e71d5d2c1ff08829078fa5c84c8e48e1bf8f48861ec6R14-R51)]) **4. General UI and Code Improvements** - Ensured update button styling is reset before applying new styles and improved accessibility by hiding the settings modal when the update modal is shown. [[1]](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aR138)], [[2]](diffhunk://#diff-5a6376050581cc6f1fb0b6266af4d8a3db1332879459afd3a073b274b5ab637aR206-R387)]) These changes collectively provide a more robust, user-friendly, and maintainable update notification experience. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Reece Browne <reecebrowne1995@gmail.com> Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Co-authored-by: a <a>
This commit is contained in:
parent
65e894870c
commit
774b500159
@ -366,6 +366,38 @@ navbar.sections.popular=Popular
|
|||||||
settings.title=Settings
|
settings.title=Settings
|
||||||
settings.update=Update available
|
settings.update=Update available
|
||||||
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available.
|
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available.
|
||||||
|
|
||||||
|
# Update modal and notification strings
|
||||||
|
update.urgentUpdateAvailable=🚨 Update Available
|
||||||
|
update.updateAvailable=Update Available
|
||||||
|
update.modalTitle=Update Available
|
||||||
|
update.current=Current
|
||||||
|
update.latest=Latest
|
||||||
|
update.latestStable=Latest Stable
|
||||||
|
update.priority=Priority
|
||||||
|
update.recommendedAction=Recommended Action
|
||||||
|
update.breakingChangesDetected=⚠️ Breaking Changes Detected
|
||||||
|
update.breakingChangesMessage=This update contains breaking changes. Please review the migration guides below.
|
||||||
|
update.migrationGuides=Migration Guides:
|
||||||
|
update.viewGuide=View Guide
|
||||||
|
update.loadingDetailedInfo=Loading detailed version information...
|
||||||
|
update.close=Close
|
||||||
|
update.viewAllReleases=View All Releases
|
||||||
|
update.downloadLatest=Download Latest
|
||||||
|
update.availableUpdates=Available Updates:
|
||||||
|
update.unableToLoadDetails=Unable to load detailed version information.
|
||||||
|
update.version=Version
|
||||||
|
|
||||||
|
# Update priority levels
|
||||||
|
update.priority.urgent=URGENT
|
||||||
|
update.priority.normal=NORMAL
|
||||||
|
update.priority.minor=MINOR
|
||||||
|
update.priority.low=LOW
|
||||||
|
|
||||||
|
# Breaking changes text
|
||||||
|
update.breakingChanges=Breaking Changes:
|
||||||
|
update.breakingChangesDefault=This version contains breaking changes
|
||||||
|
update.migrationGuide=Migration Guide
|
||||||
settings.appVersion=App Version:
|
settings.appVersion=App Version:
|
||||||
settings.downloadOption.title=Choose download option (For single file non zip downloads):
|
settings.downloadOption.title=Choose download option (For single file non zip downloads):
|
||||||
settings.downloadOption.1=Open in same window
|
settings.downloadOption.1=Open in same window
|
||||||
|
@ -16,21 +16,96 @@ function compareVersions(version1, version2) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getLatestReleaseVersion() {
|
function getDownloadUrl() {
|
||||||
const url = "https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest";
|
// Only show download for non-Docker installations
|
||||||
|
if (machineType === 'Docker' || machineType === 'Kubernetes') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseUrl = 'https://files.stirlingpdf.com/';
|
||||||
|
|
||||||
|
// Determine file based on machine type and security
|
||||||
|
if (machineType === 'Server-jar') {
|
||||||
|
return baseUrl + (activeSecurity ? 'Stirling-PDF-with-login.jar' : 'Stirling-PDF.jar');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client installations
|
||||||
|
if (machineType.startsWith('Client-')) {
|
||||||
|
const os = machineType.replace('Client-', ''); // win, mac, unix
|
||||||
|
const type = activeSecurity ? '-server-security' : '-server';
|
||||||
|
|
||||||
|
if (os === 'unix') {
|
||||||
|
return baseUrl + os + type + '.jar';
|
||||||
|
} else if (os === 'win') {
|
||||||
|
return baseUrl + os + '-installer.exe';
|
||||||
|
} else if (os === 'mac') {
|
||||||
|
return baseUrl + os + '-installer.dmg';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to get translated priority text
|
||||||
|
function getTranslatedPriority(priority) {
|
||||||
|
switch(priority?.toLowerCase()) {
|
||||||
|
case 'urgent': return updatePriorityUrgent;
|
||||||
|
case 'normal': return updatePriorityNormal;
|
||||||
|
case 'minor': return updatePriorityMinor;
|
||||||
|
case 'low': return updatePriorityLow;
|
||||||
|
default: return priority?.toUpperCase() || 'NORMAL';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getUpdateSummary() {
|
||||||
|
// Map Java License enum to API types
|
||||||
|
let type = 'normal';
|
||||||
|
if (licenseType === 'PRO') {
|
||||||
|
type = 'pro';
|
||||||
|
} else if (licenseType === 'ENTERPRISE') {
|
||||||
|
type = 'enterprise';
|
||||||
|
}
|
||||||
|
const url = `https://supabase.stirling.com/functions/v1/updates?from=${currentVersion}&type=${type}&login=${activeSecurity}&summary=true`;
|
||||||
|
console.log("Fetching update summary from:", url);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
console.log("Response status:", response.status);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data.tag_name ? data.tag_name.substring(1) : "";
|
return data;
|
||||||
} else {
|
} else {
|
||||||
// If the status is not 200, try to get the version from build.gradle
|
console.error("Failed to fetch update summary from Supabase:", response.status);
|
||||||
return await getCurrentVersionFromBypass();
|
return null;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch latest version from GitHub:", error);
|
console.error("Failed to fetch update summary from Supabase:", error);
|
||||||
// If an error occurs, try to get the version from build.gradle
|
return null;
|
||||||
return await getCurrentVersionFromBypass();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFullUpdateInfo() {
|
||||||
|
// Map Java License enum to API types
|
||||||
|
let type = 'normal';
|
||||||
|
if (licenseType === 'PRO') {
|
||||||
|
type = 'pro';
|
||||||
|
} else if (licenseType === 'ENTERPRISE') {
|
||||||
|
type = 'enterprise';
|
||||||
|
}
|
||||||
|
const url = `https://supabase.stirling.com/functions/v1/updates?from=${currentVersion}&type=${type}&login=${activeSecurity}&summary=false`;
|
||||||
|
console.log("Fetching full update info from:", url);
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
console.log("Full update response status:", response.status);
|
||||||
|
if (response.status === 200) {
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
console.error("Failed to fetch full update info from Supabase:", response.status);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch full update info from Supabase:", error);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +135,7 @@ async function checkForUpdate() {
|
|||||||
var updateLinkLegacy = document.getElementById("update-link-legacy") || null;
|
var updateLinkLegacy = document.getElementById("update-link-legacy") || null;
|
||||||
if (updateBtn !== null) {
|
if (updateBtn !== null) {
|
||||||
updateBtn.style.display = "none";
|
updateBtn.style.display = "none";
|
||||||
|
updateBtn.classList.remove("btn-danger", "btn-warning", "btn-outline-primary");
|
||||||
}
|
}
|
||||||
if (updateLink !== null) {
|
if (updateLink !== null) {
|
||||||
updateLink.style.display = "none";
|
updateLink.style.display = "none";
|
||||||
@ -71,19 +147,47 @@ async function checkForUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const latestVersion = await getLatestReleaseVersion();
|
const updateSummary = await getUpdateSummary();
|
||||||
console.log("latestVersion=" + latestVersion);
|
if (!updateSummary) {
|
||||||
|
console.log("No update summary available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("updateSummary=", updateSummary);
|
||||||
console.log("currentVersion=" + currentVersion);
|
console.log("currentVersion=" + currentVersion);
|
||||||
console.log("compareVersions(latestVersion, currentVersion) > 0)=" + compareVersions(latestVersion, currentVersion));
|
console.log("latestVersion=" + updateSummary.latest_version);
|
||||||
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
||||||
|
if (updateSummary.latest_version && compareVersions(updateSummary.latest_version, currentVersion) > 0) {
|
||||||
|
const priority = updateSummary.max_priority || 'normal';
|
||||||
|
|
||||||
if (updateBtn != null) {
|
if (updateBtn != null) {
|
||||||
document.getElementById("update-btn").style.display = "block";
|
// Style button based on priority
|
||||||
|
if (priority === 'urgent') {
|
||||||
|
updateBtn.classList.add("btn-danger");
|
||||||
|
updateBtn.innerHTML = urgentUpdateAvailable;
|
||||||
|
} else if (priority === 'normal') {
|
||||||
|
updateBtn.classList.add("btn-warning");
|
||||||
|
updateBtn.innerHTML = updateAvailableText;
|
||||||
|
} else {
|
||||||
|
updateBtn.classList.add("btn-outline-primary");
|
||||||
|
updateBtn.innerHTML = updateAvailableText;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store summary for initial display
|
||||||
|
updateBtn.setAttribute('data-update-summary', JSON.stringify(updateSummary));
|
||||||
|
updateBtn.style.display = "block";
|
||||||
|
|
||||||
|
// Add click handler for update details modal
|
||||||
|
updateBtn.onclick = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
showUpdateModal();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (updateLink !== null) {
|
if (updateLink !== null) {
|
||||||
document.getElementById("update-link").style.display = "flex";
|
document.getElementById("update-link").style.display = "flex";
|
||||||
}
|
}
|
||||||
if (updateLinkLegacy !== null) {
|
if (updateLinkLegacy !== null) {
|
||||||
document.getElementById("app-update").innerHTML = updateAvailable.replace("{0}", '<b>' + currentVersion + '</b>').replace("{1}", '<b>' + latestVersion + '</b>');
|
document.getElementById("app-update").innerHTML = updateAvailable.replace("{0}", '<b>' + currentVersion + '</b>').replace("{1}", '<b>' + updateSummary.latest_version + '</b>');
|
||||||
if (updateLinkLegacy.classList.contains("visually-hidden")) {
|
if (updateLinkLegacy.classList.contains("visually-hidden")) {
|
||||||
updateLinkLegacy.classList.remove("visually-hidden");
|
updateLinkLegacy.classList.remove("visually-hidden");
|
||||||
}
|
}
|
||||||
@ -99,6 +203,188 @@ async function checkForUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function showUpdateModal() {
|
||||||
|
// Close settings modal if open
|
||||||
|
const settingsModal = bootstrap.Modal.getInstance(document.getElementById('settingsModal'));
|
||||||
|
if (settingsModal) {
|
||||||
|
settingsModal.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get summary data from button
|
||||||
|
const updateBtn = document.getElementById("update-btn");
|
||||||
|
const summaryData = JSON.parse(updateBtn.getAttribute('data-update-summary'));
|
||||||
|
|
||||||
|
// Utility function to escape HTML special characters
|
||||||
|
function escapeHtml(str) {
|
||||||
|
if (typeof str !== 'string') return str;
|
||||||
|
return str
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''')
|
||||||
|
.replace(/\//g, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create initial modal with loading state
|
||||||
|
const initialModalHtml = `
|
||||||
|
<div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document" style="max-height: 80vh;">
|
||||||
|
<div class="modal-content" style="max-height: 80vh;">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="updateModalLabel">${updateModalTitle}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
||||||
|
<span class="material-symbols-rounded">close</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="updateModalBody" style="max-height: 60vh; overflow-y: auto;">
|
||||||
|
<div class="update-summary mb-4">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="${summaryData.latest_stable_version ? 'col-4' : 'col-6'} text-center">
|
||||||
|
<small class="text-muted">${updateCurrent}</small><br>
|
||||||
|
<strong>${escapeHtml(currentVersion)}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="${summaryData.latest_stable_version ? 'col-4' : 'col-6'} text-center">
|
||||||
|
<small class="text-muted">${updateLatest}</small><br>
|
||||||
|
<strong class="text-primary">${escapeHtml(summaryData.latest_version)}</strong>
|
||||||
|
</div>
|
||||||
|
${summaryData.latest_stable_version ? `
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<small class="text-muted">${updateLatestStable}</small><br>
|
||||||
|
<strong class="text-success">${escapeHtml(summaryData.latest_stable_version)}</strong>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
<div class="alert ${summaryData.max_priority === 'urgent' ? 'alert-danger' : 'alert-warning'}" role="alert">
|
||||||
|
<strong>${updatePriority}:</strong> ${getTranslatedPriority(summaryData.max_priority)}
|
||||||
|
${summaryData.recommended_action ? `<br><strong>${updateRecommendedAction}:</strong> ${escapeHtml(summaryData.recommended_action)}` : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${summaryData.any_breaking ? `
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<h6><strong>${updateBreakingChangesDetected}</strong></h6>
|
||||||
|
<p>${updateBreakingChangesMessage}</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
|
${summaryData.migration_guides && summaryData.migration_guides.length > 0 ? `
|
||||||
|
<div class="migration-guides mb-4">
|
||||||
|
<h6>${updateMigrationGuides}</h6>
|
||||||
|
<ul class="list-group">
|
||||||
|
${summaryData.migration_guides.map(guide => `
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<strong>${updateVersion} ${escapeHtml(guide.version)}:</strong> ${escapeHtml(guide.notes)}
|
||||||
|
</div>
|
||||||
|
<a href="${escapeHtml(guide.url)}" target="_blank" class="btn btn-sm btn-outline-primary">${updateViewGuide}</a>
|
||||||
|
</li>
|
||||||
|
`).join('')}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="spinner-border text-primary" role="status" id="loadingSpinner">
|
||||||
|
<span class="visually-hidden">${updateLoadingDetailedInfo}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2">${updateLoadingDetailedInfo}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">${updateClose}</button>
|
||||||
|
<a href="https://github.com/Stirling-Tools/Stirling-PDF/releases" target="_blank" class="btn btn-outline-primary">${updateViewAllReleases}</a>
|
||||||
|
${getDownloadUrl() ? `<a href="${escapeHtml(getDownloadUrl())}" class="btn btn-success" target="_blank">${updateDownloadLatest}</a>` : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Remove existing modal if present
|
||||||
|
const existingModal = document.getElementById('updateModal');
|
||||||
|
if (existingModal) {
|
||||||
|
existingModal.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add modal to body
|
||||||
|
document.body.insertAdjacentHTML('beforeend', initialModalHtml);
|
||||||
|
|
||||||
|
// Show modal
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('updateModal'));
|
||||||
|
modal.show();
|
||||||
|
|
||||||
|
// Fetch full update info
|
||||||
|
const fullUpdateInfo = await getFullUpdateInfo();
|
||||||
|
|
||||||
|
// Update modal with full information
|
||||||
|
const modalBody = document.getElementById('updateModalBody');
|
||||||
|
if (fullUpdateInfo && fullUpdateInfo.new_versions) {
|
||||||
|
const storedMode = localStorage.getItem("dark-mode");
|
||||||
|
const isDarkMode = storedMode === "on" ||
|
||||||
|
(storedMode === null && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||||
|
const darkClasses = isDarkMode ? {
|
||||||
|
accordionItem: 'bg-dark border-secondary text-light',
|
||||||
|
accordionButton: 'bg-dark text-light border-secondary',
|
||||||
|
accordionBody: 'bg-dark text-light'
|
||||||
|
} : {
|
||||||
|
accordionItem: '',
|
||||||
|
accordionButton: '',
|
||||||
|
accordionBody: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const detailedVersionsHtml = `
|
||||||
|
<div class="detailed-versions mt-4">
|
||||||
|
<h6>${updateAvailableUpdates}</h6>
|
||||||
|
<div class="accordion" id="versionsAccordion">
|
||||||
|
${fullUpdateInfo.new_versions.map((version, index) => `
|
||||||
|
<div class="accordion-item" style="border-color: var(--md-sys-color-outline);">
|
||||||
|
<h2 class="accordion-header" id="heading${index}">
|
||||||
|
<button class="accordion-button ${index === 0 ? '' : 'collapsed'}" style="color: var(--md-sys-color-on-surface); background-color:
|
||||||
|
var(--md-sys-color-surface);" type="button" data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#collapse${index}" aria-expanded="${index === 0 ? 'true' : 'false'}" aria-controls="collapse${index}">
|
||||||
|
<div class="d-flex justify-content-between w-100 me-3">
|
||||||
|
<span><strong>${updateVersion} ${version.version}</strong></span>
|
||||||
|
<span class="badge ${version.priority === 'urgent' ? 'bg-danger' : version.priority === 'normal' ? 'bg-warning' : 'bg-secondary'}">${getTranslatedPriority(version.priority)}</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse${index}" class="accordion-collapse collapse ${index === 0 ? 'show' : ''}"
|
||||||
|
aria-labelledby="heading${index}" data-bs-parent="#versionsAccordion">
|
||||||
|
<div class="accordion-body" style="color: var(--md-sys-color-on-surface); background-color:
|
||||||
|
var(--md-sys-color-surface-bright);">
|
||||||
|
<h6>${version.announcement.title}</h6>
|
||||||
|
<p>${version.announcement.message}</p>
|
||||||
|
${version.compatibility.breaking_changes ? `
|
||||||
|
<div class="alert alert-warning alert-sm" role="alert">
|
||||||
|
<small><strong>⚠️ ${updateBreakingChanges}</strong> ${version.compatibility.breaking_description || updateBreakingChangesDefault}</small>
|
||||||
|
${version.compatibility.migration_guide_url ? `<br><a href="${version.compatibility.migration_guide_url}" target="_blank" class="btn btn-sm btn-outline-warning mt-1">${updateMigrationGuide}</a>` : ''}
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Remove loading spinner and add detailed info
|
||||||
|
const spinner = document.getElementById('loadingSpinner');
|
||||||
|
if (spinner) {
|
||||||
|
spinner.parentElement.remove();
|
||||||
|
}
|
||||||
|
modalBody.insertAdjacentHTML('beforeend', detailedVersionsHtml);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Remove loading spinner if failed to load
|
||||||
|
const spinner = document.getElementById('loadingSpinner');
|
||||||
|
if (spinner) {
|
||||||
|
spinner.parentElement.innerHTML = `<p class="text-muted">${updateUnableToLoadDetails}</p>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", (event) => {
|
document.addEventListener("DOMContentLoaded", (event) => {
|
||||||
checkForUpdate();
|
checkForUpdate();
|
||||||
});
|
});
|
||||||
|
@ -11,9 +11,44 @@
|
|||||||
</script>
|
</script>
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
const currentVersion = /*[[${@appVersion}]]*/ '';
|
const currentVersion = /*[[${@appVersion}]]*/ '';
|
||||||
|
const licenseType = /*[[${@license}]]*/ '';
|
||||||
|
const machineType = /*[[${@machineType}]]*/ '';
|
||||||
|
const activeSecurity = /*[[${@activeSecurity}]]*/ false;
|
||||||
const noFavourites = /*[[#{noFavourites}]]*/ '';
|
const noFavourites = /*[[#{noFavourites}]]*/ '';
|
||||||
console.log(noFavourites);
|
console.log(noFavourites);
|
||||||
const updateAvailable = /*[[#{settings.updateAvailable}]]*/ '';
|
const updateAvailable = /*[[#{settings.updateAvailable}]]*/ '';
|
||||||
|
|
||||||
|
// Update notification i18n constants
|
||||||
|
const urgentUpdateAvailable = /*[[#{update.urgentUpdateAvailable}]]*/ '🚨 Update Available';
|
||||||
|
const updateAvailableText = /*[[#{update.updateAvailable}]]*/ 'Update Available';
|
||||||
|
const updateModalTitle = /*[[#{update.modalTitle}]]*/ 'Update Available';
|
||||||
|
const updateCurrent = /*[[#{update.current}]]*/ 'Current';
|
||||||
|
const updateLatest = /*[[#{update.latest}]]*/ 'Latest';
|
||||||
|
const updateLatestStable = /*[[#{update.latestStable}]]*/ 'Latest Stable';
|
||||||
|
const updatePriority = /*[[#{update.priority}]]*/ 'Priority';
|
||||||
|
const updateRecommendedAction = /*[[#{update.recommendedAction}]]*/ 'Recommended Action';
|
||||||
|
const updateBreakingChangesDetected = /*[[#{update.breakingChangesDetected}]]*/ '⚠️ Breaking Changes Detected';
|
||||||
|
const updateBreakingChangesMessage = /*[[#{update.breakingChangesMessage}]]*/ 'This update contains breaking changes. Please review the migration guides below.';
|
||||||
|
const updateMigrationGuides = /*[[#{update.migrationGuides}]]*/ 'Migration Guides:';
|
||||||
|
const updateViewGuide = /*[[#{update.viewGuide}]]*/ 'View Guide';
|
||||||
|
const updateLoadingDetailedInfo = /*[[#{update.loadingDetailedInfo}]]*/ 'Loading detailed version information...';
|
||||||
|
const updateClose = /*[[#{update.close}]]*/ 'Close';
|
||||||
|
const updateViewAllReleases = /*[[#{update.viewAllReleases}]]*/ 'View All Releases';
|
||||||
|
const updateDownloadLatest = /*[[#{update.downloadLatest}]]*/ 'Download Latest';
|
||||||
|
const updateAvailableUpdates = /*[[#{update.availableUpdates}]]*/ 'Available Updates:';
|
||||||
|
const updateUnableToLoadDetails = /*[[#{update.unableToLoadDetails}]]*/ 'Unable to load detailed version information.';
|
||||||
|
const updateVersion = /*[[#{update.version}]]*/ 'Version';
|
||||||
|
|
||||||
|
// Update priority levels
|
||||||
|
const updatePriorityUrgent = /*[[#{update.priority.urgent}]]*/ 'URGENT';
|
||||||
|
const updatePriorityNormal = /*[[#{update.priority.normal}]]*/ 'NORMAL';
|
||||||
|
const updatePriorityMinor = /*[[#{update.priority.minor}]]*/ 'MINOR';
|
||||||
|
const updatePriorityLow = /*[[#{update.priority.low}]]*/ 'LOW';
|
||||||
|
|
||||||
|
// Breaking changes text
|
||||||
|
const updateBreakingChanges = /*[[#{update.breakingChanges}]]*/ 'Breaking Changes:';
|
||||||
|
const updateBreakingChangesDefault = /*[[#{update.breakingChangesDefault}]]*/ 'This version contains breaking changes';
|
||||||
|
const updateMigrationGuide = /*[[#{update.migrationGuide}]]*/ 'Migration Guide';
|
||||||
</script>
|
</script>
|
||||||
<script th:src="@{'/js/homecard.js'}"></script>
|
<script th:src="@{'/js/homecard.js'}"></script>
|
||||||
<script th:src="@{'/js/githubVersion.js'}"></script>
|
<script th:src="@{'/js/githubVersion.js'}"></script>
|
||||||
|
@ -58,7 +58,7 @@ repositories {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = 'stirling.software'
|
group = 'stirling.software'
|
||||||
version = '1.1.1'
|
version = '1.1.2'
|
||||||
|
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
exclude group: 'commons-logging', module: 'commons-logging'
|
exclude group: 'commons-logging', module: 'commons-logging'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user