From 025035190d49eba5616771c38a98cfdc2eb60895 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20G=C3=BCnrher?=
Date: Wed, 9 Sep 2026 17:32:50 +0200
Subject: [PATCH] User-Comfort im Zahlungsparser
---
.../Views/Partials/BankStatementImport.vue | 67 ++--
app/Views/Components/RichSelectBox.vue | 336 ++++++++++++++++--
2 files changed, 352 insertions(+), 51 deletions(-)
diff --git a/app/Domains/Event/Views/Partials/BankStatementImport.vue b/app/Domains/Event/Views/Partials/BankStatementImport.vue
index b5f391e..eb7d861 100644
--- a/app/Domains/Event/Views/Partials/BankStatementImport.vue
+++ b/app/Domains/Event/Views/Partials/BankStatementImport.vue
@@ -4,6 +4,7 @@ import {toast} from 'vue3-toastify'
import FullScreenModal from "../../../../Views/Components/FullScreenModal.vue";
import LoadingModal from "../../../../Views/Components/LoadingModal.vue";
import Icon from "../../../../Views/Components/Icon.vue";
+import RichSelectBox from "../../../../Views/Components/RichSelectBox.vue";
import {useAjax} from "../../../../../resources/js/components/ajaxHandler.js";
/**
@@ -41,6 +42,39 @@ const participantsByIdentifier = computed(
() => Object.fromEntries(participants.value.map(participant => [participant.identifier, participant])),
)
+/**
+ * Die Auswahlliste für alle Zeilen -- einmal gebaut, nicht je Zeile.
+ *
+ * Getrennt nach an- und abgemeldet, weil die Entscheidung unterschiedlich weit trägt: Eine Buchung
+ * auf eine abgemeldete Anmeldung zieht eine Erstattung nach sich. Als Fließtext in einer Zeile ging
+ * das unter, als Gruppenüberschrift steht es da.
+ */
+const participantOptions = computed(() => {
+ const options = [{value: '', label: '— ignorieren —'}]
+
+ for (const participant of participants.value) {
+ const state = participant.isSettled ? 'vollständig bezahlt' : participant.amountOpen + ' offen'
+
+ options.push(participant.isSignedOff
+ ? {
+ value: participant.identifier,
+ label: participant.name,
+ description: 'abgemeldet am ' + participant.signedOffAt + ' · ' + state,
+ group: 'Abgemeldete Teilis',
+ icon: 'user-slash',
+ muted: true,
+ }
+ : {
+ value: participant.identifier,
+ label: participant.name,
+ description: state,
+ group: 'Angemeldete Teilis',
+ })
+ }
+
+ return options
+})
+
function isAssigned(row) {
return (assignment.value[row.rowNumber] ?? '') !== ''
}
@@ -140,16 +174,6 @@ function reset() {
if (fileInput.value) fileInput.value.value = ''
}
-function optionLabel(participant) {
- const state = participant.isSettled
- ? 'vollständig bezahlt'
- : participant.amountOpen + ' offen'
-
- return participant.isSignedOff
- ? participant.name + ' — abgemeldet, ' + state
- : participant.name + ' — ' + state
-}
-
function assignedParticipant(row) {
return participantsByIdentifier.value[assignment.value[row.rowNumber]] ?? null
}
@@ -257,13 +281,10 @@ function signedOffOf(row) {
{{ row.purpose }} |
-
+
{{ rowState(row).label }}
@@ -458,7 +479,7 @@ function signedOffOf(row) {
padding: 10px;
border-bottom: 1px solid #e5e7eb;
vertical-align: top;
- font-size: 0.9rem;
+ font-size: 0.95rem;
}
.statement-table .right {
@@ -476,7 +497,7 @@ function signedOffOf(row) {
}
.assignment-column {
- width: 320px;
+ width: 360px;
}
/* Zeilenfarbe sagt auf einen Blick, was passiert: grün wird gebucht, gelb will geprüft werden,
@@ -520,14 +541,6 @@ function signedOffOf(row) {
gap: 5px;
}
-.assignment-select {
- width: 100%;
- padding: 5px 6px;
- border: 1px solid #d1d5db;
- border-radius: 6px;
- background-color: #ffffff;
- font-size: 0.85rem;
-}
.pill {
align-self: flex-start;
diff --git a/app/Views/Components/RichSelectBox.vue b/app/Views/Components/RichSelectBox.vue
index c168065..477d452 100644
--- a/app/Views/Components/RichSelectBox.vue
+++ b/app/Views/Components/RichSelectBox.vue
@@ -1,57 +1,229 @@
|