snapshot: preserve dashboard filters and realtime search

This commit is contained in:
Md Bayazid Bostame
2026-03-26 00:20:59 +01:00
parent e0231a6cca
commit 37c2cddf41
5 changed files with 260 additions and 102 deletions

View File

@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: tubco-portal\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-03-25 23:02+0000\n"
"POT-Creation-Date: 2026-03-25 23:12+0000\n"
"PO-Revision-Date: 2026-03-24 00:00+0000\n"
"Language: en\n"
"MIME-Version: 1.0\n"
@@ -29,7 +29,7 @@ msgid "Abgeschlossen"
msgstr "Completed"
#: workflows/models.py:58 workflows/models.py:312
#: workflows/templates/workflows/requests_dashboard.html:190
#: workflows/templates/workflows/requests_dashboard.html:226
#: workflows/templates/workflows/welcome_emails.html:112 workflows/views.py:183
msgid "Fehlgeschlagen"
msgstr "Failed"
@@ -56,6 +56,7 @@ msgstr ""
#: workflows/models.py:138
#: workflows/templates/workflows/onboarding_intro_session.html:32
#: workflows/templates/workflows/requests_dashboard.html:149
msgid "Abteilung"
msgstr "Department"
@@ -109,12 +110,14 @@ msgstr "Finish"
#: workflows/templates/workflows/home.html:66
#: workflows/templates/workflows/onboarding_form.html:25
#: workflows/templates/workflows/requests_dashboard.html:68
#: workflows/templates/workflows/requests_dashboard.html:135
msgid "Onboarding"
msgstr "Onboarding"
#: workflows/models.py:178 workflows/models.py:259
#: workflows/templates/workflows/home.html:82
#: workflows/templates/workflows/requests_dashboard.html:78
#: workflows/templates/workflows/requests_dashboard.html:136
msgid "Offboarding"
msgstr "Offboarding"
@@ -367,12 +370,15 @@ msgstr ""
#: workflows/templates/workflows/audit_log.html:23
#: workflows/templates/workflows/audit_log.html:54
#: workflows/templates/workflows/requests_dashboard.html:161
#: workflows/templates/workflows/requests_dashboard.html:197
#: workflows/templates/workflows/welcome_emails.html:91
msgid "Aktion"
msgstr "Action"
#: workflows/templates/workflows/audit_log.html:25
#: workflows/templates/workflows/requests_dashboard.html:134
#: workflows/templates/workflows/requests_dashboard.html:142
#: workflows/templates/workflows/requests_dashboard.html:151
msgid "Alle"
msgstr ""
@@ -400,7 +406,7 @@ msgid "Filtern"
msgstr ""
#: workflows/templates/workflows/audit_log.html:45
#: workflows/templates/workflows/requests_dashboard.html:133
#: workflows/templates/workflows/requests_dashboard.html:169
msgid "Zurücksetzen"
msgstr "Reset"
@@ -410,7 +416,8 @@ msgstr ""
#: workflows/templates/workflows/audit_log.html:55
#: workflows/templates/workflows/request_timeline.html:62
#: workflows/templates/workflows/requests_dashboard.html:156
#: workflows/templates/workflows/requests_dashboard.html:132
#: workflows/templates/workflows/requests_dashboard.html:192
msgid "Typ"
msgstr "Type"
@@ -509,17 +516,17 @@ msgid "Label (EN)"
msgstr "Label (EN)"
#: workflows/templates/workflows/form_builder.html:95
#: workflows/templates/workflows/integrations_setup.html:258
#: workflows/templates/workflows/integrations_setup.html:266
#: workflows/templates/workflows/intro_builder.html:69
msgid "Aktiv"
msgstr "Active"
#: workflows/templates/workflows/form_builder.html:96
#: workflows/templates/workflows/form_builder.html:111
#: workflows/templates/workflows/integrations_setup.html:260
#: workflows/templates/workflows/integrations_setup.html:268
#: workflows/templates/workflows/intro_builder.html:70
#: workflows/templates/workflows/intro_builder.html:106
#: workflows/templates/workflows/requests_dashboard.html:247
#: workflows/templates/workflows/requests_dashboard.html:283
#: workflows/templates/workflows/welcome_emails.html:74
msgid "Löschen"
msgstr "Delete"
@@ -705,7 +712,7 @@ msgstr ""
#: workflows/templates/workflows/home.html:4
#: workflows/templates/workflows/home.html:35
#: workflows/templates/workflows/requests_dashboard.html:263
#: workflows/templates/workflows/requests_dashboard.html:299
msgid "TUBCO Onboarding & Offboarding Portal"
msgstr "TUBCO Onboarding & Offboarding Portal"
@@ -759,12 +766,12 @@ msgid "E-Mail:"
msgstr "Email:"
#: workflows/templates/workflows/home.html:43
#: workflows/templates/workflows/integrations_setup.html:121
#: workflows/templates/workflows/integrations_setup.html:125
msgid "Testmodus"
msgstr "Test mode"
#: workflows/templates/workflows/home.html:43
#: workflows/templates/workflows/integrations_setup.html:121
#: workflows/templates/workflows/integrations_setup.html:125
msgid "Produktion"
msgstr "Production"
@@ -845,6 +852,7 @@ msgstr "Search"
#: workflows/templates/workflows/home.html:102
#: workflows/templates/workflows/onboarding_intro_session.html:41
#: workflows/templates/workflows/request_timeline.html:70
#: workflows/templates/workflows/requests_dashboard.html:140
#: workflows/templates/workflows/welcome_emails.html:89
msgid "Status"
msgstr "Status"
@@ -976,8 +984,8 @@ msgid "Nextcloud-Test starten"
msgstr "Nextcloud test"
#: workflows/templates/workflows/integrations_setup.html:62
#: workflows/templates/workflows/integrations_setup.html:120
#: workflows/templates/workflows/requests_dashboard.html:230
#: workflows/templates/workflows/integrations_setup.html:124
#: workflows/templates/workflows/requests_dashboard.html:266
msgid "Status:"
msgstr "Status:"
@@ -994,174 +1002,174 @@ msgid ""
msgstr ""
#: workflows/templates/workflows/integrations_setup.html:72
#: workflows/templates/workflows/integrations_setup.html:130
#: workflows/templates/workflows/integrations_setup.html:134
msgid "Leeres Passwortfeld lässt das bestehende Passwort unverändert."
msgstr "Leaving the password field empty keeps the current password unchanged."
#: workflows/templates/workflows/integrations_setup.html:106
#: workflows/templates/workflows/integrations_setup.html:110
#, fuzzy
#| msgid "Absenderadresse (optional)"
msgid "Absenderadresse"
msgstr "Sender address (optional)"
#: workflows/templates/workflows/integrations_setup.html:111
#: workflows/templates/workflows/integrations_setup.html:115
msgid "SMTP SSL"
msgstr "SMTP SSL"
#: workflows/templates/workflows/integrations_setup.html:112
#: workflows/templates/workflows/integrations_setup.html:116
msgid "SMTP TLS"
msgstr "SMTP TLS"
#: workflows/templates/workflows/integrations_setup.html:115
#: workflows/templates/workflows/integrations_setup.html:119
msgid "Mail speichern"
msgstr "Save mail settings"
#: workflows/templates/workflows/integrations_setup.html:116
#: workflows/templates/workflows/integrations_setup.html:120
#, fuzzy
#| msgid "SMTP-Test"
msgid "SMTP-Test starten"
msgstr "SMTP test"
#: workflows/templates/workflows/integrations_setup.html:123
#: workflows/templates/workflows/integrations_setup.html:127
#, fuzzy
#| msgid "E-Mail Modus"
msgid "E-Mail Modus schalten"
msgstr "Email mode"
#: workflows/templates/workflows/integrations_setup.html:129
#: workflows/templates/workflows/integrations_setup.html:133
msgid ""
"Im Testmodus werden Systemmails umgeleitet. In Produktion werden sie an die "
"echten Empfänger gesendet."
msgstr ""
#: workflows/templates/workflows/integrations_setup.html:139
#: workflows/templates/workflows/integrations_setup.html:147
msgid "It onboarding email"
msgstr "IT onboarding email"
#: workflows/templates/workflows/integrations_setup.html:143
#: workflows/templates/workflows/integrations_setup.html:151
msgid "General info email"
msgstr "General info email"
#: workflows/templates/workflows/integrations_setup.html:147
#: workflows/templates/workflows/integrations_setup.html:155
msgid "Business card email"
msgstr "Business card email"
#: workflows/templates/workflows/integrations_setup.html:151
#: workflows/templates/workflows/integrations_setup.html:159
msgid "Hr works email"
msgstr "HR Works email"
#: workflows/templates/workflows/integrations_setup.html:155
#: workflows/templates/workflows/integrations_setup.html:163
msgid "Key notification email"
msgstr "Key notification email"
#: workflows/templates/workflows/integrations_setup.html:159
#: workflows/templates/workflows/integrations_setup.html:167
msgid "Diese Empfänger werden für condition-based E-Mail Routing genutzt."
msgstr "These recipients are used for condition-based email routing."
#: workflows/templates/workflows/integrations_setup.html:186
#: workflows/templates/workflows/integrations_setup.html:194
msgid "E-Mail Routing & Vorlagen speichern"
msgstr "Save email routing & templates"
#: workflows/templates/workflows/integrations_setup.html:192
#: workflows/templates/workflows/integrations_setup.html:200
msgid "Bedingungsregeln für zusätzliche E-Mails"
msgstr "Conditional rules for additional emails"
#: workflows/templates/workflows/integrations_setup.html:193
#: workflows/templates/workflows/integrations_setup.html:201
msgid "Zusätzliche Regeln laufen nach dem Standard-Routing."
msgstr "Additional rules run after the standard routing flow."
#: workflows/templates/workflows/integrations_setup.html:200
#: workflows/templates/workflows/integrations_setup.html:271
#: workflows/templates/workflows/integrations_setup.html:208
#: workflows/templates/workflows/integrations_setup.html:279
msgid "Regelname"
msgstr "Rule name"
#: workflows/templates/workflows/integrations_setup.html:204
#: workflows/templates/workflows/integrations_setup.html:275
#: workflows/templates/workflows/integrations_setup.html:212
#: workflows/templates/workflows/integrations_setup.html:283
msgid "Event"
msgstr "Event"
#: workflows/templates/workflows/integrations_setup.html:212
#: workflows/templates/workflows/integrations_setup.html:283
#: workflows/templates/workflows/integrations_setup.html:220
#: workflows/templates/workflows/integrations_setup.html:291
msgid "Feldname"
msgstr "Field name"
#: workflows/templates/workflows/integrations_setup.html:216
#: workflows/templates/workflows/integrations_setup.html:287
#: workflows/templates/workflows/integrations_setup.html:224
#: workflows/templates/workflows/integrations_setup.html:295
#: workflows/templates/workflows/intro_builder.html:67
msgid "Operator"
msgstr "Operator"
#: workflows/templates/workflows/integrations_setup.html:224
#: workflows/templates/workflows/integrations_setup.html:295
#: workflows/templates/workflows/integrations_setup.html:232
#: workflows/templates/workflows/integrations_setup.html:303
msgid "Vergleichswert"
msgstr "Comparison value"
#: workflows/templates/workflows/integrations_setup.html:228
#: workflows/templates/workflows/integrations_setup.html:299
#: workflows/templates/workflows/integrations_setup.html:236
#: workflows/templates/workflows/integrations_setup.html:307
#: workflows/templates/workflows/welcome_emails.html:87
msgid "Empfänger"
msgstr "Recipients"
#: workflows/templates/workflows/integrations_setup.html:232
#: workflows/templates/workflows/integrations_setup.html:303
#: workflows/templates/workflows/integrations_setup.html:240
#: workflows/templates/workflows/integrations_setup.html:311
msgid "Template Key (optional)"
msgstr "Template key (optional)"
#: workflows/templates/workflows/integrations_setup.html:234
#: workflows/templates/workflows/integrations_setup.html:305
#: workflows/templates/workflows/integrations_setup.html:242
#: workflows/templates/workflows/integrations_setup.html:313
msgid "-- Custom Betreff/Body verwenden --"
msgstr "-- Use custom subject/body --"
#: workflows/templates/workflows/integrations_setup.html:241
#: workflows/templates/workflows/integrations_setup.html:312
#: workflows/templates/workflows/integrations_setup.html:249
#: workflows/templates/workflows/integrations_setup.html:320
msgid "Custom Subject (optional)"
msgstr "Custom subject (optional)"
#: workflows/templates/workflows/integrations_setup.html:245
#: workflows/templates/workflows/integrations_setup.html:316
#: workflows/templates/workflows/integrations_setup.html:253
#: workflows/templates/workflows/integrations_setup.html:324
msgid "Custom Body (optional)"
msgstr "Custom body (optional)"
#: workflows/templates/workflows/integrations_setup.html:249
#: workflows/templates/workflows/integrations_setup.html:320
#: workflows/templates/workflows/integrations_setup.html:257
#: workflows/templates/workflows/integrations_setup.html:328
msgid "Custom Subject (EN, optional)"
msgstr "Custom subject (EN, optional)"
#: workflows/templates/workflows/integrations_setup.html:253
#: workflows/templates/workflows/integrations_setup.html:324
#: workflows/templates/workflows/integrations_setup.html:261
#: workflows/templates/workflows/integrations_setup.html:332
msgid "Custom Body (EN, optional)"
msgstr "Custom body (EN, optional)"
#: workflows/templates/workflows/integrations_setup.html:259
#: workflows/templates/workflows/integrations_setup.html:329
#: workflows/templates/workflows/integrations_setup.html:267
#: workflows/templates/workflows/integrations_setup.html:337
msgid "PDF anhängen"
msgstr "Attach PDF"
#: workflows/templates/workflows/integrations_setup.html:264
#: workflows/templates/workflows/integrations_setup.html:272
msgid "Noch keine zusätzlichen Regeln vorhanden."
msgstr "No additional rules configured yet."
#: workflows/templates/workflows/integrations_setup.html:268
#: workflows/templates/workflows/integrations_setup.html:276
msgid "Neue Regel hinzufügen"
msgstr "Add new rule"
#: workflows/templates/workflows/integrations_setup.html:334
#: workflows/templates/workflows/integrations_setup.html:342
msgid "Regeln speichern"
msgstr "Save rules"
#: workflows/templates/workflows/integrations_setup.html:344
#: workflows/templates/workflows/integrations_setup.html:352
#, fuzzy
#| msgid "Hardware-Übergabetermin"
msgid "Vorlauf Hardware-Übergabe (Tage)"
msgstr "Hardware handover date"
#: workflows/templates/workflows/integrations_setup.html:356
#: workflows/templates/workflows/integrations_setup.html:364
#, fuzzy
#| msgid "Regeln speichern"
msgid "Workflow-Regeln speichern"
msgstr "Save rules"
#: workflows/templates/workflows/integrations_setup.html:358
#: workflows/templates/workflows/integrations_setup.html:366
msgid ""
"Steuert den Mindestvorlauf für das gewünschte Übergabedatum der Geräte im "
"Onboarding-Formular."
@@ -1272,7 +1280,7 @@ msgid "z. B. max.mustermann@tub.co"
msgstr "e.g. john.doe@tub.co"
#: workflows/templates/workflows/offboarding_form.html:33
#: workflows/templates/workflows/requests_dashboard.html:131
#: workflows/templates/workflows/requests_dashboard.html:167
msgid "Suchen"
msgstr "Search"
@@ -1315,7 +1323,7 @@ msgstr ""
#: workflows/templates/workflows/offboarding_success.html:23
#: workflows/templates/workflows/onboarding_success.html:22
#: workflows/templates/workflows/request_timeline.html:104
#: workflows/templates/workflows/requests_dashboard.html:185
#: workflows/templates/workflows/requests_dashboard.html:221
msgid "PDF öffnen"
msgstr "Open PDF"
@@ -1484,7 +1492,7 @@ msgid "Alles zurücksetzen"
msgstr "Reset all"
#: workflows/templates/workflows/onboarding_intro_session.html:90
#: workflows/templates/workflows/requests_dashboard.html:203
#: workflows/templates/workflows/requests_dashboard.html:239
msgid "Live-Protokoll"
msgstr "Live protocol"
@@ -1499,7 +1507,7 @@ msgid "Live-Protokoll erzeugen"
msgstr "Generate live protocol"
#: workflows/templates/workflows/onboarding_intro_session.html:98
#: workflows/templates/workflows/requests_dashboard.html:207
#: workflows/templates/workflows/requests_dashboard.html:243
msgid "Live-Protokoll öffnen"
msgstr "Open live protocol"
@@ -1686,7 +1694,7 @@ msgid "Request Timeline"
msgstr ""
#: workflows/templates/workflows/request_timeline.html:74
#: workflows/templates/workflows/requests_dashboard.html:158
#: workflows/templates/workflows/requests_dashboard.html:194
msgid "E-Mail"
msgstr "Email"
@@ -1779,65 +1787,73 @@ msgstr "%(count)s entries visible"
msgid "Nach Name oder E-Mail suchen"
msgstr "Search by name or email"
#: workflows/templates/workflows/requests_dashboard.html:143
#: workflows/templates/workflows/requests_dashboard.html:158
msgid "Von"
msgstr ""
#: workflows/templates/workflows/requests_dashboard.html:162
msgid "Bis"
msgstr ""
#: workflows/templates/workflows/requests_dashboard.html:179
#: workflows/templates/workflows/welcome_emails.html:78
msgid "ausgewählt"
msgstr "selected"
#: workflows/templates/workflows/requests_dashboard.html:144
#: workflows/templates/workflows/requests_dashboard.html:180
msgid "Auswahl löschen"
msgstr "Delete selection"
#: workflows/templates/workflows/requests_dashboard.html:157
#: workflows/templates/workflows/requests_dashboard.html:193
msgid "Person"
msgstr "Person"
#: workflows/templates/workflows/requests_dashboard.html:159
#: workflows/templates/workflows/requests_dashboard.html:195
msgid "Dokument"
msgstr "Document"
#: workflows/templates/workflows/requests_dashboard.html:160
#: workflows/templates/workflows/requests_dashboard.html:200
#: workflows/templates/workflows/requests_dashboard.html:196
#: workflows/templates/workflows/requests_dashboard.html:236
msgid "Einweisung"
msgstr "Introduction"
#: workflows/templates/workflows/requests_dashboard.html:187
#: workflows/templates/workflows/requests_dashboard.html:223
msgid "Noch nicht verfügbar"
msgstr "Not available yet"
#: workflows/templates/workflows/requests_dashboard.html:205
#: workflows/templates/workflows/requests_dashboard.html:241
msgid "Einweisung öffnen"
msgstr "Open introduction"
#: workflows/templates/workflows/requests_dashboard.html:212
#: workflows/templates/workflows/requests_dashboard.html:248
msgid "Standard-Einweisungs-PDF"
msgstr "Standard introduction PDF"
#: workflows/templates/workflows/requests_dashboard.html:217
#: workflows/templates/workflows/requests_dashboard.html:253
msgid "Neu erzeugen"
msgstr "Regenerate"
#: workflows/templates/workflows/requests_dashboard.html:219
#: workflows/templates/workflows/requests_dashboard.html:255
msgid "Standard-PDF öffnen"
msgstr "Open standard PDF"
#: workflows/templates/workflows/requests_dashboard.html:223
#: workflows/templates/workflows/requests_dashboard.html:259
msgid "PDF erzeugen"
msgstr "Generate PDF"
#: workflows/templates/workflows/requests_dashboard.html:234
#: workflows/templates/workflows/requests_dashboard.html:270
msgid "Nicht relevant"
msgstr "Not relevant"
#: workflows/templates/workflows/requests_dashboard.html:238
#: workflows/templates/workflows/requests_dashboard.html:274
msgid "Timeline"
msgstr ""
#: workflows/templates/workflows/requests_dashboard.html:242
#: workflows/templates/workflows/requests_dashboard.html:278
msgid "Erneut versuchen"
msgstr ""
#: workflows/templates/workflows/requests_dashboard.html:254
#: workflows/templates/workflows/requests_dashboard.html:290
msgid "Noch keine Vorgänge vorhanden."
msgstr "No requests available yet."
@@ -2179,23 +2195,23 @@ msgstr "%(count)s selection(s) could not be processed."
msgid "Keine passenden Einträge gefunden."
msgstr "No matching entries found."
#: workflows/views.py:726
#: workflows/views.py:776
msgid "Einweisungs- und Übergabeprotokoll wurde erzeugt."
msgstr "Introduction and handover protocol was generated."
#: workflows/views.py:744
#: workflows/views.py:794
msgid "Einweisungsprotokoll aus Live-Status wurde erzeugt."
msgstr "Introduction protocol from live status was generated."
#: workflows/views.py:774
#: workflows/views.py:824
msgid "Einweisung wurde zurückgesetzt."
msgstr "Introduction was reset."
#: workflows/views.py:788
#: workflows/views.py:838
msgid "Einweisung wurde als abgeschlossen gespeichert."
msgstr "Introduction was saved as completed."
#: workflows/views.py:801
#: workflows/views.py:851
msgid "Einweisung wurde als Entwurf gespeichert."
msgstr "Introduction was saved as draft."

