commit 7767aa14e055f5e8e6428502140b9e7af32f1189
parent 9a642663cde612e797a13540d9b73063249500de
Author: William Lindholm <william_lindholm@outlook.com>
Date: Sun, 5 Nov 2023 22:44:54 +0100
Added pagination for tables.
Diffstat:
7 files changed, 125 insertions(+), 65 deletions(-)
diff --git a/WebAPI/routes.py b/WebAPI/routes.py
@@ -44,7 +44,7 @@ class contact(Resource):
@api.route('/messages')
class Messages(Resource):
def get(self):
- messages = db_repo.fetch_messages()
+ messages = db_repo.get_all_messages()
formatted_messages = [
{
"id": message[0],
diff --git a/WebInterface/routes.py b/WebInterface/routes.py
@@ -5,6 +5,7 @@ from flask import Flask, request, redirect, url_for, render_template, session
from dbrepository import DatabaseRepository
from . import web_interface
from .tableBuilder import TableBuilder
+from .tableFactory import TableFactory
db = DatabaseRepository()
@@ -15,7 +16,7 @@ def home():
if not session.get('logged_in'):
return redirect(url_for('web_interface.login'))
- messages = db.fetch_messages()
+ messages = db.get_all_messages()
formatted_messages = [
{
@@ -35,31 +36,12 @@ def home():
@web_interface.route('/integrations')
def integrations():
- # Define headers and rows for the messages table
- headers = ["ID", "Message", "Date", "Delete"]
- rows = [
- [1, "Hello World!", "2023-11-01"],
- [2, "Another Message", "2023-11-02"],
- ]
+ page_number = request.args.get('page', 1, type=int)
+
+ tables = TableFactory()
+ message_table = tables.get_message_table(page_number)
- def delete_link(row_data):
- # Assuming row_data is a dictionary that contains an 'id' key
- id = row_data[0]
- # Return a string of HTML. The 'material-icons' class is used for Material Icons
- return f'<a href="/message/delete/{id}" class="delete-icon"><i class="material-icons">delete</i></a>'
-
- # Initialize TableBuilder and configure the table
- table_builder = TableBuilder()
- table_builder.set_headers(headers)
- table_builder.add_rows(rows)
- table_builder.set_pagination(enabled=True, page_size=5)
- table_builder.set_sortable(["ID", "Date"])
- table_builder.add_callback_column(delete_link)
- table_builder.set_on_click("/message/{0}")
-
- # Build the TableInstance
- table_instance = table_builder.build()
- return render_template('integrations.html', page_title="Integrations", table=table_instance)
+ return render_template('integrations.html', page_title="Integrations", table=message_table)
@web_interface.route('/login', methods=['GET', 'POST'])
def login():
diff --git a/WebInterface/tableBuilder.py b/WebInterface/tableBuilder.py
@@ -1,4 +1,4 @@
-class TableInstance:
+class TableBuilder:
def __init__(self):
self.headers = []
self.rows = []
@@ -6,53 +6,79 @@ class TableInstance:
self.pagination_enabled = False
self.page_size = 10
self.current_page = 1
- self.callback_column = None
+ self.total_pages = 0
+ self.callback_columns = []
self.row_click_url_template = ""
def add_header(self, header):
self.headers.append(header)
+ return self
def add_row(self, row):
self.rows.append(row)
+ return self
def enable_pagination(self, page_size=10):
self.pagination_enabled = True
self.page_size = page_size
+ return self
def set_sortable_columns(self, columns):
self.sortable_columns = columns
+ return self
def set_callback_column(self, callback):
self.callback_column = callback
+ return self
def set_row_click_url_template(self, url_template):
self.row_click_url_template = url_template
-
-
-class TableBuilder:
- def __init__(self):
- self.table_instance = TableInstance()
+ return self
def set_headers(self, headers):
for header in headers:
- self.table_instance.add_header(header)
+ self.add_header(header)
+ return self
def add_rows(self, rows):
for row in rows:
- self.table_instance.add_row(row)
+ self.add_row(row)
+ return self
def set_pagination(self, enabled=True, page_size=10):
if enabled:
- self.table_instance.enable_pagination(page_size)
+ self.enable_pagination(page_size)
+ return self
+
+ def set_total_pages(self, total_pages):
+ self.total_pages = total_pages
+ return self
+
+ def set_current_page(self, page):
+ self.current_page = page
+ return self
def set_sortable(self, sortable_columns):
- self.table_instance.set_sortable_columns(sortable_columns)
+ self.set_sortable_columns(sortable_columns)
+ return self
def add_callback_column(self, callback):
- self.table_instance.set_callback_column(callback)
+ self.callback_columns.append(callback)
+ return self
def set_on_click(self, url_template):
- self.table_instance.set_row_click_url_template(url_template)
+ self.set_row_click_url_template(url_template)
+ return self
- def build(self):
- return self.table_instance
-\ No newline at end of file
+ def get_table_data(self):
+ return {
+ "headers": self.headers,
+ "rows": self.rows,
+ "sortable_columns": self.sortable_columns,
+ "pagination_enabled": self.pagination_enabled,
+ "page_size": self.page_size,
+ "current_page": self.current_page,
+ "total_pages": self.total_pages,
+ "callback_columns": self.callback_columns,
+ "row_click_url_template": self.row_click_url_template
+ }
diff --git a/WebInterface/tableFactory.py b/WebInterface/tableFactory.py
@@ -0,0 +1,36 @@
+from WebInterface.tableBuilder import TableBuilder
+from dbrepository import DatabaseRepository
+
+
+class TableFactory:
+
+ def __init__(self):
+ self.db = DatabaseRepository()
+
+ @staticmethod
+ def delete_link(row_data):
+ return f'<a href="/message/delete/{row_data[0]}" class="delete-icon"><i class="material-icons">delete</i></a>'
+
+ def get_message_table(self, page=0, page_size=10):
+ headers = [
+ ("ID", "8%"),
+ ("Sender", "10%"),
+ ("Relevance", "10%"),
+ ("Message", "67%"),
+ ("Delete", "5%")
+ ]
+
+ messages, total_pages = self.db.get_messages(page, page_size)
+
+ table_data = (TableBuilder()
+ .set_headers(headers)
+ .add_rows(messages)
+ .set_pagination(enabled=True, page_size=page_size)
+ .set_total_pages(total_pages)
+ .set_current_page(page)
+ .set_sortable(["ID"])
+ .set_on_click("/message/{0}")
+ .add_callback_column(self.delete_link)
+ .get_table_data())
+
+ return table_data
+\ No newline at end of file
diff --git a/dbrepository.py b/dbrepository.py
@@ -1,5 +1,7 @@
+import math
import sqlite3
+
class DatabaseRepository:
DATABASE_FILE = 'messages.db'
@@ -37,10 +39,26 @@ class DatabaseRepository:
conn.commit()
conn.close()
- def fetch_messages(self):
+ def get_all_messages(self):
conn = sqlite3.connect(self.DATABASE_FILE)
cursor = conn.cursor()
- cursor.execute("SELECT * FROM messages ORDER BY timestamp DESC")
+ cursor.execute("SELECT id, email, relevance, message_content FROM messages ORDER BY timestamp DESC")
messages = cursor.fetchall()
conn.close()
- return messages
-\ No newline at end of file
+ return messages
+
+ def get_messages(self, page, page_size):
+ conn = sqlite3.connect(self.DATABASE_FILE)
+ cursor = conn.cursor()
+
+ total_messages = cursor.execute('SELECT COUNT(*) FROM messages').fetchone()[0]
+ offset = (page - 1) * page_size
+ total_pages = math.ceil(total_messages / page_size)
+
+ paginated_messages = cursor.execute(
+ 'SELECT id, email, relevance, message_content FROM messages ORDER BY timestamp DESC LIMIT ? OFFSET ?',
+ (page_size, offset)
+ ).fetchall()
+
+ conn.close()
+ return paginated_messages, total_pages
diff --git a/static/css/main.css b/static/css/main.css
@@ -83,4 +83,8 @@ h1.mobile {
.delete-icon {
color: red;
+}
+
+td, td {
+ min-width: 100px;
}
\ No newline at end of file
diff --git a/templates/table.html b/templates/table.html
@@ -1,42 +1,37 @@
-<table id="table-instance" class="highlight">
+<table style="table-layout: fixed;" id="table-instance" class="highlight">
<thead>
<tr>
- <!-- Headers and sortable logic will be inserted here -->
- {% for header in table.headers %}
- <th>
- {{ header }}
- {% if header in table.sortable_columns %}
- <!-- Add sorting logic/link here -->
+ {% for header, width in table.headers %}
+ <th style="width: {{ width }}">
+ {{ header }}
+ {% if header in table.sortable_columns %}
<a href="?sort_by={{ header }}&order=asc">↑</a>
<a href="?sort_by={{ header }}&order=desc">↓</a>
- {% endif %}
+ {% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
- <!-- Rows and Data will be inserted here -->
{% for row in table.rows %}
<tr onclick="window.location.href='{{ table.row_click_url_template.format(row[0]) }}';">
{% for cell in row %}
- <td>{{ cell }}</td>
+ <td><p class="truncate">{{ cell }}</p></td>
+ {% endfor %}
+ {% for callback_column in table.callback_columns %}
+ <td>{{ callback_column(row) | safe }}</td>
{% endfor %}
- <!-- Callback action buttons if any -->
- {% if table.callback_column %}
- <td>{{ table.callback_column(row) | safe }}</td>
- {% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% if table.pagination_enabled %}
- <ul class="pagination">
- {% set total_pages = ((table.rows|length / table.page_size) | round(0, 'ceil')) | int %}
- {% for i in range(1, total_pages + 1) %}
+<ul class="pagination">
+ {% for i in range(1, table.total_pages + 1) %}
<li class="{% if table.current_page == i %}active{% else %}waves-effect{% endif %}">
- <a href="?page={{ i }}">{{ i }}</a>
+ <a href="?page={{ i }}">{{ i }}</a>
</li>
{% endfor %}
- </ul>
+</ul>
{% endif %}
\ No newline at end of file