AppManager: Show spinner during search
Search form doesn't throw an error when not on main page
Change-Id: I108c681101c3b03901205695ee3775fb18eaa900
diff --git a/core/installer/welcome/stat/app-manager.js b/core/installer/welcome/stat/app-manager.js
index 55357f3..9cafd83 100644
--- a/core/installer/welcome/stat/app-manager.js
+++ b/core/installer/welcome/stat/app-manager.js
@@ -9,46 +9,64 @@
document.addEventListener("DOMContentLoaded", function () {
let searchRequestCount = 0;
const page = document.documentElement;
- const headerHeight = parseFloat(getComputedStyle(page).getPropertyValue('--pico-header-height').replace("px", ""));
+ const headerHeight = parseFloat(getComputedStyle(page).getPropertyValue("--pico-header-height").replace("px", ""));
const nav = document.getElementById("menu");
const windowHeight = window.innerHeight - headerHeight;
nav.style.setProperty("--max-height", `${windowHeight}px`);
const menu = document.getElementById("menu-nav");
const menuHeight = parseFloat(getComputedStyle(document.getElementById('menu-nav')).height.replace("px", "")) + 15;
menu.style.setProperty("height", `${menuHeight}px`);
- const searchForm = document.getElementById('search-form');
- const searchInput = document.getElementById('search-input');
+ const searchForm = document.getElementById("search-form");
+ const searchInput = document.getElementById("search-input");
+ function startSearchAnimation() {
+ searchInput.classList.remove("search-icon");
+ searchInput.classList.add("search-progress-icon");
+ }
+ function stopSearchAnimation() {
+ searchInput.classList.remove("search-progress-icon");
+ searchInput.classList.add("search-icon");
+ }
function fetchAndUpdateAppList() {
searchRequestCount++;
const currentRequest = searchRequestCount;
const formData = new FormData(searchForm);
- const query = formData.get('query');
- const pageType = document.getElementById('page-type').value;
+ const query = formData.get("query");
+ const pageType = document.getElementById("page-type").value;
const url = `/${pageType}?query=${encodeURIComponent(query)}`;
+ startSearchAnimation();
fetch(url, {
- method: 'GET'
+ method: "GET"
})
.then(response => response.text())
.then(html => {
if (currentRequest !== searchRequestCount) {
return;
}
- const tempDiv = document.createElement('div');
+ const tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
- const newAppListHTML = tempDiv.querySelector('#app-list').innerHTML;
+ const newAppListHTML = tempDiv.querySelector("#app-list").innerHTML;
const appListContainer = document.getElementById("app-list");
appListContainer.innerHTML = newAppListHTML;
})
- .catch(error => console.error('Error fetching app list:', error));
+ .catch(error => {
+ console.error("Error fetching app list:", error);
+ })
+ .finally(() => {
+ stopSearchAnimation();
+ });
}
const delayedFetchAndUpdateAppList = delaySearch(fetchAndUpdateAppList, 300);
- searchForm.addEventListener('submit', (event) => {
- event.preventDefault();
- fetchAndUpdateAppList();
- });
- searchInput.addEventListener('input', () => {
- delayedFetchAndUpdateAppList();
- });
+ if (searchForm) {
+ searchForm.addEventListener("submit", (event) => {
+ event.preventDefault();
+ fetchAndUpdateAppList();
+ });
+ }
+ if (searchInput) {
+ searchInput.addEventListener("input", () => {
+ delayedFetchAndUpdateAppList();
+ });
+ }
});
let prevWindowHeight = window.innerHeight;
diff --git a/core/installer/welcome/stat/appmanager.css b/core/installer/welcome/stat/appmanager.css
index cde49ab..f8ee945 100644
--- a/core/installer/welcome/stat/appmanager.css
+++ b/core/installer/welcome/stat/appmanager.css
@@ -327,3 +327,11 @@
.primary {
color: #7f9f7f;
}
+
+.search-icon {
+ background-image: var(--pico-icon-search) !important;
+}
+
+.search-progress-icon {
+ background-image: var(--pico-icon-loading) !important;
+}