diff --git a/db.sqlite3 b/db.sqlite3 index f3537cd..f118960 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index bc95570..710cf37 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 3f16f2b..fcd72b8 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: wira-risk-management\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-10 13:44+0200\n" +"POT-Creation-Date: 2025-09-11 10:17+0200\n" "PO-Revision-Date: 2025-09-09 13:45+0200\n" "Last-Translator: Kevin Heyer \n" "Language-Team: German\n" @@ -22,12 +22,12 @@ msgstr "Admin" #: risks/admin.py:15 risks/models.py:36 templates/risks/dashboard.html:75 #: templates/risks/dashboard.html:80 templates/risks/dashboard.html:85 -#: templates/risks/list_risks.html:76 +#: templates/risks/list_risks.html:97 msgid "Risks" msgstr "Risiken" -#: risks/admin.py:16 risks/models.py:190 templates/base.html:36 -#: templates/risks/list_risks.html:37 +#: risks/admin.py:16 risks/models.py:190 templates/base.html:38 +#: templates/risks/list_risks.html:31 msgid "Controls" msgstr "Maßnahmen" @@ -39,8 +39,8 @@ msgstr "Restrisiken" msgid "Reviews" msgstr "Prüfung" -#: risks/admin.py:19 risks/models.py:258 templates/base.html:37 -#: templates/risks/item_risk.html:248 +#: risks/admin.py:19 risks/models.py:258 templates/base.html:39 +#: templates/risks/item_risk.html:252 msgid "Incidents" msgstr "Vorfälle" @@ -48,13 +48,13 @@ msgstr "Vorfälle" msgid "Users" msgstr "Benutzer" -#: risks/admin.py:133 risks/models.py:302 templates/risks/item_risk.html:287 +#: risks/admin.py:133 risks/models.py:326 templates/risks/item_risk.html:291 msgid "User" msgstr "Benutzer" #: risks/admin.py:139 msgid "Message" -msgstr "" +msgstr "Nachricht" #: risks/admin.py:147 msgid "Mark selected as read" @@ -76,9 +76,10 @@ msgstr "%(n)d Benachrichtigungen wurden als ungelesen Markiert" #: risks/admin.py:157 msgid "Mark selected as sent" -msgstr "" +msgstr "Auswahl als gelesen markieren" #: risks/admin.py:160 +#, python-format msgid "%(n)d notifications marked as sent." msgstr "%(n)d Benachrichtigungen wurden als gelesen Markiert" @@ -87,18 +88,23 @@ msgid "Mark selected as unsent" msgstr "Auswahl als ungesendet markieren" #: risks/admin.py:165 +#, python-format msgid "%(n)d notifications marked as unsent." msgstr "%(n)d Benachrichtigungen wurden als gelesen Markiert" -#: risks/admin.py:177 +#: risks/admin.py:182 +msgid "Extra recipients" +msgstr "Zusätzliche Empfänger" + +#: risks/admin.py:190 msgid "SSO Information" msgstr "SSO-Informationen" -#: risks/admin.py:186 +#: risks/admin.py:199 msgid "Risks Owned" msgstr "Eigene Risiken" -#: risks/admin.py:190 +#: risks/admin.py:203 msgid "Controls Responsible" msgstr "Verantwortlich für Maßnahmen" @@ -107,17 +113,17 @@ msgid "Risk Management" msgstr "Risikomanagement" #: risks/forms.py:9 risks/forms.py:16 risks/forms.py:23 risks/models.py:73 -#: templates/risks/item_risk.html:64 templates/risks/item_risk.html:202 -#: templates/risks/item_risk.html:256 +#: templates/risks/item_risk.html:64 templates/risks/item_risk.html:206 +#: templates/risks/item_risk.html:260 msgid "Status" msgstr "Status" -#: risks/forms.py:30 risks/models.py:42 templates/risks/item_risk.html:177 +#: risks/forms.py:30 risks/models.py:42 templates/risks/item_risk.html:181 msgid "Review required" msgstr "Prüfung nötig" #: risks/models.py:35 templates/risks/item_risk.html:11 -#: templates/risks/list_risks.html:18 templates/risks/list_risks.html:83 +#: templates/risks/list_risks.html:18 templates/risks/list_risks.html:110 msgid "Risk" msgstr "Risiko" @@ -182,7 +188,7 @@ msgid "Availability" msgstr "Verfügbarkeit" #: risks/models.py:64 risks/models.py:200 risks/models.py:265 -#: templates/risks/item_risk.html:201 +#: templates/risks/item_risk.html:205 msgid "Title" msgstr "Titel" @@ -191,15 +197,17 @@ msgid "Description" msgstr "Beschreibung" #: risks/models.py:66 templates/risks/item_risk.html:53 +#: templates/risks/list_risks.html:57 msgid "Asset" msgstr "Asset" #: risks/models.py:67 templates/risks/item_risk.html:54 +#: templates/risks/list_risks.html:70 msgid "Process" msgstr "Prozess" #: risks/models.py:68 templates/risks/item_risk.html:55 -#: templates/risks/list_risks.html:85 +#: templates/risks/list_risks.html:44 templates/risks/list_risks.html:112 msgid "Category" msgstr "Kategorie" @@ -211,6 +219,10 @@ msgstr "Erstellt am" msgid "Updated at" msgstr "Aktualisiert am" +#: risks/models.py:71 +msgid "Effects" +msgstr "Auswirkungen" + #: risks/models.py:133 msgid "Residual Risk" msgstr "Restrisiko" @@ -251,7 +263,7 @@ msgstr "Audit-Log" msgid "Auditlogs" msgstr "Audit-Logs" -#: risks/models.py:257 templates/risks/item_risk.html:255 +#: risks/models.py:257 templates/risks/item_risk.html:259 msgid "Incident" msgstr "Vorfall" @@ -267,15 +279,120 @@ msgstr "Meldedatum" msgid "Reported by" msgstr "Gemeldet von" -#: risks/models.py:279 +#: risks/models.py:279 risks/utils.py:119 msgid "Notification" msgstr "Benachrichtigung" -#: risks/models.py:280 templates/base.html:78 +#: risks/models.py:280 templates/base.html:80 #: templates/risks/notifications.html:4 msgid "Notifications" msgstr "Nachrichten" +#: risks/models.py:295 +msgid "Risk created" +msgstr "Risiko erstellt" + +#: risks/models.py:296 +msgid "Risk updated" +msgstr "Risiko Aktualisiert" + +#: risks/models.py:297 +msgid "Risk deleted" +msgstr "Risiko gelöscht" + +#: risks/models.py:298 +msgid "Risk review required" +msgstr "Risikoprüfung nötig" + +#: risks/models.py:299 +msgid "Risk review completed" +msgstr "Risikoprüfung Abgeschlossen" + +#: risks/models.py:301 +msgid "Control created" +msgstr "Maßnahme erstellt" + +#: risks/models.py:302 +msgid "Control updated" +msgstr "Maßnahme Aktualisiert" + +#: risks/models.py:303 +msgid "Control deleted" +msgstr "Maßnahme '{title}' gelöscht" + +#: risks/models.py:305 +msgid "Residual created" +msgstr "Restrisiko erstellt" + +#: risks/models.py:306 +msgid "Residual updated" +msgstr "Restrisiko Aktualisiert" + +#: risks/models.py:307 +msgid "Residual deleted" +msgstr "Restrisiko gelöscht" + +#: risks/models.py:308 +msgid "Residual review required" +msgstr "Restrisikoprüfung nötig" + +#: risks/models.py:309 +msgid "Residual review completed" +msgstr "Restrisiko geprüft" + +#: risks/models.py:311 +msgid "Incident created" +msgstr "Vorfall erstellt" + +#: risks/models.py:312 +msgid "Incident updated" +msgstr "Vorfall Aktualisiert" + +#: risks/models.py:313 +msgid "Incident deleted" +msgstr "Vorfall gelöscht" + +#: risks/models.py:315 +msgid "User created" +msgstr "Benutzer erstellt" + +#: risks/models.py:316 +msgid "User deleted" +msgstr "Benutzer gelöscht" + +#: risks/models.py:371 +msgid "Notification rule" +msgstr "Benachrichtigungsregel" + +#: risks/models.py:372 +msgid "Notification rules" +msgstr "Benachrichtigungsregeln" + +#: risks/models.py:375 +msgid "Event" +msgstr "Aktion" + +#: risks/models.py:380 +msgid "Show in app" +msgstr "Zeige in der WebApp" + +#: risks/models.py:381 +msgid "Send via email" +msgstr "Sende via E-Mail" + +#: risks/models.py:385 +msgid "Send to owner/responsible/reporter (if available)" +msgstr "Sende an Risikoeigner/Verantwortliche/Melder (Wenn vorhanden)" + +#: risks/models.py:389 +msgid "Send to all staff" +msgstr "Sende an alle App-Mitarbeiter" + +#: risks/models.py:393 +msgid "Extra recipients (emails, comma or newline separated)" +msgstr "" +"Zusätzliche Empfänger (E-Mails, durch Komma oder Zeilenumbruch getrennt)" + #: risks/signals.py:57 #, python-brace-format msgid "User '{u}' created" @@ -291,13 +408,13 @@ msgstr "Benutzer '{u}' löschte" msgid "Risk '{title}' {state}" msgstr "Risiko '{title}' {state}" -#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240 -#: risks/signals.py:296 +#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212 +#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411 msgid "created" msgstr "erstellt" -#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240 -#: risks/signals.py:296 +#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212 +#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411 msgid "updated" msgstr "Aktualisiert" @@ -306,77 +423,137 @@ msgstr "Aktualisiert" msgid "Risk '{title}' deleted" msgstr "Risiko '{title}' gelöscht" -#: risks/signals.py:145 +#: risks/signals.py:117 +#, python-brace-format +msgid "Risk created: {t}" +msgstr "Risiko erstellt: {t}" + +#: risks/signals.py:123 +#, python-brace-format +msgid "Risk updated: {t}" +msgstr "Risiko Aktualisiert: {t}" + +#: risks/signals.py:143 +#, python-brace-format +msgid "Risk deleted: {t}" +msgstr "Risiko gelöscht: {t}" + +#: risks/signals.py:164 #, python-brace-format msgid "Control '{title}' {state}" msgstr "Maßnahme '{title}' {state}" -#: risks/signals.py:154 +#: risks/signals.py:173 #, python-brace-format msgid "Control '{title}' deleted" msgstr "Maßnahme '{title}' gelöscht" #: risks/signals.py:211 #, python-brace-format +msgid "Control {event}: {t}" +msgstr "Maßnahme {event}: {t}" + +#: risks/signals.py:231 +#, python-brace-format +msgid "Control deleted: {t}" +msgstr "Maßnahme gelöscht: {t}" + +#: risks/signals.py:246 +#, python-brace-format msgid "Review required for risk '{t}' due to control change" msgstr "Prüfung nötig für: '{t}', da Maßnahmen geändert wurden" -#: risks/signals.py:230 +#: risks/signals.py:265 #, python-brace-format msgid "Review required for risk '{t}'" msgstr "Prüfung benötigt für Risiko '{t}'" -#: risks/signals.py:235 +#: risks/signals.py:270 #, python-brace-format msgid "Review completed for risk '{t}'" msgstr "Prüfung Abgeschlossen für Risiko '{t}'" -#: risks/signals.py:239 +#: risks/signals.py:274 #, python-brace-format msgid "Residual risk {state} for '{t}'" msgstr "Restrisiko {state} für '{t}'" -#: risks/signals.py:244 +#: risks/signals.py:279 #, python-brace-format msgid "Residual risk deleted for '{t}'" msgstr "Restrisiko für '{t}' gelöscht" -#: risks/signals.py:296 +#: risks/signals.py:316 +#, python-brace-format +msgid "Residual created for risk: {t}" +msgstr "Restrisiko erstellt für das Risiko: {t}" + +#: risks/signals.py:328 +#, python-brace-format +msgid "Residual review required for risk: {t}" +msgstr "Restrisikoprüfung benötigt für Risiko {t}" + +#: risks/signals.py:334 +#, python-brace-format +msgid "Residual review completed for risk: {t}" +msgstr "Restrisikoprüfung Abgeschlossen für Risiko {t}" + +#: risks/signals.py:340 +#, python-brace-format +msgid "Residual updated for risk: {t}" +msgstr "Restrisiko Aktualisiert für das Risiko: {t}" + +#: risks/signals.py:358 +#, python-brace-format +msgid "Residual deleted for risk: {t}" +msgstr "Restrisiko gelöscht für das Risiko: {t}" + +#: risks/signals.py:369 #, python-brace-format msgid "Incident '{t}' {s}" -msgstr "Vorfälle '{t}' {s}" +msgstr "Vorfall '{t}' {s}" -#: risks/signals.py:301 +#: risks/signals.py:374 #, python-brace-format msgid "Incident '{t}' deleted" msgstr "Vorfall '{t}' gelöscht" -#: risks/utils.py:48 +#: risks/signals.py:410 +#, python-brace-format +msgid "Incident {event}: {t}" +msgstr "Vorfall {event}: {t}" + +#: risks/signals.py:442 +#, python-brace-format +msgid "Incident deleted: {t}" +msgstr "Vorfall gelöscht: {t}" + +#: risks/utils.py:53 risks/utils.py:67 #, python-brace-format msgid "Follow-up reached: review required for risk '{t}'" msgstr "Wiedervorlagedatum erreicht: Prüfung nötig für Risiko '{t}'" -#: risks/views.py:315 +#: risks/views.py:345 msgid "Notification marked as read." msgstr "Nachricht als gelesen markiert" -#: risks/views.py:323 +#: risks/views.py:353 msgid "All notifications marked as read." msgstr "Alle Benachrichtigungen wurden als gelesen Markiert" -#: risks/views.py:340 +#: risks/views.py:370 msgid "Risk status updated." msgstr "Risikostatus Aktualisiert" -#: risks/views.py:354 +#: risks/views.py:384 msgid "Control status updated." msgstr "Maßnahmenstatus Aktualisiert" -#: risks/views.py:368 +#: risks/views.py:398 msgid "Incident status updated." msgstr "Vorfallstatus Aktualisiert" -#: risks/views.py:384 +#: risks/views.py:414 msgid "Residual review flag updated." msgstr "Restrisiko geprüft" @@ -384,32 +561,37 @@ msgstr "Restrisiko geprüft" msgid "Dashboard" msgstr "Dashboard" -#: templates/base.html:35 templates/risks/item_risk.html:4 +#: templates/base.html:35 templates/risks/risk_matrix.html:4 +#: templates/risks/risk_matrix.html:12 templates/risks/risk_matrix.html:18 +msgid "Risk Matrix" +msgstr "Risikomatrix" + +#: templates/base.html:37 templates/risks/item_risk.html:4 #: templates/risks/list_risks.html:4 msgid "Risk analysis" msgstr "Risikoanalyse" -#: templates/base.html:73 +#: templates/base.html:75 msgid "AdminCP" msgstr "Adminbereich" -#: templates/base.html:86 +#: templates/base.html:88 msgid "Derk Mode" msgstr "Dark Mode" -#: templates/base.html:92 +#: templates/base.html:94 msgid "Logout" msgstr "Logout" -#: templates/base.html:107 +#: templates/base.html:109 msgid "Login" msgstr "Login" -#: templates/base.html:142 templates/base.html:149 +#: templates/base.html:144 templates/base.html:151 msgid "Light Mode" msgstr "Light Mode" -#: templates/base.html:152 +#: templates/base.html:154 msgid "Dark Mode" msgstr "Dark Mode" @@ -471,99 +653,100 @@ msgstr "Aktualisiert am" msgid "Resubmission" msgstr "Wiedervorlagedatum" -#: templates/risks/item_risk.html:76 +#: templates/risks/item_risk.html:80 msgid "Risk assessment" msgstr "Risikomanagement" -#: templates/risks/item_risk.html:84 +#: templates/risks/item_risk.html:88 msgid "Gross (before measures)" msgstr "Brutto (vor Maßnahmen)" -#: templates/risks/item_risk.html:89 templates/risks/item_risk.html:135 -#: templates/risks/list_risks.html:86 +#: templates/risks/item_risk.html:93 templates/risks/item_risk.html:139 +#: templates/risks/list_risks.html:118 templates/risks/list_risks.html:122 +#: templates/risks/risk_matrix.html:25 msgid "Likelihood" msgstr "Eintritt" -#: templates/risks/item_risk.html:90 templates/risks/item_risk.html:136 +#: templates/risks/item_risk.html:94 templates/risks/item_risk.html:140 msgid "Probability of occurrence" msgstr "Eintrittswahrscheinlichkeit" -#: templates/risks/item_risk.html:98 templates/risks/item_risk.html:144 -#: templates/risks/list_risks.html:87 +#: templates/risks/item_risk.html:102 templates/risks/item_risk.html:148 +#: templates/risks/list_risks.html:119 templates/risks/list_risks.html:123 +#: templates/risks/risk_matrix.html:25 msgid "Impact" msgstr "Schaden" -#: templates/risks/item_risk.html:99 templates/risks/item_risk.html:145 +#: templates/risks/item_risk.html:103 templates/risks/item_risk.html:149 msgid "Extent of damage" msgstr "Schadensausmaß" -#: templates/risks/item_risk.html:107 templates/risks/item_risk.html:108 -#: templates/risks/item_risk.html:153 templates/risks/item_risk.html:154 -#: templates/risks/list_risks.html:89 +#: templates/risks/item_risk.html:111 templates/risks/item_risk.html:112 +#: templates/risks/item_risk.html:157 templates/risks/item_risk.html:158 +#: templates/risks/list_risks.html:121 templates/risks/list_risks.html:125 msgid "Level" msgstr "Stufe" -#: templates/risks/item_risk.html:116 templates/risks/item_risk.html:117 -#: templates/risks/item_risk.html:161 templates/risks/item_risk.html:163 -#: templates/risks/list_risks.html:88 +#: templates/risks/item_risk.html:120 templates/risks/item_risk.html:121 +#: templates/risks/item_risk.html:165 templates/risks/item_risk.html:167 +#: templates/risks/list_risks.html:120 templates/risks/list_risks.html:124 +#: templates/risks/risk_matrix.html:39 msgid "Score" msgstr "Score" -#: templates/risks/item_risk.html:130 +#: templates/risks/item_risk.html:134 msgid "Net (after measures)" msgstr "Netto (nach Maßnahmen)" -#: templates/risks/item_risk.html:169 +#: templates/risks/item_risk.html:173 msgid "No net risk recorded yet." msgstr "Kein Restrisiko vergeben" -#: templates/risks/item_risk.html:180 +#: templates/risks/item_risk.html:184 msgid "Save" msgstr "Speichern" -#: templates/risks/item_risk.html:194 +#: templates/risks/item_risk.html:198 msgid "Measures" msgstr "Maßnahmen" -#: templates/risks/item_risk.html:203 +#: templates/risks/item_risk.html:207 msgid "Deadline" msgstr "Frist" -#: templates/risks/item_risk.html:204 +#: templates/risks/item_risk.html:208 msgid "Responsible" msgstr "Verantwortliche/r" -#: templates/risks/item_risk.html:205 +#: templates/risks/item_risk.html:209 msgid "Link" msgstr "Link" -#: templates/risks/item_risk.html:239 +#: templates/risks/item_risk.html:243 msgid "No measures recorded." msgstr "Keine Maßnahmen gefunden." -#: templates/risks/item_risk.html:257 -#, fuzzy -#| msgid "Reported by" +#: templates/risks/item_risk.html:261 msgid "Reported on" -msgstr "Gemeldet von" +msgstr "Gemeldet am" -#: templates/risks/item_risk.html:271 +#: templates/risks/item_risk.html:275 msgid "No incidents recorded." msgstr "Keine Vorfälle gefunden." -#: templates/risks/item_risk.html:279 +#: templates/risks/item_risk.html:283 msgid "History" msgstr "" -#: templates/risks/item_risk.html:286 +#: templates/risks/item_risk.html:290 msgid "Time" msgstr "Zeitpunkt" -#: templates/risks/item_risk.html:288 +#: templates/risks/item_risk.html:292 msgid "Action" msgstr "Aktion" -#: templates/risks/item_risk.html:302 +#: templates/risks/item_risk.html:306 msgid "No History found." msgstr "Keine Historie vorhanden" @@ -571,20 +754,33 @@ msgstr "Keine Historie vorhanden" msgid "Filter" msgstr "Filter" -#: templates/risks/list_risks.html:22 templates/risks/list_risks.html:41 -#: templates/risks/list_risks.html:60 templates/risks/notifications.html:13 -msgid "All" -msgstr "Alle" - -#: templates/risks/list_risks.html:56 templates/risks/list_risks.html:90 -msgid "Risk Owner" +#: templates/risks/list_risks.html:83 +#, fuzzy +#| msgid "Risk Owner" +msgid "Owner" msgstr "Risikoeigner" -#: templates/risks/list_risks.html:84 +#: templates/risks/list_risks.html:111 msgid "Asset / Process" msgstr "Asset / Prozess" -#: templates/risks/list_risks.html:152 +#: templates/risks/list_risks.html:113 +msgid "Risk Owner" +msgstr "Risikoeigner" + +#: templates/risks/list_risks.html:114 +msgid "Gross Risk" +msgstr "Bruttorisiko" + +#: templates/risks/list_risks.html:115 +msgid "Net Risk" +msgstr "Nettorisiko" + +#: templates/risks/list_risks.html:195 +msgid "No residual risk defined" +msgstr "Noch kein Restrisiko definiert" + +#: templates/risks/list_risks.html:201 msgid "No risks present" msgstr "Aktuell keine Risiken" @@ -592,6 +788,10 @@ msgstr "Aktuell keine Risiken" msgid "Unread" msgstr "Ungelesen" +#: templates/risks/notifications.html:13 +msgid "All" +msgstr "Alle" + #: templates/risks/notifications.html:20 msgid "Mark all as read" msgstr "Alle als gelesen Markieren" @@ -607,3 +807,23 @@ msgstr "Als gelesen markieren" #: templates/risks/notifications.html:53 msgid "No notifications." msgstr "Keine Nachrichten" + +#: templates/risks/risk_matrix.html:13 +msgid "Detail View" +msgstr "Detailansicht" + +#: templates/risks/risk_matrix.html:54 +msgid "Show" +msgstr "Zeige" + +#: templates/risks/risk_matrix.html:58 +msgid "Gross" +msgstr "Brutto" + +#: templates/risks/risk_matrix.html:61 +msgid "Net" +msgstr "Netto" + +#: templates/risks/risk_matrix.html:73 templates/risks/risk_matrix.html:115 +msgid "Impact \\\\ Likelihood" +msgstr "Schadensausmaß \\\\ Eintrittswahrscheinlichkeit" diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index d06e20b..bde0ace 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-10 13:44+0200\n" +"POT-Creation-Date: 2025-09-11 10:17+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -28,12 +28,12 @@ msgstr "" #: risks/admin.py:15 risks/models.py:36 templates/risks/dashboard.html:75 #: templates/risks/dashboard.html:80 templates/risks/dashboard.html:85 -#: templates/risks/list_risks.html:76 +#: templates/risks/list_risks.html:97 msgid "Risks" msgstr "" -#: risks/admin.py:16 risks/models.py:190 templates/base.html:36 -#: templates/risks/list_risks.html:37 +#: risks/admin.py:16 risks/models.py:190 templates/base.html:38 +#: templates/risks/list_risks.html:31 msgid "Controls" msgstr "" @@ -45,8 +45,8 @@ msgstr "" msgid "Reviews" msgstr "" -#: risks/admin.py:19 risks/models.py:258 templates/base.html:37 -#: templates/risks/item_risk.html:248 +#: risks/admin.py:19 risks/models.py:258 templates/base.html:39 +#: templates/risks/item_risk.html:252 msgid "Incidents" msgstr "" @@ -54,7 +54,7 @@ msgstr "" msgid "Users" msgstr "" -#: risks/admin.py:133 risks/models.py:302 templates/risks/item_risk.html:287 +#: risks/admin.py:133 risks/models.py:326 templates/risks/item_risk.html:291 msgid "User" msgstr "" @@ -98,15 +98,19 @@ msgstr "" msgid "%(n)d notifications marked as unsent." msgstr "" -#: risks/admin.py:177 -msgid "SSO Information" -msgstr "" - -#: risks/admin.py:186 -msgid "Risks Owned" +#: risks/admin.py:182 +msgid "Extra recipients" msgstr "" #: risks/admin.py:190 +msgid "SSO Information" +msgstr "" + +#: risks/admin.py:199 +msgid "Risks Owned" +msgstr "" + +#: risks/admin.py:203 msgid "Controls Responsible" msgstr "" @@ -115,17 +119,17 @@ msgid "Risk Management" msgstr "" #: risks/forms.py:9 risks/forms.py:16 risks/forms.py:23 risks/models.py:73 -#: templates/risks/item_risk.html:64 templates/risks/item_risk.html:202 -#: templates/risks/item_risk.html:256 +#: templates/risks/item_risk.html:64 templates/risks/item_risk.html:206 +#: templates/risks/item_risk.html:260 msgid "Status" msgstr "" -#: risks/forms.py:30 risks/models.py:42 templates/risks/item_risk.html:177 +#: risks/forms.py:30 risks/models.py:42 templates/risks/item_risk.html:181 msgid "Review required" msgstr "" #: risks/models.py:35 templates/risks/item_risk.html:11 -#: templates/risks/list_risks.html:18 templates/risks/list_risks.html:83 +#: templates/risks/list_risks.html:18 templates/risks/list_risks.html:110 msgid "Risk" msgstr "" @@ -190,7 +194,7 @@ msgid "Availability" msgstr "" #: risks/models.py:64 risks/models.py:200 risks/models.py:265 -#: templates/risks/item_risk.html:201 +#: templates/risks/item_risk.html:205 msgid "Title" msgstr "" @@ -199,15 +203,17 @@ msgid "Description" msgstr "" #: risks/models.py:66 templates/risks/item_risk.html:53 +#: templates/risks/list_risks.html:57 msgid "Asset" msgstr "" #: risks/models.py:67 templates/risks/item_risk.html:54 +#: templates/risks/list_risks.html:70 msgid "Process" msgstr "" #: risks/models.py:68 templates/risks/item_risk.html:55 -#: templates/risks/list_risks.html:85 +#: templates/risks/list_risks.html:44 templates/risks/list_risks.html:112 msgid "Category" msgstr "" @@ -219,6 +225,10 @@ msgstr "" msgid "Updated at" msgstr "" +#: risks/models.py:71 +msgid "Effects" +msgstr "" + #: risks/models.py:133 msgid "Residual Risk" msgstr "" @@ -259,7 +269,7 @@ msgstr "" msgid "Auditlogs" msgstr "" -#: risks/models.py:257 templates/risks/item_risk.html:255 +#: risks/models.py:257 templates/risks/item_risk.html:259 msgid "Incident" msgstr "" @@ -275,15 +285,119 @@ msgstr "" msgid "Reported by" msgstr "" -#: risks/models.py:279 +#: risks/models.py:279 risks/utils.py:119 msgid "Notification" msgstr "" -#: risks/models.py:280 templates/base.html:78 +#: risks/models.py:280 templates/base.html:80 #: templates/risks/notifications.html:4 msgid "Notifications" msgstr "" +#: risks/models.py:295 +msgid "Risk created" +msgstr "" + +#: risks/models.py:296 +msgid "Risk updated" +msgstr "" + +#: risks/models.py:297 +msgid "Risk deleted" +msgstr "" + +#: risks/models.py:298 +msgid "Risk review required" +msgstr "" + +#: risks/models.py:299 +msgid "Risk review completed" +msgstr "" + +#: risks/models.py:301 +msgid "Control created" +msgstr "" + +#: risks/models.py:302 +msgid "Control updated" +msgstr "" + +#: risks/models.py:303 +msgid "Control deleted" +msgstr "" + +#: risks/models.py:305 +msgid "Residual created" +msgstr "" + +#: risks/models.py:306 +msgid "Residual updated" +msgstr "" + +#: risks/models.py:307 +msgid "Residual deleted" +msgstr "" + +#: risks/models.py:308 +msgid "Residual review required" +msgstr "" + +#: risks/models.py:309 +msgid "Residual review completed" +msgstr "" + +#: risks/models.py:311 +msgid "Incident created" +msgstr "" + +#: risks/models.py:312 +msgid "Incident updated" +msgstr "" + +#: risks/models.py:313 +msgid "Incident deleted" +msgstr "" + +#: risks/models.py:315 +msgid "User created" +msgstr "" + +#: risks/models.py:316 +msgid "User deleted" +msgstr "" + +#: risks/models.py:371 +msgid "Notification rule" +msgstr "" + +#: risks/models.py:372 +msgid "Notification rules" +msgstr "" + +#: risks/models.py:375 +msgid "Event" +msgstr "" + +#: risks/models.py:380 +msgid "Show in app" +msgstr "" + +#: risks/models.py:381 +msgid "Send via email" +msgstr "" + +#: risks/models.py:385 +msgid "Send to owner/responsible/reporter (if available)" +msgstr "" + +#: risks/models.py:389 +msgid "Send to all staff" +msgstr "" + +#: risks/models.py:393 +msgid "Extra recipients (emails, comma or newline separated)" +msgstr "" + #: risks/signals.py:57 #, python-brace-format msgid "User '{u}' created" @@ -299,13 +413,13 @@ msgstr "" msgid "Risk '{title}' {state}" msgstr "" -#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240 -#: risks/signals.py:296 +#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212 +#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411 msgid "created" msgstr "" -#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240 -#: risks/signals.py:296 +#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212 +#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411 msgid "updated" msgstr "" @@ -314,77 +428,137 @@ msgstr "" msgid "Risk '{title}' deleted" msgstr "" -#: risks/signals.py:145 +#: risks/signals.py:117 +#, python-brace-format +msgid "Risk created: {t}" +msgstr "" + +#: risks/signals.py:123 +#, python-brace-format +msgid "Risk updated: {t}" +msgstr "" + +#: risks/signals.py:143 +#, python-brace-format +msgid "Risk deleted: {t}" +msgstr "" + +#: risks/signals.py:164 #, python-brace-format msgid "Control '{title}' {state}" msgstr "" -#: risks/signals.py:154 +#: risks/signals.py:173 #, python-brace-format msgid "Control '{title}' deleted" msgstr "" #: risks/signals.py:211 #, python-brace-format +msgid "Control {event}: {t}" +msgstr "" + +#: risks/signals.py:231 +#, python-brace-format +msgid "Control deleted: {t}" +msgstr "" + +#: risks/signals.py:246 +#, python-brace-format msgid "Review required for risk '{t}' due to control change" msgstr "" -#: risks/signals.py:230 +#: risks/signals.py:265 #, python-brace-format msgid "Review required for risk '{t}'" msgstr "" -#: risks/signals.py:235 +#: risks/signals.py:270 #, python-brace-format msgid "Review completed for risk '{t}'" msgstr "" -#: risks/signals.py:239 +#: risks/signals.py:274 #, python-brace-format msgid "Residual risk {state} for '{t}'" msgstr "" -#: risks/signals.py:244 +#: risks/signals.py:279 #, python-brace-format msgid "Residual risk deleted for '{t}'" msgstr "" -#: risks/signals.py:296 +#: risks/signals.py:316 +#, python-brace-format +msgid "Residual created for risk: {t}" +msgstr "" + +#: risks/signals.py:328 +#, python-brace-format +msgid "Residual review required for risk: {t}" +msgstr "" + +#: risks/signals.py:334 +#, python-brace-format +msgid "Residual review completed for risk: {t}" +msgstr "" + +#: risks/signals.py:340 +#, python-brace-format +msgid "Residual updated for risk: {t}" +msgstr "" + +#: risks/signals.py:358 +#, python-brace-format +msgid "Residual deleted for risk: {t}" +msgstr "" + +#: risks/signals.py:369 #, python-brace-format msgid "Incident '{t}' {s}" msgstr "" -#: risks/signals.py:301 +#: risks/signals.py:374 #, python-brace-format msgid "Incident '{t}' deleted" msgstr "" -#: risks/utils.py:48 +#: risks/signals.py:410 +#, python-brace-format +msgid "Incident {event}: {t}" +msgstr "" + +#: risks/signals.py:442 +#, python-brace-format +msgid "Incident deleted: {t}" +msgstr "" + +#: risks/utils.py:53 risks/utils.py:67 #, python-brace-format msgid "Follow-up reached: review required for risk '{t}'" msgstr "" -#: risks/views.py:315 +#: risks/views.py:345 msgid "Notification marked as read." msgstr "" -#: risks/views.py:323 +#: risks/views.py:353 msgid "All notifications marked as read." msgstr "" -#: risks/views.py:340 +#: risks/views.py:370 msgid "Risk status updated." msgstr "" -#: risks/views.py:354 +#: risks/views.py:384 msgid "Control status updated." msgstr "" -#: risks/views.py:368 +#: risks/views.py:398 msgid "Incident status updated." msgstr "" -#: risks/views.py:384 +#: risks/views.py:414 msgid "Residual review flag updated." msgstr "" @@ -392,32 +566,37 @@ msgstr "" msgid "Dashboard" msgstr "" -#: templates/base.html:35 templates/risks/item_risk.html:4 +#: templates/base.html:35 templates/risks/risk_matrix.html:4 +#: templates/risks/risk_matrix.html:12 templates/risks/risk_matrix.html:18 +msgid "Risk Matrix" +msgstr "" + +#: templates/base.html:37 templates/risks/item_risk.html:4 #: templates/risks/list_risks.html:4 msgid "Risk analysis" msgstr "" -#: templates/base.html:73 +#: templates/base.html:75 msgid "AdminCP" msgstr "" -#: templates/base.html:86 +#: templates/base.html:88 msgid "Derk Mode" msgstr "" -#: templates/base.html:92 +#: templates/base.html:94 msgid "Logout" msgstr "" -#: templates/base.html:107 +#: templates/base.html:109 msgid "Login" msgstr "" -#: templates/base.html:142 templates/base.html:149 +#: templates/base.html:144 templates/base.html:151 msgid "Light Mode" msgstr "" -#: templates/base.html:152 +#: templates/base.html:154 msgid "Dark Mode" msgstr "" @@ -477,97 +656,100 @@ msgstr "" msgid "Resubmission" msgstr "" -#: templates/risks/item_risk.html:76 +#: templates/risks/item_risk.html:80 msgid "Risk assessment" msgstr "" -#: templates/risks/item_risk.html:84 +#: templates/risks/item_risk.html:88 msgid "Gross (before measures)" msgstr "" -#: templates/risks/item_risk.html:89 templates/risks/item_risk.html:135 -#: templates/risks/list_risks.html:86 +#: templates/risks/item_risk.html:93 templates/risks/item_risk.html:139 +#: templates/risks/list_risks.html:118 templates/risks/list_risks.html:122 +#: templates/risks/risk_matrix.html:25 msgid "Likelihood" msgstr "" -#: templates/risks/item_risk.html:90 templates/risks/item_risk.html:136 +#: templates/risks/item_risk.html:94 templates/risks/item_risk.html:140 msgid "Probability of occurrence" msgstr "" -#: templates/risks/item_risk.html:98 templates/risks/item_risk.html:144 -#: templates/risks/list_risks.html:87 +#: templates/risks/item_risk.html:102 templates/risks/item_risk.html:148 +#: templates/risks/list_risks.html:119 templates/risks/list_risks.html:123 +#: templates/risks/risk_matrix.html:25 msgid "Impact" msgstr "" -#: templates/risks/item_risk.html:99 templates/risks/item_risk.html:145 +#: templates/risks/item_risk.html:103 templates/risks/item_risk.html:149 msgid "Extent of damage" msgstr "" -#: templates/risks/item_risk.html:107 templates/risks/item_risk.html:108 -#: templates/risks/item_risk.html:153 templates/risks/item_risk.html:154 -#: templates/risks/list_risks.html:89 +#: templates/risks/item_risk.html:111 templates/risks/item_risk.html:112 +#: templates/risks/item_risk.html:157 templates/risks/item_risk.html:158 +#: templates/risks/list_risks.html:121 templates/risks/list_risks.html:125 msgid "Level" msgstr "" -#: templates/risks/item_risk.html:116 templates/risks/item_risk.html:117 -#: templates/risks/item_risk.html:161 templates/risks/item_risk.html:163 -#: templates/risks/list_risks.html:88 +#: templates/risks/item_risk.html:120 templates/risks/item_risk.html:121 +#: templates/risks/item_risk.html:165 templates/risks/item_risk.html:167 +#: templates/risks/list_risks.html:120 templates/risks/list_risks.html:124 +#: templates/risks/risk_matrix.html:39 msgid "Score" msgstr "" -#: templates/risks/item_risk.html:130 +#: templates/risks/item_risk.html:134 msgid "Net (after measures)" msgstr "" -#: templates/risks/item_risk.html:169 +#: templates/risks/item_risk.html:173 msgid "No net risk recorded yet." msgstr "" -#: templates/risks/item_risk.html:180 +#: templates/risks/item_risk.html:184 msgid "Save" msgstr "" -#: templates/risks/item_risk.html:194 +#: templates/risks/item_risk.html:198 msgid "Measures" msgstr "" -#: templates/risks/item_risk.html:203 +#: templates/risks/item_risk.html:207 msgid "Deadline" msgstr "" -#: templates/risks/item_risk.html:204 +#: templates/risks/item_risk.html:208 msgid "Responsible" msgstr "" -#: templates/risks/item_risk.html:205 +#: templates/risks/item_risk.html:209 msgid "Link" msgstr "" -#: templates/risks/item_risk.html:239 +#: templates/risks/item_risk.html:243 msgid "No measures recorded." msgstr "" -#: templates/risks/item_risk.html:257 +#: templates/risks/item_risk.html:261 msgid "Reported on" msgstr "" -#: templates/risks/item_risk.html:271 +#: templates/risks/item_risk.html:275 msgid "No incidents recorded." msgstr "" -#: templates/risks/item_risk.html:279 +#: templates/risks/item_risk.html:283 msgid "History" msgstr "" -#: templates/risks/item_risk.html:286 +#: templates/risks/item_risk.html:290 msgid "Time" msgstr "" -#: templates/risks/item_risk.html:288 +#: templates/risks/item_risk.html:292 msgid "Action" msgstr "" -#: templates/risks/item_risk.html:302 +#: templates/risks/item_risk.html:306 msgid "No History found." msgstr "" @@ -575,20 +757,31 @@ msgstr "" msgid "Filter" msgstr "" -#: templates/risks/list_risks.html:22 templates/risks/list_risks.html:41 -#: templates/risks/list_risks.html:60 templates/risks/notifications.html:13 -msgid "All" +#: templates/risks/list_risks.html:83 +msgid "Owner" msgstr "" -#: templates/risks/list_risks.html:56 templates/risks/list_risks.html:90 -msgid "Risk Owner" -msgstr "" - -#: templates/risks/list_risks.html:84 +#: templates/risks/list_risks.html:111 msgid "Asset / Process" msgstr "" -#: templates/risks/list_risks.html:152 +#: templates/risks/list_risks.html:113 +msgid "Risk Owner" +msgstr "" + +#: templates/risks/list_risks.html:114 +msgid "Gross Risk" +msgstr "" + +#: templates/risks/list_risks.html:115 +msgid "Net Risk" +msgstr "" + +#: templates/risks/list_risks.html:195 +msgid "No residual risk defined" +msgstr "" + +#: templates/risks/list_risks.html:201 msgid "No risks present" msgstr "" @@ -596,6 +789,10 @@ msgstr "" msgid "Unread" msgstr "" +#: templates/risks/notifications.html:13 +msgid "All" +msgstr "" + #: templates/risks/notifications.html:20 msgid "Mark all as read" msgstr "" @@ -611,3 +808,23 @@ msgstr "" #: templates/risks/notifications.html:53 msgid "No notifications." msgstr "" + +#: templates/risks/risk_matrix.html:13 +msgid "Detail View" +msgstr "" + +#: templates/risks/risk_matrix.html:54 +msgid "Show" +msgstr "" + +#: templates/risks/risk_matrix.html:58 +msgid "Gross" +msgstr "" + +#: templates/risks/risk_matrix.html:61 +msgid "Net" +msgstr "" + +#: templates/risks/risk_matrix.html:73 templates/risks/risk_matrix.html:115 +msgid "Impact \\\\ Likelihood" +msgstr "" diff --git a/risks/templatetags/risk_extras.py b/risks/templatetags/risk_extras.py index f06fd65..1c8e003 100644 --- a/risks/templatetags/risk_extras.py +++ b/risks/templatetags/risk_extras.py @@ -10,6 +10,20 @@ _LIKELIHOOD_LABELS = dict(Risk.LIKELIHOOD_CHOICES) _IMPACT_LABELS = dict(Risk.IMPACT_CHOICES) LEVEL_ID_MAP = {"Low": 1, "Medium": 2, "High": 3, "Critical": 4} +@register.filter +def dict_get(d, key): + try: + return d.get(key) + except Exception: + return None + +@register.filter +def mul(a, b): + try: + return int(a) * int(b) + except (TypeError, ValueError): + return "" + @register.filter def level_id(level): return LEVEL_ID_MAP.get(str(level), "") @@ -38,7 +52,7 @@ def likelihood_id_label(val): return "" label = _LIKELIHOOD_LABELS.get(i, "") short = _short(str(label)) if label else "" - return format_html("{}
({})", i, short) if label else format_html("{}", i) + return format_html("{} ({})", i, short) if label else format_html("{}", i) @register.filter def impact_id_label(val): @@ -48,7 +62,7 @@ def impact_id_label(val): return "" label = _IMPACT_LABELS.get(i, "") short = _short(str(label)) if label else "" - return format_html("{}
({})", i, short) if label else format_html("{}", i) + return format_html("{} ({})", i, short) if label else format_html("{}", i) @register.filter @@ -131,4 +145,24 @@ def to_bg(css_class: str): css = str(css_class) except Exception: return "" - return css.replace("is-control-", "has-background-control-") if css.startswith("is-control-") else css \ No newline at end of file + return css.replace("is-control-", "has-background-control-") if css.startswith("is-control-") else css + +@register.filter +def score_bg_class(score): + """ + Mappt Score (1..20) auf deine Farbhintergründe. + """ + try: + s = int(score) + except (TypeError, ValueError): + return "" + if s <= 4: + return "has-background-control-verylow" + elif s <= 8: + return "has-background-control-low" + elif s <= 12: + return "has-background-control-mid" + elif s <= 16: + return "has-background-control-high" + else: + return "has-background-control-veryhigh" \ No newline at end of file diff --git a/risks/urls.py b/risks/urls.py index 031882e..a07da14 100644 --- a/risks/urls.py +++ b/risks/urls.py @@ -13,6 +13,7 @@ urlpatterns = [ path("risks/controls/", views.show_control, name="show_control"), path("risks/list_incidents", views.list_incidents, name="list_incidents"), path("risks/incidents/", views.show_incident, name="show_incident"), + path("risks/risk_matrix", views.risk_matrix, name="risk_matrix"), # Notifications path("notifications/", views.notifications, name="notifications"), diff --git a/risks/views.py b/risks/views.py index e0a4cc6..a5e3057 100644 --- a/risks/views.py +++ b/risks/views.py @@ -9,7 +9,7 @@ from django.shortcuts import redirect, render, get_object_or_404 from django.utils.translation import gettext_lazy as _ from rest_framework import viewsets from rest_framework.permissions import IsAuthenticated -from collections import Counter +from collections import Counter, defaultdict from .forms import RiskStatusForm, ControlStatusForm, IncidentStatusForm, ResidualReviewForm from .models import Risk, Control, ResidualRisk, AuditLog, Incident, Notification from .serializers import ControlSerializer, RiskSerializer, ResidualRiskSerializer, UserSerializer, AuditSerializer, IncidentSerializer @@ -119,12 +119,15 @@ def list_risks(request): """ View for listing all Risks """ - qs = Risk.objects.all().select_related("owner") + qs = Risk.objects.all().select_related("owner", "residual_risk") # GET-Parameter lesen risk_id = request.GET.get("risk") control_id = request.GET.get("control") owner_id = request.GET.get("owner") + category = request.GET.get("category") + asset = request.GET.get("asset") + process = request.GET.get("process") if risk_id: qs = qs.filter(id=risk_id) @@ -132,16 +135,43 @@ def list_risks(request): qs = qs.filter(controls__id=control_id) if owner_id: qs = qs.filter(owner_id=owner_id) + if category: + qs = qs.filter(category=category) + if asset: + qs = qs.filter(asset=asset) + if process: + qs = qs.filter(process=process) risks = qs.order_by("title").distinct() controls = Control.objects.all().order_by("title") owners = User.objects.filter(owned_risks__isnull=False).distinct().order_by("username") + categories = (Risk.objects + .exclude(category__isnull=True) + .exclude(category__exact="") + .values_list("category", flat=True) + .distinct() + .order_by("category")) + assets = (Risk.objects + .exclude(asset__isnull=True) + .exclude(asset__exact="") + .values_list("asset", flat=True) + .distinct() + .order_by("asset")) + processes = (Risk.objects + .exclude(process__isnull=True) + .exclude(process__exact="") + .values_list("process", flat=True) + .distinct() + .order_by("process")) return render(request, "risks/list_risks.html", { "risks": risks, "controls": controls, "owners": owners, + "categories": categories, + "assets": assets, + "processes": processes, }) @login_required @@ -382,4 +412,31 @@ def update_residual_review(request, risk_id): obj._changed_by = request.user obj.save(update_fields=["review_required", "updated_at"]) messages.success(request, _("Residual review flag updated.")) - return redirect("risks:show_risk", id=risk.pk) \ No newline at end of file + return redirect("risks:show_risk", id=risk.pk) + + +def risk_matrix(request): + risks = (Risk.objects + .select_related("owner", "residual_risk") # wichtig fürs Netto + .all()) + + impacts = sorted(Risk.IMPACT_CHOICES, key=lambda x: x[0]) + likelihoods = sorted(Risk.LIKELIHOOD_CHOICES, key=lambda x: x[0]) + + gross_matrix = {i: {l: [] for l, _ in likelihoods} for i, _ in impacts} + net_matrix = {i: {l: [] for l, _ in likelihoods} for i, _ in impacts} + + for r in risks: + # Brutto platzieren + gross_matrix[r.impact][r.likelihood].append(r) + # Netto (falls vorhanden) platzieren + rr = getattr(r, "residual_risk", None) + if rr: + net_matrix[rr.impact][rr.likelihood].append(r) + + return render(request, "risks/risk_matrix.html", { + "impacts": impacts, + "likelihoods": likelihoods, + "gross_matrix": gross_matrix, + "net_matrix": net_matrix, + }) diff --git a/static/css/design.css b/static/css/design.css index 7392c06..c6454a3 100644 --- a/static/css/design.css +++ b/static/css/design.css @@ -1,10 +1,10 @@ /* Base palette */ :root{ - --c-verylow:#22c55e; --c-verylow-100:#dcfce7; --c-verylow-300:#86efac; --c-verylow-inv:#fff; + --c-verylow:#22c55e; --c-verylow-100:#dcfce7; --c-verylow-300:#86efac; --c-verylow-inv:#000; --c-low:#84cc16; --c-low-100:#ecfccb; --c-low-300:#bef264; --c-low-inv:#111; --c-mid:#eab308; --c-mid-100:#fef9c3; --c-mid-300:#fde047; --c-mid-inv:#111; --c-high:#f97316; --c-high-100:#ffedd5; --c-high-300:#fbbf24; --c-high-inv:#111; - --c-veryhigh:#dc2626; --c-veryhigh-100:#fee2e2;--c-veryhigh-300:#fca5a5; --c-veryhigh-inv:#fff; + --c-veryhigh:#dc2626; --c-veryhigh-100:#fee2e2;--c-veryhigh-300:#fca5a5; --c-veryhigh-inv:#000; } /* Helpers (wie Bulma) */ @@ -80,6 +80,9 @@ .progress.is-control-high::-moz-progress-bar{background:var(--c-high)} .progress.is-control-veryhigh::-moz-progress-bar{background:var(--c-veryhigh)} +abbr { + text-decoration: none; +} /* Topbar-Farbe erzwingen (Bulma überschreibt sonst mit weiß) */ .navbar.topbar-nav { diff --git a/templates/base.html b/templates/base.html index d872ddb..a5a907c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -32,6 +32,8 @@ {% trans "Risk Management" %}