summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2024-01-10 09:12:02 +0100
committerPaul-Christian Volkmer2024-01-10 09:12:02 +0100
commitd88e2973da6988ca93521348836151f1ee6a8444 (patch)
treee403f9c7ffe3b551227200499b7db3e14304423c
parentaf767e4ea68325304142b7083dd8201607288f9e (diff)
feat: add paginator to request page
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt7
-rw-r--r--src/main/resources/static/style.css39
-rw-r--r--src/main/resources/templates/index.html81
4 files changed, 100 insertions, 30 deletions
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
index c1d4d43..0738650 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
@@ -24,6 +24,7 @@ import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.relational.core.mapping.Embedded
import org.springframework.data.relational.core.mapping.Table
import org.springframework.data.repository.CrudRepository
+import org.springframework.data.repository.PagingAndSortingRepository
import java.time.Instant
import java.util.*
@@ -52,7 +53,7 @@ data class CountedState(
val status: RequestStatus,
)
-interface RequestRepository : CrudRepository<Request, Long> {
+interface RequestRepository : CrudRepository<Request, Long>, PagingAndSortingRepository<Request, Long> {
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: String): List<Request>
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
index 51bf3fc..99b9972 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
@@ -23,6 +23,9 @@ import dev.dnpm.etl.processor.NotFoundException
import dev.dnpm.etl.processor.monitoring.ReportService
import dev.dnpm.etl.processor.monitoring.RequestId
import dev.dnpm.etl.processor.monitoring.RequestRepository
+import org.springframework.data.domain.Pageable
+import org.springframework.data.domain.Sort
+import org.springframework.data.web.PageableDefault
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
@@ -37,8 +40,8 @@ class HomeController(
) {
@GetMapping
- fun index(model: Model): String {
- val requests = requestRepository.findAll().sortedByDescending { it.processedAt }.take(25)
+ fun index(@PageableDefault(page = 0, size = 20, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable, model: Model): String {
+ val requests = requestRepository.findAll(pageable)
model.addAttribute("requests", requests)
return "index"
diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css
index f3266e2..e215eb0 100644
--- a/src/main/resources/static/style.css
+++ b/src/main/resources/static/style.css
@@ -92,6 +92,10 @@ nav li a:hover {
text-decoration: underline;
}
+a {
+ color: var(--bg-blue);
+}
+
.breadcrumps {
margin: 0 auto;
max-width: 1140px;
@@ -188,6 +192,41 @@ table {
font-family: sans-serif;
}
+.paged-table {
+ border: 1px solid var(--table-border);
+ border-radius: .5em;
+ background: white;
+}
+
+.paged-table > table {
+ border: none;
+ background: transparent;
+}
+
+.page-control {
+ border-radius: .5em;
+ padding: 1em 2em;
+ text-align: center;
+
+ line-height: 1.75em;
+}
+
+.page-control a {
+ padding: 0 .25em;
+ font-size: 1.75em;
+ color: var(--bg-gray);
+ text-decoration: none;
+}
+
+.page-control a[href] {
+ color: var(--bg-blue);
+}
+
+.page-control span {
+ padding: 0 .5em;
+ vertical-align: text-bottom;
+}
+
#samples-table.max {
width: 100vw;
position: fixed;
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
index 96f1cfe..ec8b3c7 100644
--- a/src/main/resources/templates/index.html
+++ b/src/main/resources/templates/index.html
@@ -11,35 +11,62 @@
<h1>Letzte Anfragen</h1>
- <table>
- <thead>
- <tr>
- <th>Status</th>
- <th>Typ</th>
- <th>ID</th>
- <th>Datum</th>
- <th>Patienten-ID</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="request : ${requests}">
- <td th:if="${request.status.value.contains('success')}" class="bg-green"><small>[[ ${request.status} ]]</small></td>
- <td th:if="${request.status.value.contains('warning')}" class="bg-yellow"><small>[[ ${request.status} ]]</small></td>
- <td th:if="${request.status.value.contains('error')}" class="bg-red"><small>[[ ${request.status} ]]</small></td>
- <td th:if="${request.status.value == 'unknown'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
- <td th:if="${request.status.value == 'duplication'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
- <td th:style="${request.type.value == 'delete'} ? 'color: red;'"><small>[[ ${request.type} ]]</small></td>
- <td th:if="not ${request.report}">[[ ${request.uuid} ]]</td>
- <td th:if="${request.report}">
- <a th:href="@{/report/{id}(id=${request.uuid})}">[[ ${request.uuid} ]]</a>
- </td>
- <td><time th:datetime="${request.processedAt}">[[ ${request.processedAt} ]]</time></td>
- <td>[[ ${request.patientId} ]]</td>
- </tr>
- </tbody>
- </table>
+ <div class="paged-table">
+ <div class="page-control">
+ <a id="first-page-link" th:href="@{/(page=${0})}" title="Zum Anfang: Taste W" th:if="${not requests.isFirst()}">&larrb;</a><a th:if="${requests.isFirst()}">&larrb;</a>
+ <a id="prev-page-link" th:href="@{/(page=${requests.getNumber() - 1})}" title="Seite zurück: Taste A" th:if="${not requests.isFirst()}">&larr;</a><a th:if="${requests.isFirst()}">&larr;</a>
+ <span>Seite [[ ${requests.getNumber() + 1} ]] von [[ ${requests.getTotalPages()} ]]</span>
+ <a id="next-page-link" th:href="@{/(page=${requests.getNumber() + 1})}" title="Seite vor: Taste D" th:if="${not requests.isLast()}">&rarr;</a><a th:if="${requests.isLast()}">&rarr;</a>
+ <a id="last-page-link" th:href="@{/(page=${requests.getTotalPages() - 1})}" title="Zum Ende: Taste S" th:if="${not requests.isLast()}">&rarrb;</a><a th:if="${requests.isLast()}">&rarrb;</a>
+ </div>
+ <table class="paged">
+ <thead>
+ <tr>
+ <th>Status</th>
+ <th>Typ</th>
+ <th>ID</th>
+ <th>Datum</th>
+ <th>Patienten-ID</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr th:each="request : ${requests}">
+ <td th:if="${request.status.value.contains('success')}" class="bg-green"><small>[[ ${request.status} ]]</small></td>
+ <td th:if="${request.status.value.contains('warning')}" class="bg-yellow"><small>[[ ${request.status} ]]</small></td>
+ <td th:if="${request.status.value.contains('error')}" class="bg-red"><small>[[ ${request.status} ]]</small></td>
+ <td th:if="${request.status.value == 'unknown'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
+ <td th:if="${request.status.value == 'duplication'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
+ <td th:style="${request.type.value == 'delete'} ? 'color: red;'"><small>[[ ${request.type} ]]</small></td>
+ <td th:if="not ${request.report}">[[ ${request.uuid} ]]</td>
+ <td th:if="${request.report}">
+ <a th:href="@{/report/{id}(id=${request.uuid})}">[[ ${request.uuid} ]]</a>
+ </td>
+ <td><time th:datetime="${request.processedAt}">[[ ${request.processedAt} ]]</time></td>
+ <td>[[ ${request.patientId} ]]</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</main>
<script th:src="@{/scripts.js}"></script>
+ <script>
+ window.onload = () => {
+ let keyBindings = {
+ 'w': 'first-page-link',
+ 'a': 'prev-page-link',
+ 'd': 'next-page-link',
+ 's': 'last-page-link'
+ };
+ window.onkeydown = (event) => {
+ for (const [key, elemId] of Object.entries(keyBindings)) {
+ if (event.key === key && document.getElementById(elemId)) {
+ document.getElementById(elemId).style.background = 'yellow';
+ document.getElementById(elemId).click();
+ }
+ }
+ };
+ };
+ </script>
</body>
</html> \ No newline at end of file