Skip to content

Commit

Permalink
add pagination to activity
Browse files Browse the repository at this point in the history
kinof meh because of subsequential grouping
  • Loading branch information
Sylvain Blanc committed Aug 30, 2024
1 parent 3c09a9e commit b3a3460
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 70 deletions.
23 changes: 21 additions & 2 deletions backend/routes/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,10 +707,20 @@ router.post("/getItemDetails", async (req, res) => {
//DB Queries - History
router.get("/getHistory", async (req, res) => {
try {
// Extract page and limit from query parameters
const page = parseInt(req.query.page) || 0; // default to page 1 if not provided
const limit = parseInt(req.query.limit) || 10; // default to 10 items per page if not provided
const offset = (page) * limit;

// Fetch rows with pagination
const { rows } = await db.query(
`SELECT * FROM jf_playback_activity order by "ActivityDateInserted" desc`,
`SELECT * FROM jf_playback_activity
ORDER BY "ActivityDateInserted" DESC
LIMIT $1 OFFSET $2`,
[limit, offset]
);

// Group results as per the existing logic
const groupedResults = {};
rows.forEach((row) => {
if (groupedResults[row.NowPlayingItemId + row.EpisodeId]) {
Expand All @@ -734,12 +744,21 @@ router.get("/getHistory", async (req, res) => {
}
});

res.send(Object.values(groupedResults));
// Return paginated results
res.send({
page,
limit,
totalItems: rows.length, // Total number of items in the current page
totalGroups: Object.keys(groupedResults).length, // Total number of grouped results in the current page
data: Object.values(groupedResults),
});
} catch (error) {
console.log(error);
res.status(500).send("Server error");
}
});


router.post("/getLibraryHistory", async (req, res) => {
try {
const { libraryid } = req.body;
Expand Down
48 changes: 21 additions & 27 deletions frontend/src/pages/activity.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from "react";

import axios from "axios";

import "./css/activity.css";
Expand All @@ -9,10 +8,11 @@ import ActivityTable from "./components/activity/activity-table";
import Loading from "./components/general/loading";

function Activity() {
const [data, setData] = useState();
const [data, setData] = useState([]);
const [config, setConfig] = useState(null);

const [itemCount, setItemCount] = useState(10);
const [itemCount, setItemCount] = useState(10); // Nombre d'éléments par page
const [page, setPage] = useState(0); // Page actuelle

useEffect(() => {
const fetchConfig = async () => {
Expand All @@ -34,44 +34,32 @@ function Activity() {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json",
},
params: {
page,
limit: itemCount,
},
})
.then((data) => {
setData(data.data);
.then((response) => {
setData(response.data.data);
})
.catch((error) => {
console.log(error);
});
};

if (!data && config) {
if (config) {
fetchLibraries();
}

if (!config) {
} else {
fetchConfig();
}

const intervalId = setInterval(fetchLibraries, 60000 * 60);
return () => clearInterval(intervalId);
}, [data, config]);
return () => {};
}, [config, page, itemCount]);

if (!data) {
if (!data.length) {
return <Loading />;
}

if (data.length === 0) {
return (
<div>
<div className="Heading">
<h1>Activity</h1>
</div>
<div className="Activity">
<h1>No Activity to display</h1>
</div>
</div>
);
}

return (
<div className="Activity">
<div className="Heading">
Expand All @@ -82,6 +70,7 @@ function Activity() {
value={itemCount}
onChange={(event) => {
setItemCount(event.target.value);
setPage(0); // Revenir à la première page lors du changement de nombre d'éléments
}}
>
<option value="10">10</option>
Expand All @@ -92,7 +81,12 @@ function Activity() {
</div>
</div>
<div className="Activity">
<ActivityTable data={data} itemCount={itemCount} />
<ActivityTable
data={data}
itemPerPage={itemCount}
page={page}
setPage={setPage}
/>
</div>
</div>
);
Expand Down
54 changes: 13 additions & 41 deletions frontend/src/pages/components/activity/activity-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import StreamInfo from "./stream_info";

import "../../css/activity/activity-table.css";

// localStorage.setItem('hour12',true);

function formatTotalWatchTime(seconds) {
const hours = Math.floor(seconds / 3600);
Expand Down Expand Up @@ -134,12 +133,10 @@ function Row(data) {
<span onClick={() => openModal(row)}>{row.Client}</span>
</TableCell>
<TableCell>
{Intl.DateTimeFormat("en-UK", options).format(
new Date(row.ActivityDateInserted),
)}
{row.ActivityDateInserted}
</TableCell>
<TableCell>
{formatTotalWatchTime(row.PlaybackDuration) || "0 seconds"}
{formatTotalWatchTime(row.TotalPlaybackDuration) || "0 seconds"}
</TableCell>
<TableCell>
{row.results.length !== 0 ? row.results.length : 1}
Expand Down Expand Up @@ -302,23 +299,17 @@ function EnhancedTableHead(props) {
}

export default function ActivityTable(props) {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);

const [order, setOrder] = React.useState("desc");
const [orderBy, setOrderBy] = React.useState("ActivityDateInserted");

if (rowsPerPage !== props.itemCount) {
setRowsPerPage(props.itemCount);
setPage(0);
}

const handleNextPageClick = () => {
setPage((prevPage) => prevPage + 1);
props.setPage(() => props.page + 1);
};

const handlePreviousPageClick = () => {
setPage((prevPage) => prevPage - 1);
props.setPage(() => props.page - 1);
};

function descendingComparator(a, b, orderBy) {
Expand Down Expand Up @@ -352,14 +343,6 @@ export default function ActivityTable(props) {
return stabilizedThis.map((el) => el[0]);
}

const visibleRows = React.useMemo(
() =>
stableSort(props.data, getComparator(order, orderBy)).slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage,
),
[order, orderBy, page, rowsPerPage, getComparator, props.data],
);

const handleRequestSort = (event, property) => {
const isAsc = orderBy === property && order === "asc";
Expand All @@ -375,10 +358,10 @@ export default function ActivityTable(props) {
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
rowCount={rowsPerPage}
rowCount={props.itemPerPage}
/>
<TableBody>
{visibleRows.map((row) => (
{props.data.map((row) => (
<Row
key={row.Id + row.NowPlayingItemId + row.EpisodeId}
row={row}
Expand Down Expand Up @@ -409,44 +392,33 @@ export default function ActivityTable(props) {
<ButtonGroup className="pagination-buttons">
<Button
className="page-btn"
onClick={() => setPage(0)}
disabled={page === 0}
onClick={() => props.setPage(0)}
disabled={props.page === 0}
>
First
</Button>

<Button
className="page-btn"
onClick={handlePreviousPageClick}
disabled={page === 0}
disabled={props.page === 0}
>
Previous
</Button>

<div className="page-number d-flex align-items-center justify-content-center">{`${
page * rowsPerPage + 1
}-${Math.min(
page * rowsPerPage + 1 + (rowsPerPage - 1),
props.data.length,
)} of ${props.data.length}`}</div>
(props.page) * props.itemPerPage + 1
}-${
props.page * props.itemPerPage + 1 + (props.itemPerPage - 1)
}`}</div>

<Button
className="page-btn"
onClick={handleNextPageClick}
disabled={page >= Math.ceil(props.data.length / rowsPerPage) - 1}
>
Next
</Button>

<Button
className="page-btn"
onClick={() =>
setPage(Math.ceil(props.data.length / rowsPerPage) - 1)
}
disabled={page >= Math.ceil(props.data.length / rowsPerPage) - 1}
>
Last
</Button>
</ButtonGroup>
</div>
</>
Expand Down

0 comments on commit b3a3460

Please sign in to comment.