Add popstate handling
authorMarcel Werk <burntime@woltlab.com>
Fri, 27 Sep 2024 09:38:39 +0000 (11:38 +0200)
committerMarcel Werk <burntime@woltlab.com>
Tue, 12 Nov 2024 11:51:53 +0000 (12:51 +0100)
ts/WoltLabSuite/Core/Component/GridView.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Component/GridView.js

index 40254fb7ad793a13d5291f298f8da5716ab7aa50..75e9fb3e40aa920cca0c774e0db307a178daa8d7 100644 (file)
@@ -11,6 +11,8 @@ export class GridView {
   #pageNo: number;
   #sortField: string;
   #sortOrder: string;
+  #defaultSortField: string;
+  #defaultSortOrder: string;
 
   constructor(
     gridId: string,
@@ -27,11 +29,17 @@ export class GridView {
     this.#pageNo = pageNo;
     this.#baseUrl = baseUrl;
     this.#sortField = sortField;
+    this.#defaultSortField = sortField;
     this.#sortOrder = sortOrder;
+    this.#defaultSortOrder = sortOrder;
 
     this.#initPagination();
     this.#initSorting();
     this.#initActions();
+
+    window.addEventListener("popstate", () => {
+      this.#handlePopState();
+    });
   }
 
   #initPagination(): void {
@@ -81,18 +89,20 @@ export class GridView {
     });
   }
 
-  #switchPage(pageNo: number): void {
+  #switchPage(pageNo: number, updateQueryString: boolean = true): void {
     this.#topPagination.page = pageNo;
     this.#bottomPagination.page = pageNo;
     this.#pageNo = pageNo;
 
-    void this.#loadRows();
+    void this.#loadRows(updateQueryString);
   }
 
-  async #loadRows(): Promise<void> {
+  async #loadRows(updateQueryString: boolean = true): Promise<void> {
     const response = await getRows(this.#gridClassName, this.#pageNo, this.#sortField, this.#sortOrder);
     DomUtil.setInnerHtml(this.#table.querySelector("tbody")!, response.unwrap().template);
-    this.#updateQueryString();
+    if (updateQueryString) {
+      this.#updateQueryString();
+    }
     this.#initActions();
   }
 
@@ -137,4 +147,28 @@ export class GridView {
       });
     });
   }
+
+  #handlePopState(): void {
+    let pageNo = 1;
+    this.#sortField = this.#defaultSortField;
+    this.#sortOrder = this.#defaultSortOrder;
+
+    const url = new URL(window.location.href);
+    url.searchParams.forEach((value, key) => {
+      if (key === "pageNo") {
+        pageNo = parseInt(value, 10);
+        return;
+      }
+
+      if (key === "sortField") {
+        this.#sortField = value;
+      }
+
+      if (key === "sortOrder") {
+        this.#sortOrder = value;
+      }
+    });
+
+    this.#switchPage(pageNo, false);
+  }
 }
index e65b94b4b0128dced5018a0448f2b44c536a5cef..d65ff5e1f0a91ac40f2ed00c4971a2b9c2a3a3cf 100644 (file)
@@ -13,6 +13,8 @@ define(["require", "exports", "tslib", "../Api/GridViews/GetRows", "../Dom/Util"
         #pageNo;
         #sortField;
         #sortOrder;
+        #defaultSortField;
+        #defaultSortOrder;
         constructor(gridId, gridClassName, pageNo, baseUrl = "", sortField = "", sortOrder = "ASC") {
             this.#gridClassName = gridClassName;
             this.#table = document.getElementById(`${gridId}_table`);
@@ -21,10 +23,15 @@ define(["require", "exports", "tslib", "../Api/GridViews/GetRows", "../Dom/Util"
             this.#pageNo = pageNo;
             this.#baseUrl = baseUrl;
             this.#sortField = sortField;
+            this.#defaultSortField = sortField;
             this.#sortOrder = sortOrder;
+            this.#defaultSortOrder = sortOrder;
             this.#initPagination();
             this.#initSorting();
             this.#initActions();
+            window.addEventListener("popstate", () => {
+                this.#handlePopState();
+            });
         }
         #initPagination() {
             this.#topPagination.addEventListener("switchPage", (event) => {
@@ -66,16 +73,18 @@ define(["require", "exports", "tslib", "../Api/GridViews/GetRows", "../Dom/Util"
                 }
             });
         }
-        #switchPage(pageNo) {
+        #switchPage(pageNo, updateQueryString = true) {
             this.#topPagination.page = pageNo;
             this.#bottomPagination.page = pageNo;
             this.#pageNo = pageNo;
-            void this.#loadRows();
+            void this.#loadRows(updateQueryString);
         }
-        async #loadRows() {
+        async #loadRows(updateQueryString = true) {
             const response = await (0, GetRows_1.getRows)(this.#gridClassName, this.#pageNo, this.#sortField, this.#sortOrder);
             Util_1.default.setInnerHtml(this.#table.querySelector("tbody"), response.unwrap().template);
-            this.#updateQueryString();
+            if (updateQueryString) {
+                this.#updateQueryString();
+            }
             this.#initActions();
         }
         #updateQueryString() {
@@ -112,6 +121,25 @@ define(["require", "exports", "tslib", "../Api/GridViews/GetRows", "../Dom/Util"
                 });
             });
         }
+        #handlePopState() {
+            let pageNo = 1;
+            this.#sortField = this.#defaultSortField;
+            this.#sortOrder = this.#defaultSortOrder;
+            const url = new URL(window.location.href);
+            url.searchParams.forEach((value, key) => {
+                if (key === "pageNo") {
+                    pageNo = parseInt(value, 10);
+                    return;
+                }
+                if (key === "sortField") {
+                    this.#sortField = value;
+                }
+                if (key === "sortOrder") {
+                    this.#sortOrder = value;
+                }
+            });
+            this.#switchPage(pageNo, false);
+        }
     }
     exports.GridView = GridView;
 });