View File

@@ -425,18 +425,37 @@
.search-form {
display: grid;
gap: 12px;
gap: 10px;
}
.filter-grid {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 8px;
}
.filter-field {
display: grid;
gap: 4px;
}
.filter-field label {
font-size: 11px;
font-weight: 800;
color: #294465;
}
.search-box {
position: relative;
}
.search-box input {
.search-box input,
.filter-field select,
.filter-field input[type="date"] {
width: 100%;
border: 1px solid var(--line-strong);
border-radius: 16px;
padding: 14px 16px;
border-radius: 14px;
padding: 11px 13px;
font: inherit;
font-weight: 600;
color: var(--ink);
@@ -444,7 +463,9 @@
box-shadow: inset 0 1px 0 rgba(255,255,255,0.98);
}
.search-box input:focus {
.search-box input:focus,
.filter-field select:focus,
.filter-field input[type="date"]:focus {
outline: none;
border-color: rgba(0, 0, 120, 0.3);
box-shadow: 0 0 0 4px rgba(0, 0, 120, 0.08);
@@ -488,7 +509,7 @@
}
.table-controls {
padding: 14px 18px 14px;
padding: 12px 18px 12px;
border-bottom: 1px solid var(--line);
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(244,248,255,0.96));
}
@@ -496,16 +517,16 @@
.table-controls-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 14px;
gap: 10px;
align-items: stretch;
}
.control-stack {
display: grid;
gap: 12px;
padding: 14px;
gap: 10px;
padding: 12px;
border: 1px solid rgba(217, 227, 238, 0.95);
border-radius: 18px;
border-radius: 16px;
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(249,251,255,0.95));
box-shadow: inset 0 1px 0 rgba(255,255,255,0.9);
}
@@ -848,6 +869,10 @@
.table-controls-grid {
grid-template-columns: 1fr;
}
.filter-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 760px) {
@@ -860,4 +885,5 @@
.topbar { flex-direction: column; }
.quick-actions { justify-content: flex-start; }
.table-wrap { padding-left: 12px; padding-right: 12px; }
.filter-grid { grid-template-columns: 1fr; }
}

