diff --git a/pluginHolder/templates/pluginHolder/plugins.html b/pluginHolder/templates/pluginHolder/plugins.html index 9477ac53c..0c1aefb25 100644 --- a/pluginHolder/templates/pluginHolder/plugins.html +++ b/pluginHolder/templates/pluginHolder/plugins.html @@ -1035,6 +1035,38 @@ cursor: not-allowed; } + .upgrades-badge { + display: inline-block; + min-width: 20px; + height: 20px; + padding: 0 6px; + margin-left: 6px; + background: #f59e0b; + color: white; + border-radius: 10px; + font-size: 12px; + font-weight: 700; + line-height: 20px; + text-align: center; + } + + .upgrades-view-notice { + background: #eff6ff; + border: 1px solid #bfdbfe; + border-radius: 8px; + padding: 16px 20px; + margin-bottom: 20px; + display: flex; + align-items: flex-start; + gap: 12px; + } + + .upgrades-view-notice i { + color: #2563eb; + font-size: 20px; + margin-top: 2px; + } + .btn-link { padding: 6px 12px; background: var(--bg-secondary, #f8f9ff); @@ -1298,6 +1330,11 @@ {% trans "Table View" %} + + '; + html += '' + name + '' + newVer + '' + yourVer + '' + date + '' + actionHtml + ''; + }); + tbody.innerHTML = html; +} + +function loadPluginStore(forUpgradesView) { const storeLoading = document.getElementById('storeLoading'); const storeError = document.getElementById('storeError'); const storeErrorText = document.getElementById('storeErrorText'); const storeContent = document.getElementById('storeContent'); const storeTableBody = document.getElementById('storeTableBody'); + const upgradesLoading = document.getElementById('upgradesLoading'); if (!storeLoading || !storeError || !storeErrorText || !storeContent) return; storeLoading.style.display = 'block'; storeError.style.display = 'none'; storeContent.style.display = 'block'; + if (upgradesLoading) upgradesLoading.style.display = forUpgradesView ? 'block' : 'none'; fetch('/plugins/api/store/plugins/', { method: 'GET', @@ -1903,21 +2058,43 @@ function loadPluginStore() { }) .then(data => { storeLoading.style.display = 'none'; + const upgradesLoadingEl = document.getElementById('upgradesLoading'); + if (upgradesLoadingEl) upgradesLoadingEl.style.display = 'none'; if (data.success) { storePlugins = data.plugins; - displayStorePlugins(); + if (typeof updateUpgradesBadge === 'function') updateUpgradesBadge(); + const upgradesViewEl = document.getElementById('upgradesView'); + if (upgradesViewEl && upgradesViewEl.style.display === 'block' && typeof displayUpgradesAvailable === 'function') { + displayUpgradesAvailable(); + } else { + displayStorePlugins(); + } storeContent.style.display = 'block'; } else { storeErrorText.textContent = data.error || 'Failed to load plugins from store'; storeError.style.display = 'block'; + const upgradesError = document.getElementById('upgradesError'); + const upgradesErrorText = document.getElementById('upgradesErrorText'); + if (upgradesError && upgradesErrorText) { + upgradesErrorText.textContent = data.error || 'Failed to load plugin store'; + upgradesError.style.display = 'block'; + } } }) .catch(error => { storeLoading.style.display = 'none'; + const upgradesLoadingEl = document.getElementById('upgradesLoading'); + if (upgradesLoadingEl) upgradesLoadingEl.style.display = 'none'; storeErrorText.textContent = error.message || 'Error loading plugin store. Please refresh the page and try again.'; storeError.style.display = 'block'; storeContent.style.display = 'block'; + const upgradesError = document.getElementById('upgradesError'); + const upgradesErrorText = document.getElementById('upgradesErrorText'); + if (upgradesError && upgradesErrorText) { + upgradesErrorText.textContent = error.message || 'Error checking for upgrades.'; + upgradesError.style.display = 'block'; + } if (storeTableBody && storeTableBody.innerHTML === '') { storeTableBody.innerHTML = 'Unable to load plugins. Please check your connection and try again.'; } @@ -3158,12 +3335,13 @@ document.addEventListener('DOMContentLoaded', function() { // Check URL hash for view preference const hash = window.location.hash.substring(1); // Remove # - const validViews = ['grid', 'table', 'store']; + const validViews = ['grid', 'table', 'upgrades', 'store']; // Check if view elements exist before calling toggleView const gridView = document.getElementById('gridView'); const tableView = document.getElementById('tableView'); const storeView = document.getElementById('storeView'); + const upgradesViewEl = document.getElementById('upgradesView'); // Only proceed if all view elements exist (plugins are installed) if (gridView && tableView && storeView) {