From 969bacc1379df77355e78f8ff580666fc1681b36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20Schr=C3=B6ter?=
Date: Mon, 27 Jan 2025 13:24:30 +0100
Subject: [PATCH] Implement pagination for modification history retrieval and
update frontend to support paginated data
---
app_http_handlers.go | 25 +++++++++++-
local_db.go | 26 +++++++++++-
web-app/src/History.tsx | 87 ++++++++++++++++++++++++++++++++---------
3 files changed, 116 insertions(+), 22 deletions(-)
diff --git a/app_http_handlers.go b/app_http_handlers.go
index 58809ec..85a944e 100644
--- a/app_http_handlers.go
+++ b/app_http_handlers.go
@@ -248,13 +248,34 @@ func (app *App) getDocumentHandler() gin.HandlerFunc {
// Section for local-db actions
func (app *App) getModificationHistoryHandler(c *gin.Context) {
- modifications, err := GetAllModifications(app.Database)
+ // Parse pagination parameters
+ page := 1
+ pageSize := 20
+
+ if p, err := strconv.Atoi(c.DefaultQuery("page", "1")); err == nil && p > 0 {
+ page = p
+ }
+ if ps, err := strconv.Atoi(c.DefaultQuery("pageSize", "20")); err == nil && ps > 0 && ps <= 100 {
+ pageSize = ps
+ }
+
+ // Get paginated modifications and total count
+ modifications, total, err := GetPaginatedModifications(app.Database, page, pageSize)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve modification history"})
log.Errorf("Failed to retrieve modification history: %v", err)
return
}
- c.JSON(http.StatusOK, modifications)
+
+ totalPages := (int(total) + pageSize - 1) / pageSize
+
+ c.JSON(http.StatusOK, gin.H{
+ "items": modifications,
+ "totalItems": total,
+ "totalPages": totalPages,
+ "currentPage": page,
+ "pageSize": pageSize,
+ })
}
func (app *App) undoModificationHandler(c *gin.Context) {
diff --git a/local_db.go b/local_db.go
index 931d7fb..2d696f2 100644
--- a/local_db.go
+++ b/local_db.go
@@ -63,13 +63,35 @@ func GetModification(db *gorm.DB, id uint) (*ModificationHistory, error) {
return &record, result.Error
}
-// GetAllModifications retrieves all modification records from the database
+// GetAllModifications retrieves all modification records from the database (deprecated - use GetPaginatedModifications instead)
func GetAllModifications(db *gorm.DB) ([]ModificationHistory, error) {
var records []ModificationHistory
- result := db.Order("date_changed DESC").Find(&records) // GORM's Find method retrieves all records
+ result := db.Order("date_changed DESC").Find(&records)
return records, result.Error
}
+// GetPaginatedModifications retrieves a page of modification records with total count
+func GetPaginatedModifications(db *gorm.DB, page int, pageSize int) ([]ModificationHistory, int64, error) {
+ var records []ModificationHistory
+ var total int64
+
+ // Get total count
+ if err := db.Model(&ModificationHistory{}).Count(&total).Error; err != nil {
+ return nil, 0, err
+ }
+
+ // Calculate offset
+ offset := (page - 1) * pageSize
+
+ // Get paginated records
+ result := db.Order("date_changed DESC").
+ Offset(offset).
+ Limit(pageSize).
+ Find(&records)
+
+ return records, total, result.Error
+}
+
// UndoModification marks a modification record as undone and sets the undo date
func SetModificationUndone(db *gorm.DB, record *ModificationHistory) error {
record.Undone = true
diff --git a/web-app/src/History.tsx b/web-app/src/History.tsx
index e68fb57..e659ea5 100644
--- a/web-app/src/History.tsx
+++ b/web-app/src/History.tsx
@@ -12,11 +12,23 @@ interface ModificationHistory {
UndoneDate: string | null;
}
+interface PaginatedResponse {
+ items: ModificationHistory[];
+ totalItems: number;
+ totalPages: number;
+ currentPage: number;
+ pageSize: number;
+}
+
const History: React.FC = () => {
const [modifications, setModifications] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [paperlessUrl, setPaperlessUrl] = useState('');
+ const [currentPage, setCurrentPage] = useState(1);
+ const [totalPages, setTotalPages] = useState(1);
+ const [totalItems, setTotalItems] = useState(0);
+ const pageSize = 20;
// Get Paperless URL
useEffect(() => {
@@ -36,19 +48,22 @@ const History: React.FC = () => {
fetchUrl();
}, []);
- // Get all modifications
+ // Get modifications with pagination
useEffect(() => {
- fetchModifications();
- }, []);
+ fetchModifications(currentPage);
+ }, [currentPage]);
- const fetchModifications = async () => {
+ const fetchModifications = async (page: number) => {
+ setLoading(true);
try {
- const response = await fetch('/api/modifications');
+ const response = await fetch(`/api/modifications?page=${page}&pageSize=${pageSize}`);
if (!response.ok) {
throw new Error('Failed to fetch modifications');
}
- const data = await response.json();
- setModifications(data);
+ const data: PaginatedResponse = await response.json();
+ setModifications(data.items);
+ setTotalPages(data.totalPages);
+ setTotalItems(data.totalItems);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error occurred');
} finally {
@@ -108,19 +123,55 @@ const History: React.FC = () => {
No modifications found
) : (
-
- {modifications.map((modification) => (
-
- ))}
-
+ <>
+
+ {modifications.map((modification) => (
+
+ ))}
+
+
+
+
+ Showing {((currentPage - 1) * pageSize) + 1} to {Math.min(currentPage * pageSize, totalItems)} of {totalItems} results
+
+
+
+
+
+ Page {currentPage} of {totalPages}
+
+
+
+
+ >
)}
);
};
-export default History;
\ No newline at end of file
+export default History;