diff --git a/ts/admin.ts b/ts/admin.ts index b89996f..4dcf854 100644 --- a/ts/admin.ts +++ b/ts/admin.ts @@ -155,16 +155,15 @@ const tabs: { id: string; url: string; reloader: () => void; unloader?: () => vo let t: { id: string; url: string; reloader: () => void; unloader?: () => void } = { id: p.tabName, url: p.pagePath, - reloader: () => - p.reload(() => { - if (!navigated && isNavigatable(p)) { - if (p.isURL()) { - navigated = true; - p.navigate(); - } - } - if (isPageEventBindable(p)) p.bindPageEvents(); - }), + reloader: () => { + if (isPageEventBindable(p)) p.bindPageEvents(); + if (!navigated && isNavigatable(p) && p.isURL()) { + navigated = true; + p.navigate(); + } else { + p.reload(() => {}); + } + }, }; if (isPageEventBindable(p)) t.unloader = p.unbindPageEvents; tabs.push(t); diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts index 41c5bc8..a43868e 100644 --- a/ts/modules/accounts.ts +++ b/ts/modules/accounts.ts @@ -1106,6 +1106,7 @@ export class accountsList extends PaginatedList implements Navigatable, AsTab { itemsPerPage: 40, maxItemsLoadedForSearch: 200, appendNewItems: (resp: PaginatedDTO) => { + console.log("append"); for (let u of (resp as UsersDTO).users || []) { if (this.users.has(u.id)) { this.users.get(u.id).update(u); @@ -1121,6 +1122,7 @@ export class accountsList extends PaginatedList implements Navigatable, AsTab { ); }, replaceWithNewItems: (resp: PaginatedDTO) => { + console.log("replace"); let accountsOnDOM = new Map(); for (let id of this.users.keys()) { diff --git a/ts/modules/list.ts b/ts/modules/list.ts index ffd8a68..f463f97 100644 --- a/ts/modules/list.ts +++ b/ts/modules/list.ts @@ -359,6 +359,8 @@ export abstract class PaginatedList implements PageEventBindable { return bottomIdx; }; + private _loadLock: boolean = false; + private _loadQueue: (() => void)[] = []; private _load = ( itemLimit: number, page: number, @@ -367,7 +369,17 @@ export abstract class PaginatedList implements PageEventBindable { post?: (resp: PaginatedDTO) => void, failCallback?: (req: XMLHttpRequest) => void, ) => { + if (this._loadLock) { + console.debug("Queuing load, position:", this._loadQueue.length); + const now = Date.now(); + this._loadQueue.push(() => { + console.debug("Queued load running, appended at:", now); + this._load(itemLimit, page, appendFunc, pre, post, failCallback); + }); + return; + } this._lastLoad = Date.now(); + this._loadLock = true; let params = this._search.inServerSearch ? this._searchParams : this.defaultParams(); params.limit = itemLimit; params.page = page; @@ -397,9 +409,14 @@ export abstract class PaginatedList implements PageEventBindable { this._counter.loaded = this._search.ordering.length; + this._loadLock = false; + if (post) post(resp); if (this._c.pageLoadCallback) this._c.pageLoadCallback(req); + + const next = this._loadQueue.shift(); + if (next) next(); }, true, ); @@ -408,6 +425,7 @@ export abstract class PaginatedList implements PageEventBindable { // Removes all elements, and reloads the first page. public abstract reload: (callback?: (resp: PaginatedDTO) => void) => void; protected _reload = (callback?: (resp: PaginatedDTO) => void) => { + console.trace("reloading"); this.lastPage = false; this._counter.reset(); this._counter.getTotal( @@ -446,6 +464,7 @@ export abstract class PaginatedList implements PageEventBindable { // Loads the next page. If "loadAll", all pages will be loaded until the last is reached. public abstract loadMore: (loadAll?: boolean, callback?: (resp?: PaginatedDTO) => void) => void; protected _loadMore = (loadAll: boolean = false, callback?: (resp: PaginatedDTO) => void) => { + console.trace("loading more"); this._c.loadMoreButtons.forEach((v) => (v.disabled = true)); const timeout = setTimeout(() => { this._c.loadMoreButtons.forEach((v) => (v.disabled = false)); diff --git a/ts/modules/search.ts b/ts/modules/search.ts index f16aac1..eb076d7 100644 --- a/ts/modules/search.ts +++ b/ts/modules/search.ts @@ -552,6 +552,7 @@ export class Search implements Navigatable { return this._ascending; } + // FIXME: This is being called by navigate, and triggering a "load more" when we haven't loaded at all, and loading without a searchc when we have one! onSearchBoxChange = ( newItems: boolean = false, appendedItems: boolean = false, @@ -721,6 +722,15 @@ export class Search implements Navigatable { return req; }; + private _qps: URLSearchParams = new URLSearchParams(); + private _clearWithoutNavigate = false; + // clearQueryParam removes the "search" query parameter --without-- triggering a navigate call. + clearQueryParam = () => { + if (!this._qps.has("search")) return; + this._clearWithoutNavigate = true; + this.setQueryParam(""); + }; + // setQueryParam sets the ?search query param to the current searchbox content, // or value if given. If everything is set up correctly, this should trigger a search when it is // set to a new value. @@ -754,10 +764,13 @@ export class Search implements Navigatable { // navigate pulls the current "search" query param, puts it in the search box and searches it. navigate = (url?: string, then?: () => void) => { - (window as any).s = this; - const urlParams = new URLSearchParams(url || window.location.search); - const searchContent = urlParams.get("search") || ""; - console.log("navigate!, setting search box to ", searchContent); + this._qps = new URLSearchParams(url || window.location.search); + if (this._clearWithoutNavigate) { + this._clearWithoutNavigate = false; + return; + } + + const searchContent = this._qps.get("search") || ""; this._c.search.value = searchContent; this.onSearchBoxChange(); this.onServerSearch(then); @@ -772,6 +785,7 @@ export class Search implements Navigatable { this._c.search.oninput = () => { this.inServerSearch = false; + this.clearQueryParam(); this.onSearchBoxChange(); }; this._c.search.addEventListener("keyup", (ev: KeyboardEvent) => {