mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-03-04 23:27:46 +01:00
Added pagination to the nodes list
This commit is contained in:
@@ -9,7 +9,6 @@ table {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
th, td {
|
||||
padding: 10px;
|
||||
border: 1px solid #333;
|
||||
@@ -67,7 +66,32 @@ tr:nth-child(odd) {
|
||||
width: 80%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 1em;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.pagination li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.pagination li a {
|
||||
color: white;
|
||||
background-color: #333;
|
||||
padding: 6px 12px;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pagination li.active a {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
@@ -139,6 +163,9 @@ tr:nth-child(odd) {
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Pagination Controls -->
|
||||
<div class="pagination"></div>
|
||||
{% else %}
|
||||
<p>No nodes found.</p>
|
||||
{% endif %}
|
||||
@@ -153,14 +180,19 @@ tr:nth-child(odd) {
|
||||
valueNames: [
|
||||
"long_name", "short_name", "hw_model", "firmware", "role",
|
||||
"last_lat", "last_long", "channel", { name: "last_update", attr: "data-timestamp" }
|
||||
]
|
||||
],
|
||||
page: 50,
|
||||
pagination: {
|
||||
paginationClass: "pagination"
|
||||
}
|
||||
};
|
||||
|
||||
nodeList = new List("node-list", options);
|
||||
|
||||
updateCount(); // Update count on load
|
||||
updateCount();
|
||||
|
||||
nodeList.on("updated", function () {
|
||||
updateCount(); // Update count when search or sort changes
|
||||
updateCount();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,7 +208,7 @@ tr:nth-child(odd) {
|
||||
return matchesRole && matchesChannel && matchesHWModel;
|
||||
});
|
||||
|
||||
updateCount(); // Update the count after filtering
|
||||
updateCount();
|
||||
}
|
||||
|
||||
function updateCount() {
|
||||
@@ -189,22 +221,21 @@ tr:nth-child(odd) {
|
||||
var rows = table.querySelectorAll("tr");
|
||||
var csvContent = [];
|
||||
|
||||
// Extract header row
|
||||
var headers = [];
|
||||
table.querySelectorAll("th").forEach(th => headers.push(th.innerText));
|
||||
csvContent.push(headers.join(","));
|
||||
|
||||
// Extract table rows
|
||||
rows.forEach(row => {
|
||||
var cells = row.querySelectorAll("td");
|
||||
if (cells.length > 0) {
|
||||
var rowData = [];
|
||||
cells.forEach(cell => rowData.push(cell.innerText));
|
||||
csvContent.push(rowData.join(","));
|
||||
if (row.style.display !== "none") {
|
||||
var cells = row.querySelectorAll("td");
|
||||
if (cells.length > 0) {
|
||||
var rowData = [];
|
||||
cells.forEach(cell => rowData.push(cell.innerText));
|
||||
csvContent.push(rowData.join(","));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Create CSV file and trigger download
|
||||
var csvString = csvContent.join("\n");
|
||||
var blob = new Blob([csvString], { type: "text/csv" });
|
||||
var a = document.createElement("a");
|
||||
|
||||
@@ -1020,27 +1020,36 @@ async def nodelist(request):
|
||||
content_type="text/plain",
|
||||
)
|
||||
|
||||
|
||||
@routes.get("/api")
|
||||
async def api(request):
|
||||
try:
|
||||
# Extract optional query parameters
|
||||
role = request.query.get("role")
|
||||
channel = request.query.get("channel")
|
||||
hw_model = request.query.get("hw_model")
|
||||
|
||||
# Fetch filtered nodes
|
||||
nodes = await store.get_nodes(role, channel, hw_model)
|
||||
|
||||
# Convert node objects to dictionaries for JSON output
|
||||
nodes_json = [node.to_dict() for node in nodes]
|
||||
return web.json_response({"nodes": nodes_json})
|
||||
|
||||
# Return a pretty-printed JSON response
|
||||
return web.json_response(
|
||||
{"nodes": nodes_json},
|
||||
dumps=lambda obj: json.dumps(obj, indent=2) # Pretty print for development
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
# Log error and stack trace to console
|
||||
print("Error in /api endpoint:", str(e))
|
||||
print(traceback.format_exc())
|
||||
|
||||
# Return a plain-text error response
|
||||
return web.Response(
|
||||
text=f"An error occurred: {str(e)}",
|
||||
status=500,
|
||||
content_type="text/plain",
|
||||
content_type="text/plain"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user