From cd858b2d64f361bf9d021c6f9cccf4be1425f7ea Mon Sep 17 00:00:00 2001 From: Alan Guo Xiang Tan Date: Thu, 8 Jan 2026 12:34:04 +0800 Subject: [PATCH] UX: Add loading spinner when loading more categories in sidebar modal (#37001) - Add ConditionalLoadingSpinner at bottom of modal for "load more" state - Replace loadingSpinner helper with ConditionalLoadingSpinner for initial load --- .../edit-navigation-menu/categories-modal.gjs | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/frontend/discourse/app/components/sidebar/edit-navigation-menu/categories-modal.gjs b/frontend/discourse/app/components/sidebar/edit-navigation-menu/categories-modal.gjs index 8ab1af4d9a5..0c98d4fb4c8 100644 --- a/frontend/discourse/app/components/sidebar/edit-navigation-menu/categories-modal.gjs +++ b/frontend/discourse/app/components/sidebar/edit-navigation-menu/categories-modal.gjs @@ -6,12 +6,12 @@ import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import { service } from "@ember/service"; import { TrackedSet } from "@ember-compat/tracked-built-ins"; +import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner"; import EditNavigationMenuModal from "discourse/components/sidebar/edit-navigation-menu/modal"; import borderColor from "discourse/helpers/border-color"; import categoryBadge from "discourse/helpers/category-badge"; import concatClass from "discourse/helpers/concat-class"; import dirSpan from "discourse/helpers/dir-span"; -import loadingSpinner from "discourse/helpers/loading-spinner"; import { popupAjaxError } from "discourse/lib/ajax-error"; import discourseDebounce from "discourse/lib/debounce"; import { INPUT_DELAY } from "discourse/lib/environment"; @@ -27,6 +27,7 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component @tracked initialLoad = true; @tracked filtered = false; @tracked fetchedCategoriesGroupings = []; + @tracked loadingMore = false; @tracked selectedCategoryIds = new TrackedSet([ ...this.currentUser.sidebar_category_ids, @@ -76,8 +77,13 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component @action didInsert(element) { - this.observer.disconnect(); - this.observer.observe(element); + const categoryId = parseInt(element.dataset.categoryId, 10); + const lastCategoryId = this.fetchedCategories.at(-1)?.id; + + if (categoryId === lastCategoryId) { + this.observer.disconnect(); + this.observer.observe(element); + } } searchOpts() { @@ -111,6 +117,7 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component ) { // The shown categories are up-to-date, so we can do elaboration if (this.loadAnotherPage && !this.lastPage) { + this.loadingMore = true; const requestedPage = this.loadedPage + 1; const opts = { page: requestedPage, ...this.searchOpts() }; @@ -127,6 +134,7 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component this.loadAnotherPage = false; this.loadedPage = requestedPage; + this.loadingMore = false; } } else { // The shown categories are stale, refresh everything @@ -256,17 +264,13 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component @closeModal={{@closeModal}} class="sidebar__edit-navigation-menu__categories-modal" > -
- {{#if this.initialLoad}} - - {{else}} + + {{#each this.fetchedCategoriesGroupings as |categories|}}
{{/each}} - {{/if}} - + + + + }