View File

@@ -1,4 +1,34 @@
(function () {
const filterForm = document.querySelector('.search-form');
if (filterForm) {
const searchInput = filterForm.querySelector('input[name="q"]');
const immediateFields = Array.from(
filterForm.querySelectorAll('select[name], input[type="date"][name]')
);
let debounceTimer = null;
const submitFilters = function () {
if (debounceTimer) {
window.clearTimeout(debounceTimer);
debounceTimer = null;
}
filterForm.requestSubmit();
};
if (searchInput) {
searchInput.addEventListener('input', function () {
if (debounceTimer) {
window.clearTimeout(debounceTimer);
}
debounceTimer = window.setTimeout(submitFilters, 280);
});
}
immediateFields.forEach(function (field) {
field.addEventListener('change', submitFilters);
});
}
const selectAll = document.getElementById('select-all');
const rowChecks = Array.from(document.querySelectorAll('.row-select'));
const selectedCount = document.getElementById('selected-count');

View File

@@ -112,7 +112,7 @@
{% endif %}
<section class="content-grid">
<section class="table-card">
<section class="table-card" id="vorgaenge">
<div class="table-head">
<div>
<h2>{% trans "Vorgänge" %}</h2>
@@ -123,14 +123,50 @@
<div class="table-controls">
<div class="table-controls-grid">
<div class="control-stack">
<form method="get" action="/requests/" class="search-form">
<form method="get" action="/requests/#vorgaenge" class="search-form">
<div class="search-box">
<input type="search" name="q" value="{{ search_query }}" placeholder="{% trans "Nach Name oder E-Mail suchen" %}" aria-label="{% trans "Nach Name oder E-Mail suchen" %}" />
</div>
<div class="filter-grid">
<div class="filter-field">
<label for="type-filter">{% trans "Typ" %}</label>
<select id="type-filter" name="type">
<option value="">{% trans "Alle" %}</option>
<option value="onboarding" {% if selected_type == 'onboarding' %}selected{% endif %}>{% trans "Onboarding" %}</option>
<option value="offboarding" {% if selected_type == 'offboarding' %}selected{% endif %}>{% trans "Offboarding" %}</option>
</select>
</div>
<div class="filter-field">
<label for="status-filter">{% trans "Status" %}</label>
<select id="status-filter" name="status">
<option value="">{% trans "Alle" %}</option>
{% for choice in status_choices %}
<option value="{{ choice.value }}" {% if selected_status == choice.value %}selected{% endif %}>{{ choice.label }}</option>
{% endfor %}
</select>
</div>
<div class="filter-field">
<label for="department-filter">{% trans "Abteilung" %}</label>
<select id="department-filter" name="department">
<option value="">{% trans "Alle" %}</option>
{% for department in departments %}
<option value="{{ department }}" {% if selected_department == department %}selected{% endif %}>{{ department }}</option>
{% endfor %}
</select>
</div>
<div class="filter-field">
<label for="date-from-filter">{% trans "Von" %}</label>
<input id="date-from-filter" type="date" name="date_from" value="{{ date_from }}" />
</div>
<div class="filter-field">
<label for="date-to-filter">{% trans "Bis" %}</label>
<input id="date-to-filter" type="date" name="date_to" value="{{ date_to }}" />
</div>
</div>
<div class="intro-actions">
<button class="btn btn-primary" type="submit">{% trans "Suchen" %}</button>
{% if search_query %}
<a class="btn btn-secondary" href="/requests/">{% trans "Zurücksetzen" %}</a>
{% if has_filters %}
<a class="btn btn-secondary" href="/requests/#vorgaenge">{% trans "Zurücksetzen" %}</a>
{% endif %}
</div>
</form>

View File

@@ -557,11 +557,37 @@ def requests_dashboard(request):
return redirect('requests_dashboard')
search_query = request.GET.get('q', '').strip()
type_filter = (request.GET.get('type') or '').strip().lower()
status_filter = (request.GET.get('status') or '').strip().lower()
department_filter = (request.GET.get('department') or '').strip()
date_from = (request.GET.get('date_from') or '').strip()
date_to = (request.GET.get('date_to') or '').strip()
onboarding_qs = OnboardingRequest.objects.order_by('-created_at')
offboarding_qs = OffboardingRequest.objects.order_by('-created_at')
all_onboarding = OnboardingRequest.objects.all()
all_offboarding = OffboardingRequest.objects.all()
if search_query:
onboarding_qs = onboarding_qs.filter(Q(full_name__icontains=search_query) | Q(work_email__icontains=search_query))
offboarding_qs = offboarding_qs.filter(Q(full_name__icontains=search_query) | Q(work_email__icontains=search_query))
if status_filter in {'submitted', 'processing', 'completed', 'failed'}:
onboarding_qs = onboarding_qs.filter(processing_status=status_filter)
offboarding_qs = offboarding_qs.filter(processing_status=status_filter)
if department_filter:
onboarding_qs = onboarding_qs.filter(department=department_filter)
offboarding_qs = offboarding_qs.filter(department=department_filter)
if date_from:
onboarding_qs = onboarding_qs.filter(created_at__date__gte=date_from)
offboarding_qs = offboarding_qs.filter(created_at__date__gte=date_from)
if date_to:
onboarding_qs = onboarding_qs.filter(created_at__date__lte=date_to)
offboarding_qs = offboarding_qs.filter(created_at__date__lte=date_to)
if type_filter == 'onboarding':
offboarding_qs = offboarding_qs.none()
elif type_filter == 'offboarding':
onboarding_qs = onboarding_qs.none()
onboarding_items = onboarding_qs[:50]
offboarding_items = offboarding_qs[:50]
@@ -649,12 +675,36 @@ def requests_dashboard(request):
onboarding_total = onboarding_qs.count()
offboarding_total = offboarding_qs.count()
departments = sorted(
{
value.strip()
for value in list(all_onboarding.exclude(department='').values_list('department', flat=True))
+ list(all_offboarding.exclude(department='').values_list('department', flat=True))
if value and value.strip()
},
key=str.lower,
)
status_choices = [
{'value': 'submitted', 'label': _request_status_label('submitted', language_code)},
{'value': 'processing', 'label': _request_status_label('processing', language_code)},
{'value': 'completed', 'label': _request_status_label('completed', language_code)},
{'value': 'failed', 'label': _request_status_label('failed', language_code)},
]
has_filters = any([search_query, type_filter, status_filter, department_filter, date_from, date_to])
return render(
request,
'workflows/requests_dashboard.html',
{
'rows': rows[:60],
'search_query': search_query,
'selected_type': type_filter,
'selected_status': status_filter,
'selected_department': department_filter,
'date_from': date_from,
'date_to': date_to,
'departments': departments,
'status_choices': status_choices,
'has_filters': has_filters,
'onboarding_total': onboarding_total,
'offboarding_total': offboarding_total,
'combined_total': onboarding_total + offboarding_total,