diff options
Diffstat (limited to 'src/main')
4 files changed, 53 insertions, 8 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 9aede20..4ed071d 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt @@ -144,4 +144,6 @@ interface RequestRepository : ") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;" ) fun findPatientUniqueDeleteStates(): List<CountedState> + + fun findByPatientPseudonymContainingIgnoreCaseOrTanContainingIgnoreCase(patientPseudonym: PatientPseudonym, tan: Tan, pageable: Pageable): Page<Request> } diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt index e7cb95f..3a2ea35 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt @@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.services import dev.dnpm.etl.processor.PatientPseudonym import dev.dnpm.etl.processor.RequestId +import dev.dnpm.etl.processor.Tan import dev.dnpm.etl.processor.monitoring.* import java.util.* import org.springframework.data.domain.Page @@ -36,6 +37,9 @@ class RequestService(private val requestRepository: RequestRepository) { fun findAll(pageable: Pageable): Page<Request> = requestRepository.findAll(pageable) + fun searchRequestLike(patientPseudonym: PatientPseudonym, tan: Tan, pageable: Pageable): Page<Request> = + requestRepository.findByPatientPseudonymContainingIgnoreCaseOrTanContainingIgnoreCase(patientPseudonym, tan, pageable) + fun findByUuid(uuid: RequestId): Optional<Request> = requestRepository.findByUuidEquals(uuid) fun findRequestByPatientId( 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 9262c29..6a76c38 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt @@ -22,12 +22,14 @@ package dev.dnpm.etl.processor.web import dev.dnpm.etl.processor.NotFoundException import dev.dnpm.etl.processor.PatientPseudonym import dev.dnpm.etl.processor.RequestId +import dev.dnpm.etl.processor.Tan import dev.dnpm.etl.processor.config.AppConfigProperties import dev.dnpm.etl.processor.monitoring.ReportService import dev.dnpm.etl.processor.services.RequestService import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.data.web.PageableDefault +import org.springframework.security.core.context.SecurityContextHolder import org.springframework.stereotype.Controller import org.springframework.ui.Model import org.springframework.web.bind.annotation.DeleteMapping @@ -35,6 +37,7 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam @Controller @RequestMapping(path = ["/"]) @@ -45,11 +48,26 @@ class HomeController( ) { @GetMapping fun index( + @RequestParam(name = "q", required = false) queryString: String?, @PageableDefault(page = 0, size = 10, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable, model: Model, ): String { - val requests = requestService.findAll(pageable) + val isAdminOrUser = + SecurityContextHolder + .getContext() + .authentication + ?.authorities + ?.any { it.authority == "ROLE_USER" || it.authority == "ROLE_ADMIN" } == true + + val requests = + // Only available for logged-in admins or users + if (null != queryString && isAdminOrUser) { + model.addAttribute("query", queryString) + requestService.searchRequestLike(PatientPseudonym(queryString), Tan(queryString), pageable) + } else { + requestService.findAll(pageable) + } model.addAttribute("requests", requests) model.addAttribute("postInitialSubmissionBlock", appConfigProperties.postInitialSubmissionBlock) return "index" diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index db85196..cea3f73 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -9,6 +9,13 @@ <div th:replace="~{fragments.html :: nav}"></div> <main> + <div class="search-form" sec:authorize="hasRole('USER') or hasRole('ADMIN')"> + <form th:action="@{/}" method="get"> + <input id="search-input" type="text" name="q" maxlength="64" placeholder="Suche nach Patienten-Pseudonym oder TAN" th:value="${query}"/> + <a th:href="@{/}">🞫</a> + </form> + </div> + <h1> Alle Anfragen <a id="reload-notify" class="btn btn-red reload" title="Neue Anfragen laden" th:href="@{/}"> @@ -19,7 +26,12 @@ <div> <h2 th:if="${patientPseudonym != null}"> Betreffend Patienten-Pseudonym <span class="monospace" th:text="${patientPseudonym}">***</span> - <a class="btn btn-blue" th:if="${patientPseudonym != null}" th:href="@{/}">Alle anzeigen</a> + <a class="btn btn-blue" th:href="@{/}">Alle anzeigen</a> + </h2> + + <h2 th:if="not ${null == query || query.isBlank()}"> + Für die Suche nach „<span class="monospace" th:text="${query}">***</span>“ + <a class="btn btn-blue" th:href="@{/}">Alle anzeigen</a> </h2> </div> @@ -27,7 +39,7 @@ <div class="notification info">Noch keine Anfragen eingegangen</div> </div> - <div class="border" th:if="${requests.totalElements > 0}"> + <div th:if="${requests.totalElements > 0}"> <div class="paged"> <div class="card" th:each="request : ${requests}"> <div th:if="${request.status.value.contains('success')}" class="card-header bg-green">Erfolgreiche Übertragung</div> @@ -77,13 +89,20 @@ </div> </div> </div> - <div th:if="${patientPseudonym == null}" class="page-control"> + <div th:if="${patientPseudonym == null && query == null}" class="page-control"> <a id="first-page-link" th:href="@{/(page=${0})}" title="Zum Anfang: Taste W" th:if="${not requests.isFirst()}">⇤</a><a th:if="${requests.isFirst()}">⇤</a> <a id="prev-page-link" th:href="@{/(page=${requests.getNumber() - 1})}" title="Seite zurück: Taste A" th:if="${not requests.isFirst()}">←</a><a th:if="${requests.isFirst()}">←</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()}">→</a><a th:if="${requests.isLast()}">→</a> <a id="last-page-link" th:href="@{/(page=${requests.getTotalPages() - 1})}" title="Zum Ende: Taste S" th:if="${not requests.isLast()}">⇥</a><a th:if="${requests.isLast()}">⇥</a> </div> + <div th:if="${patientPseudonym == null && query != null}" class="page-control"> + <a id="first-page-link" th:href="@{/(q=${query},page=${0})}" title="Zum Anfang: Taste W" th:if="${not requests.isFirst()}">⇤</a><a th:if="${requests.isFirst()}">⇤</a> + <a id="prev-page-link" th:href="@{/(q=${query},page=${requests.getNumber() - 1})}" title="Seite zurück: Taste A" th:if="${not requests.isFirst()}">←</a><a th:if="${requests.isFirst()}">←</a> + <span>Seite [[ ${requests.getNumber() + 1} ]] von [[ ${requests.getTotalPages()} ]]</span> + <a id="next-page-link" th:href="@{/(q=${query},page=${requests.getNumber() + 1})}" title="Seite vor: Taste D" th:if="${not requests.isLast()}">→</a><a th:if="${requests.isLast()}">→</a> + <a id="last-page-link" th:href="@{/(q=${query},page=${requests.getTotalPages() - 1})}" title="Zum Ende: Taste S" th:if="${not requests.isLast()}">⇥</a><a th:if="${requests.isLast()}">⇥</a> + </div> <div th:if="${patientPseudonym != null}" class="page-control"> <a id="first-page-link" th:href="@{/patient/{patientPseudonym}(patientPseudonym=${patientPseudonym},page=${0})}" title="Zum Anfang: Taste W" th:if="${not requests.isFirst()}">⇤</a><a th:if="${requests.isFirst()}">⇤</a> <a id="prev-page-link" th:href="@{/patient/{patientPseudonym}(patientPseudonym=${patientPseudonym},page=${requests.getNumber() - 1})}" title="Seite zurück: Taste A" th:if="${not requests.isFirst()}">←</a><a th:if="${requests.isFirst()}">←</a> @@ -105,10 +124,12 @@ '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(); + if (document.activeElement.id !== 'search-input') { + 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(); + } } } }; |
