feat: Add risk matrix view and related functionality
- Implemented a new view for the risk matrix, allowing users to visualize risks based on their impact and likelihood. - Added filters for category, asset, and process in the risk listing view. - Enhanced risk listing template to include new filters and improved layout. - Introduced new CSS variables for better color management in the design. - Updated existing template tags to support new functionalities, including score background class mapping. - Modified existing risk listing to display residual risk details alongside gross risk. - Added new risk matrix HTML template with tabbed interface for gross and net risk views.
This commit is contained in:
parent
ed300ca403
commit
9d02badf14
11 changed files with 1038 additions and 270 deletions
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: wira-risk-management\n"
|
"Project-Id-Version: wira-risk-management\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"PO-Revision-Date: 2025-09-09 13:45+0200\n"
|
||||||
"Last-Translator: Kevin Heyer <kevin@example.com>\n"
|
"Last-Translator: Kevin Heyer <kevin@example.com>\n"
|
||||||
"Language-Team: German\n"
|
"Language-Team: German\n"
|
||||||
|
@ -22,12 +22,12 @@ msgstr "Admin"
|
||||||
|
|
||||||
#: risks/admin.py:15 risks/models.py:36 templates/risks/dashboard.html:75
|
#: 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/dashboard.html:80 templates/risks/dashboard.html:85
|
||||||
#: templates/risks/list_risks.html:76
|
#: templates/risks/list_risks.html:97
|
||||||
msgid "Risks"
|
msgid "Risks"
|
||||||
msgstr "Risiken"
|
msgstr "Risiken"
|
||||||
|
|
||||||
#: risks/admin.py:16 risks/models.py:190 templates/base.html:36
|
#: risks/admin.py:16 risks/models.py:190 templates/base.html:38
|
||||||
#: templates/risks/list_risks.html:37
|
#: templates/risks/list_risks.html:31
|
||||||
msgid "Controls"
|
msgid "Controls"
|
||||||
msgstr "Maßnahmen"
|
msgstr "Maßnahmen"
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ msgstr "Restrisiken"
|
||||||
msgid "Reviews"
|
msgid "Reviews"
|
||||||
msgstr "Prüfung"
|
msgstr "Prüfung"
|
||||||
|
|
||||||
#: risks/admin.py:19 risks/models.py:258 templates/base.html:37
|
#: risks/admin.py:19 risks/models.py:258 templates/base.html:39
|
||||||
#: templates/risks/item_risk.html:248
|
#: templates/risks/item_risk.html:252
|
||||||
msgid "Incidents"
|
msgid "Incidents"
|
||||||
msgstr "Vorfälle"
|
msgstr "Vorfälle"
|
||||||
|
|
||||||
|
@ -48,13 +48,13 @@ msgstr "Vorfälle"
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "Benutzer"
|
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"
|
msgid "User"
|
||||||
msgstr "Benutzer"
|
msgstr "Benutzer"
|
||||||
|
|
||||||
#: risks/admin.py:139
|
#: risks/admin.py:139
|
||||||
msgid "Message"
|
msgid "Message"
|
||||||
msgstr ""
|
msgstr "Nachricht"
|
||||||
|
|
||||||
#: risks/admin.py:147
|
#: risks/admin.py:147
|
||||||
msgid "Mark selected as read"
|
msgid "Mark selected as read"
|
||||||
|
@ -76,9 +76,10 @@ msgstr "%(n)d Benachrichtigungen wurden als ungelesen Markiert"
|
||||||
|
|
||||||
#: risks/admin.py:157
|
#: risks/admin.py:157
|
||||||
msgid "Mark selected as sent"
|
msgid "Mark selected as sent"
|
||||||
msgstr ""
|
msgstr "Auswahl als gelesen markieren"
|
||||||
|
|
||||||
#: risks/admin.py:160
|
#: risks/admin.py:160
|
||||||
|
#, python-format
|
||||||
msgid "%(n)d notifications marked as sent."
|
msgid "%(n)d notifications marked as sent."
|
||||||
msgstr "%(n)d Benachrichtigungen wurden als gelesen Markiert"
|
msgstr "%(n)d Benachrichtigungen wurden als gelesen Markiert"
|
||||||
|
|
||||||
|
@ -87,18 +88,23 @@ msgid "Mark selected as unsent"
|
||||||
msgstr "Auswahl als ungesendet markieren"
|
msgstr "Auswahl als ungesendet markieren"
|
||||||
|
|
||||||
#: risks/admin.py:165
|
#: risks/admin.py:165
|
||||||
|
#, python-format
|
||||||
msgid "%(n)d notifications marked as unsent."
|
msgid "%(n)d notifications marked as unsent."
|
||||||
msgstr "%(n)d Benachrichtigungen wurden als gelesen Markiert"
|
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"
|
msgid "SSO Information"
|
||||||
msgstr "SSO-Informationen"
|
msgstr "SSO-Informationen"
|
||||||
|
|
||||||
#: risks/admin.py:186
|
#: risks/admin.py:199
|
||||||
msgid "Risks Owned"
|
msgid "Risks Owned"
|
||||||
msgstr "Eigene Risiken"
|
msgstr "Eigene Risiken"
|
||||||
|
|
||||||
#: risks/admin.py:190
|
#: risks/admin.py:203
|
||||||
msgid "Controls Responsible"
|
msgid "Controls Responsible"
|
||||||
msgstr "Verantwortlich für Maßnahmen"
|
msgstr "Verantwortlich für Maßnahmen"
|
||||||
|
|
||||||
|
@ -107,17 +113,17 @@ msgid "Risk Management"
|
||||||
msgstr "Risikomanagement"
|
msgstr "Risikomanagement"
|
||||||
|
|
||||||
#: risks/forms.py:9 risks/forms.py:16 risks/forms.py:23 risks/models.py:73
|
#: 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:64 templates/risks/item_risk.html:206
|
||||||
#: templates/risks/item_risk.html:256
|
#: templates/risks/item_risk.html:260
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "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"
|
msgid "Review required"
|
||||||
msgstr "Prüfung nötig"
|
msgstr "Prüfung nötig"
|
||||||
|
|
||||||
#: risks/models.py:35 templates/risks/item_risk.html:11
|
#: 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"
|
msgid "Risk"
|
||||||
msgstr "Risiko"
|
msgstr "Risiko"
|
||||||
|
|
||||||
|
@ -182,7 +188,7 @@ msgid "Availability"
|
||||||
msgstr "Verfügbarkeit"
|
msgstr "Verfügbarkeit"
|
||||||
|
|
||||||
#: risks/models.py:64 risks/models.py:200 risks/models.py:265
|
#: 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"
|
msgid "Title"
|
||||||
msgstr "Titel"
|
msgstr "Titel"
|
||||||
|
|
||||||
|
@ -191,15 +197,17 @@ msgid "Description"
|
||||||
msgstr "Beschreibung"
|
msgstr "Beschreibung"
|
||||||
|
|
||||||
#: risks/models.py:66 templates/risks/item_risk.html:53
|
#: risks/models.py:66 templates/risks/item_risk.html:53
|
||||||
|
#: templates/risks/list_risks.html:57
|
||||||
msgid "Asset"
|
msgid "Asset"
|
||||||
msgstr "Asset"
|
msgstr "Asset"
|
||||||
|
|
||||||
#: risks/models.py:67 templates/risks/item_risk.html:54
|
#: risks/models.py:67 templates/risks/item_risk.html:54
|
||||||
|
#: templates/risks/list_risks.html:70
|
||||||
msgid "Process"
|
msgid "Process"
|
||||||
msgstr "Prozess"
|
msgstr "Prozess"
|
||||||
|
|
||||||
#: risks/models.py:68 templates/risks/item_risk.html:55
|
#: 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"
|
msgid "Category"
|
||||||
msgstr "Kategorie"
|
msgstr "Kategorie"
|
||||||
|
|
||||||
|
@ -211,6 +219,10 @@ msgstr "Erstellt am"
|
||||||
msgid "Updated at"
|
msgid "Updated at"
|
||||||
msgstr "Aktualisiert am"
|
msgstr "Aktualisiert am"
|
||||||
|
|
||||||
|
#: risks/models.py:71
|
||||||
|
msgid "Effects"
|
||||||
|
msgstr "Auswirkungen"
|
||||||
|
|
||||||
#: risks/models.py:133
|
#: risks/models.py:133
|
||||||
msgid "Residual Risk"
|
msgid "Residual Risk"
|
||||||
msgstr "Restrisiko"
|
msgstr "Restrisiko"
|
||||||
|
@ -251,7 +263,7 @@ msgstr "Audit-Log"
|
||||||
msgid "Auditlogs"
|
msgid "Auditlogs"
|
||||||
msgstr "Audit-Logs"
|
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"
|
msgid "Incident"
|
||||||
msgstr "Vorfall"
|
msgstr "Vorfall"
|
||||||
|
|
||||||
|
@ -267,15 +279,120 @@ msgstr "Meldedatum"
|
||||||
msgid "Reported by"
|
msgid "Reported by"
|
||||||
msgstr "Gemeldet von"
|
msgstr "Gemeldet von"
|
||||||
|
|
||||||
#: risks/models.py:279
|
#: risks/models.py:279 risks/utils.py:119
|
||||||
msgid "Notification"
|
msgid "Notification"
|
||||||
msgstr "Benachrichtigung"
|
msgstr "Benachrichtigung"
|
||||||
|
|
||||||
#: risks/models.py:280 templates/base.html:78
|
#: risks/models.py:280 templates/base.html:80
|
||||||
#: templates/risks/notifications.html:4
|
#: templates/risks/notifications.html:4
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Nachrichten"
|
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
|
#: risks/signals.py:57
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "User '{u}' created"
|
msgid "User '{u}' created"
|
||||||
|
@ -291,13 +408,13 @@ msgstr "Benutzer '{u}' löschte"
|
||||||
msgid "Risk '{title}' {state}"
|
msgid "Risk '{title}' {state}"
|
||||||
msgstr "Risiko '{title}' {state}"
|
msgstr "Risiko '{title}' {state}"
|
||||||
|
|
||||||
#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240
|
#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212
|
||||||
#: risks/signals.py:296
|
#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411
|
||||||
msgid "created"
|
msgid "created"
|
||||||
msgstr "erstellt"
|
msgstr "erstellt"
|
||||||
|
|
||||||
#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240
|
#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212
|
||||||
#: risks/signals.py:296
|
#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411
|
||||||
msgid "updated"
|
msgid "updated"
|
||||||
msgstr "Aktualisiert"
|
msgstr "Aktualisiert"
|
||||||
|
|
||||||
|
@ -306,77 +423,137 @@ msgstr "Aktualisiert"
|
||||||
msgid "Risk '{title}' deleted"
|
msgid "Risk '{title}' deleted"
|
||||||
msgstr "Risiko '{title}' gelöscht"
|
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
|
#, python-brace-format
|
||||||
msgid "Control '{title}' {state}"
|
msgid "Control '{title}' {state}"
|
||||||
msgstr "Maßnahme '{title}' {state}"
|
msgstr "Maßnahme '{title}' {state}"
|
||||||
|
|
||||||
#: risks/signals.py:154
|
#: risks/signals.py:173
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Control '{title}' deleted"
|
msgid "Control '{title}' deleted"
|
||||||
msgstr "Maßnahme '{title}' gelöscht"
|
msgstr "Maßnahme '{title}' gelöscht"
|
||||||
|
|
||||||
#: risks/signals.py:211
|
#: risks/signals.py:211
|
||||||
#, python-brace-format
|
#, 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"
|
msgid "Review required for risk '{t}' due to control change"
|
||||||
msgstr "Prüfung nötig für: '{t}', da Maßnahmen geändert wurden"
|
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
|
#, python-brace-format
|
||||||
msgid "Review required for risk '{t}'"
|
msgid "Review required for risk '{t}'"
|
||||||
msgstr "Prüfung benötigt für Risiko '{t}'"
|
msgstr "Prüfung benötigt für Risiko '{t}'"
|
||||||
|
|
||||||
#: risks/signals.py:235
|
#: risks/signals.py:270
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Review completed for risk '{t}'"
|
msgid "Review completed for risk '{t}'"
|
||||||
msgstr "Prüfung Abgeschlossen für Risiko '{t}'"
|
msgstr "Prüfung Abgeschlossen für Risiko '{t}'"
|
||||||
|
|
||||||
#: risks/signals.py:239
|
#: risks/signals.py:274
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Residual risk {state} for '{t}'"
|
msgid "Residual risk {state} for '{t}'"
|
||||||
msgstr "Restrisiko {state} für '{t}'"
|
msgstr "Restrisiko {state} für '{t}'"
|
||||||
|
|
||||||
#: risks/signals.py:244
|
#: risks/signals.py:279
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Residual risk deleted for '{t}'"
|
msgid "Residual risk deleted for '{t}'"
|
||||||
msgstr "Restrisiko für '{t}' gelöscht"
|
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
|
#, python-brace-format
|
||||||
msgid "Incident '{t}' {s}"
|
msgid "Incident '{t}' {s}"
|
||||||
msgstr "Vorfälle '{t}' {s}"
|
msgstr "Vorfall '{t}' {s}"
|
||||||
|
|
||||||
#: risks/signals.py:301
|
#: risks/signals.py:374
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Incident '{t}' deleted"
|
msgid "Incident '{t}' deleted"
|
||||||
msgstr "Vorfall '{t}' gelöscht"
|
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
|
#, python-brace-format
|
||||||
msgid "Follow-up reached: review required for risk '{t}'"
|
msgid "Follow-up reached: review required for risk '{t}'"
|
||||||
msgstr "Wiedervorlagedatum erreicht: Prüfung nötig für Risiko '{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."
|
msgid "Notification marked as read."
|
||||||
msgstr "Nachricht als gelesen markiert"
|
msgstr "Nachricht als gelesen markiert"
|
||||||
|
|
||||||
#: risks/views.py:323
|
#: risks/views.py:353
|
||||||
msgid "All notifications marked as read."
|
msgid "All notifications marked as read."
|
||||||
msgstr "Alle Benachrichtigungen wurden als gelesen Markiert"
|
msgstr "Alle Benachrichtigungen wurden als gelesen Markiert"
|
||||||
|
|
||||||
#: risks/views.py:340
|
#: risks/views.py:370
|
||||||
msgid "Risk status updated."
|
msgid "Risk status updated."
|
||||||
msgstr "Risikostatus Aktualisiert"
|
msgstr "Risikostatus Aktualisiert"
|
||||||
|
|
||||||
#: risks/views.py:354
|
#: risks/views.py:384
|
||||||
msgid "Control status updated."
|
msgid "Control status updated."
|
||||||
msgstr "Maßnahmenstatus Aktualisiert"
|
msgstr "Maßnahmenstatus Aktualisiert"
|
||||||
|
|
||||||
#: risks/views.py:368
|
#: risks/views.py:398
|
||||||
msgid "Incident status updated."
|
msgid "Incident status updated."
|
||||||
msgstr "Vorfallstatus Aktualisiert"
|
msgstr "Vorfallstatus Aktualisiert"
|
||||||
|
|
||||||
#: risks/views.py:384
|
#: risks/views.py:414
|
||||||
msgid "Residual review flag updated."
|
msgid "Residual review flag updated."
|
||||||
msgstr "Restrisiko geprüft"
|
msgstr "Restrisiko geprüft"
|
||||||
|
|
||||||
|
@ -384,32 +561,37 @@ msgstr "Restrisiko geprüft"
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr "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
|
#: templates/risks/list_risks.html:4
|
||||||
msgid "Risk analysis"
|
msgid "Risk analysis"
|
||||||
msgstr "Risikoanalyse"
|
msgstr "Risikoanalyse"
|
||||||
|
|
||||||
#: templates/base.html:73
|
#: templates/base.html:75
|
||||||
msgid "AdminCP"
|
msgid "AdminCP"
|
||||||
msgstr "Adminbereich"
|
msgstr "Adminbereich"
|
||||||
|
|
||||||
#: templates/base.html:86
|
#: templates/base.html:88
|
||||||
msgid "Derk Mode"
|
msgid "Derk Mode"
|
||||||
msgstr "Dark Mode"
|
msgstr "Dark Mode"
|
||||||
|
|
||||||
#: templates/base.html:92
|
#: templates/base.html:94
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Logout"
|
msgstr "Logout"
|
||||||
|
|
||||||
#: templates/base.html:107
|
#: templates/base.html:109
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr "Login"
|
msgstr "Login"
|
||||||
|
|
||||||
#: templates/base.html:142 templates/base.html:149
|
#: templates/base.html:144 templates/base.html:151
|
||||||
msgid "Light Mode"
|
msgid "Light Mode"
|
||||||
msgstr "Light Mode"
|
msgstr "Light Mode"
|
||||||
|
|
||||||
#: templates/base.html:152
|
#: templates/base.html:154
|
||||||
msgid "Dark Mode"
|
msgid "Dark Mode"
|
||||||
msgstr "Dark Mode"
|
msgstr "Dark Mode"
|
||||||
|
|
||||||
|
@ -471,99 +653,100 @@ msgstr "Aktualisiert am"
|
||||||
msgid "Resubmission"
|
msgid "Resubmission"
|
||||||
msgstr "Wiedervorlagedatum"
|
msgstr "Wiedervorlagedatum"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:76
|
#: templates/risks/item_risk.html:80
|
||||||
msgid "Risk assessment"
|
msgid "Risk assessment"
|
||||||
msgstr "Risikomanagement"
|
msgstr "Risikomanagement"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:84
|
#: templates/risks/item_risk.html:88
|
||||||
msgid "Gross (before measures)"
|
msgid "Gross (before measures)"
|
||||||
msgstr "Brutto (vor Maßnahmen)"
|
msgstr "Brutto (vor Maßnahmen)"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:89 templates/risks/item_risk.html:135
|
#: templates/risks/item_risk.html:93 templates/risks/item_risk.html:139
|
||||||
#: templates/risks/list_risks.html:86
|
#: templates/risks/list_risks.html:118 templates/risks/list_risks.html:122
|
||||||
|
#: templates/risks/risk_matrix.html:25
|
||||||
msgid "Likelihood"
|
msgid "Likelihood"
|
||||||
msgstr "Eintritt"
|
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"
|
msgid "Probability of occurrence"
|
||||||
msgstr "Eintrittswahrscheinlichkeit"
|
msgstr "Eintrittswahrscheinlichkeit"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:98 templates/risks/item_risk.html:144
|
#: templates/risks/item_risk.html:102 templates/risks/item_risk.html:148
|
||||||
#: templates/risks/list_risks.html:87
|
#: templates/risks/list_risks.html:119 templates/risks/list_risks.html:123
|
||||||
|
#: templates/risks/risk_matrix.html:25
|
||||||
msgid "Impact"
|
msgid "Impact"
|
||||||
msgstr "Schaden"
|
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"
|
msgid "Extent of damage"
|
||||||
msgstr "Schadensausmaß"
|
msgstr "Schadensausmaß"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:107 templates/risks/item_risk.html:108
|
#: templates/risks/item_risk.html:111 templates/risks/item_risk.html:112
|
||||||
#: templates/risks/item_risk.html:153 templates/risks/item_risk.html:154
|
#: templates/risks/item_risk.html:157 templates/risks/item_risk.html:158
|
||||||
#: templates/risks/list_risks.html:89
|
#: templates/risks/list_risks.html:121 templates/risks/list_risks.html:125
|
||||||
msgid "Level"
|
msgid "Level"
|
||||||
msgstr "Stufe"
|
msgstr "Stufe"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:116 templates/risks/item_risk.html:117
|
#: templates/risks/item_risk.html:120 templates/risks/item_risk.html:121
|
||||||
#: templates/risks/item_risk.html:161 templates/risks/item_risk.html:163
|
#: templates/risks/item_risk.html:165 templates/risks/item_risk.html:167
|
||||||
#: templates/risks/list_risks.html:88
|
#: templates/risks/list_risks.html:120 templates/risks/list_risks.html:124
|
||||||
|
#: templates/risks/risk_matrix.html:39
|
||||||
msgid "Score"
|
msgid "Score"
|
||||||
msgstr "Score"
|
msgstr "Score"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:130
|
#: templates/risks/item_risk.html:134
|
||||||
msgid "Net (after measures)"
|
msgid "Net (after measures)"
|
||||||
msgstr "Netto (nach Maßnahmen)"
|
msgstr "Netto (nach Maßnahmen)"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:169
|
#: templates/risks/item_risk.html:173
|
||||||
msgid "No net risk recorded yet."
|
msgid "No net risk recorded yet."
|
||||||
msgstr "Kein Restrisiko vergeben"
|
msgstr "Kein Restrisiko vergeben"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:180
|
#: templates/risks/item_risk.html:184
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:194
|
#: templates/risks/item_risk.html:198
|
||||||
msgid "Measures"
|
msgid "Measures"
|
||||||
msgstr "Maßnahmen"
|
msgstr "Maßnahmen"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:203
|
#: templates/risks/item_risk.html:207
|
||||||
msgid "Deadline"
|
msgid "Deadline"
|
||||||
msgstr "Frist"
|
msgstr "Frist"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:204
|
#: templates/risks/item_risk.html:208
|
||||||
msgid "Responsible"
|
msgid "Responsible"
|
||||||
msgstr "Verantwortliche/r"
|
msgstr "Verantwortliche/r"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:205
|
#: templates/risks/item_risk.html:209
|
||||||
msgid "Link"
|
msgid "Link"
|
||||||
msgstr "Link"
|
msgstr "Link"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:239
|
#: templates/risks/item_risk.html:243
|
||||||
msgid "No measures recorded."
|
msgid "No measures recorded."
|
||||||
msgstr "Keine Maßnahmen gefunden."
|
msgstr "Keine Maßnahmen gefunden."
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:257
|
#: templates/risks/item_risk.html:261
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Reported by"
|
|
||||||
msgid "Reported on"
|
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."
|
msgid "No incidents recorded."
|
||||||
msgstr "Keine Vorfälle gefunden."
|
msgstr "Keine Vorfälle gefunden."
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:279
|
#: templates/risks/item_risk.html:283
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:286
|
#: templates/risks/item_risk.html:290
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr "Zeitpunkt"
|
msgstr "Zeitpunkt"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:288
|
#: templates/risks/item_risk.html:292
|
||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Aktion"
|
msgstr "Aktion"
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:302
|
#: templates/risks/item_risk.html:306
|
||||||
msgid "No History found."
|
msgid "No History found."
|
||||||
msgstr "Keine Historie vorhanden"
|
msgstr "Keine Historie vorhanden"
|
||||||
|
|
||||||
|
@ -571,20 +754,33 @@ msgstr "Keine Historie vorhanden"
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr "Filter"
|
msgstr "Filter"
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:22 templates/risks/list_risks.html:41
|
#: templates/risks/list_risks.html:83
|
||||||
#: templates/risks/list_risks.html:60 templates/risks/notifications.html:13
|
#, fuzzy
|
||||||
msgid "All"
|
#| msgid "Risk Owner"
|
||||||
msgstr "Alle"
|
msgid "Owner"
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:56 templates/risks/list_risks.html:90
|
|
||||||
msgid "Risk Owner"
|
|
||||||
msgstr "Risikoeigner"
|
msgstr "Risikoeigner"
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:84
|
#: templates/risks/list_risks.html:111
|
||||||
msgid "Asset / Process"
|
msgid "Asset / Process"
|
||||||
msgstr "Asset / Prozess"
|
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"
|
msgid "No risks present"
|
||||||
msgstr "Aktuell keine Risiken"
|
msgstr "Aktuell keine Risiken"
|
||||||
|
|
||||||
|
@ -592,6 +788,10 @@ msgstr "Aktuell keine Risiken"
|
||||||
msgid "Unread"
|
msgid "Unread"
|
||||||
msgstr "Ungelesen"
|
msgstr "Ungelesen"
|
||||||
|
|
||||||
|
#: templates/risks/notifications.html:13
|
||||||
|
msgid "All"
|
||||||
|
msgstr "Alle"
|
||||||
|
|
||||||
#: templates/risks/notifications.html:20
|
#: templates/risks/notifications.html:20
|
||||||
msgid "Mark all as read"
|
msgid "Mark all as read"
|
||||||
msgstr "Alle als gelesen Markieren"
|
msgstr "Alle als gelesen Markieren"
|
||||||
|
@ -607,3 +807,23 @@ msgstr "Als gelesen markieren"
|
||||||
#: templates/risks/notifications.html:53
|
#: templates/risks/notifications.html:53
|
||||||
msgid "No notifications."
|
msgid "No notifications."
|
||||||
msgstr "Keine Nachrichten"
|
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"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -28,12 +28,12 @@ msgstr ""
|
||||||
|
|
||||||
#: risks/admin.py:15 risks/models.py:36 templates/risks/dashboard.html:75
|
#: 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/dashboard.html:80 templates/risks/dashboard.html:85
|
||||||
#: templates/risks/list_risks.html:76
|
#: templates/risks/list_risks.html:97
|
||||||
msgid "Risks"
|
msgid "Risks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/admin.py:16 risks/models.py:190 templates/base.html:36
|
#: risks/admin.py:16 risks/models.py:190 templates/base.html:38
|
||||||
#: templates/risks/list_risks.html:37
|
#: templates/risks/list_risks.html:31
|
||||||
msgid "Controls"
|
msgid "Controls"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -45,8 +45,8 @@ msgstr ""
|
||||||
msgid "Reviews"
|
msgid "Reviews"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/admin.py:19 risks/models.py:258 templates/base.html:37
|
#: risks/admin.py:19 risks/models.py:258 templates/base.html:39
|
||||||
#: templates/risks/item_risk.html:248
|
#: templates/risks/item_risk.html:252
|
||||||
msgid "Incidents"
|
msgid "Incidents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ msgstr ""
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr ""
|
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"
|
msgid "User"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -98,15 +98,19 @@ msgstr ""
|
||||||
msgid "%(n)d notifications marked as unsent."
|
msgid "%(n)d notifications marked as unsent."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/admin.py:177
|
#: risks/admin.py:182
|
||||||
msgid "SSO Information"
|
msgid "Extra recipients"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: risks/admin.py:186
|
|
||||||
msgid "Risks Owned"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/admin.py:190
|
#: risks/admin.py:190
|
||||||
|
msgid "SSO Information"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: risks/admin.py:199
|
||||||
|
msgid "Risks Owned"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: risks/admin.py:203
|
||||||
msgid "Controls Responsible"
|
msgid "Controls Responsible"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -115,17 +119,17 @@ msgid "Risk Management"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/forms.py:9 risks/forms.py:16 risks/forms.py:23 risks/models.py:73
|
#: 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:64 templates/risks/item_risk.html:206
|
||||||
#: templates/risks/item_risk.html:256
|
#: templates/risks/item_risk.html:260
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
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"
|
msgid "Review required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:35 templates/risks/item_risk.html:11
|
#: 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"
|
msgid "Risk"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -190,7 +194,7 @@ msgid "Availability"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:64 risks/models.py:200 risks/models.py:265
|
#: 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"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -199,15 +203,17 @@ msgid "Description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:66 templates/risks/item_risk.html:53
|
#: risks/models.py:66 templates/risks/item_risk.html:53
|
||||||
|
#: templates/risks/list_risks.html:57
|
||||||
msgid "Asset"
|
msgid "Asset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:67 templates/risks/item_risk.html:54
|
#: risks/models.py:67 templates/risks/item_risk.html:54
|
||||||
|
#: templates/risks/list_risks.html:70
|
||||||
msgid "Process"
|
msgid "Process"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:68 templates/risks/item_risk.html:55
|
#: 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"
|
msgid "Category"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -219,6 +225,10 @@ msgstr ""
|
||||||
msgid "Updated at"
|
msgid "Updated at"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: risks/models.py:71
|
||||||
|
msgid "Effects"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:133
|
#: risks/models.py:133
|
||||||
msgid "Residual Risk"
|
msgid "Residual Risk"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -259,7 +269,7 @@ msgstr ""
|
||||||
msgid "Auditlogs"
|
msgid "Auditlogs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:257 templates/risks/item_risk.html:255
|
#: risks/models.py:257 templates/risks/item_risk.html:259
|
||||||
msgid "Incident"
|
msgid "Incident"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -275,15 +285,119 @@ msgstr ""
|
||||||
msgid "Reported by"
|
msgid "Reported by"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:279
|
#: risks/models.py:279 risks/utils.py:119
|
||||||
msgid "Notification"
|
msgid "Notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/models.py:280 templates/base.html:78
|
#: risks/models.py:280 templates/base.html:80
|
||||||
#: templates/risks/notifications.html:4
|
#: templates/risks/notifications.html:4
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr ""
|
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
|
#: risks/signals.py:57
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "User '{u}' created"
|
msgid "User '{u}' created"
|
||||||
|
@ -299,13 +413,13 @@ msgstr ""
|
||||||
msgid "Risk '{title}' {state}"
|
msgid "Risk '{title}' {state}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240
|
#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212
|
||||||
#: risks/signals.py:296
|
#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411
|
||||||
msgid "created"
|
msgid "created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:72 risks/signals.py:147 risks/signals.py:240
|
#: risks/signals.py:72 risks/signals.py:166 risks/signals.py:212
|
||||||
#: risks/signals.py:296
|
#: risks/signals.py:275 risks/signals.py:369 risks/signals.py:411
|
||||||
msgid "updated"
|
msgid "updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -314,77 +428,137 @@ msgstr ""
|
||||||
msgid "Risk '{title}' deleted"
|
msgid "Risk '{title}' deleted"
|
||||||
msgstr ""
|
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
|
#, python-brace-format
|
||||||
msgid "Control '{title}' {state}"
|
msgid "Control '{title}' {state}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:154
|
#: risks/signals.py:173
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Control '{title}' deleted"
|
msgid "Control '{title}' deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:211
|
#: risks/signals.py:211
|
||||||
#, python-brace-format
|
#, 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"
|
msgid "Review required for risk '{t}' due to control change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:230
|
#: risks/signals.py:265
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Review required for risk '{t}'"
|
msgid "Review required for risk '{t}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:235
|
#: risks/signals.py:270
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Review completed for risk '{t}'"
|
msgid "Review completed for risk '{t}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:239
|
#: risks/signals.py:274
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Residual risk {state} for '{t}'"
|
msgid "Residual risk {state} for '{t}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:244
|
#: risks/signals.py:279
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Residual risk deleted for '{t}'"
|
msgid "Residual risk deleted for '{t}'"
|
||||||
msgstr ""
|
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
|
#, python-brace-format
|
||||||
msgid "Incident '{t}' {s}"
|
msgid "Incident '{t}' {s}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/signals.py:301
|
#: risks/signals.py:374
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Incident '{t}' deleted"
|
msgid "Incident '{t}' deleted"
|
||||||
msgstr ""
|
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
|
#, python-brace-format
|
||||||
msgid "Follow-up reached: review required for risk '{t}'"
|
msgid "Follow-up reached: review required for risk '{t}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:315
|
#: risks/views.py:345
|
||||||
msgid "Notification marked as read."
|
msgid "Notification marked as read."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:323
|
#: risks/views.py:353
|
||||||
msgid "All notifications marked as read."
|
msgid "All notifications marked as read."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:340
|
#: risks/views.py:370
|
||||||
msgid "Risk status updated."
|
msgid "Risk status updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:354
|
#: risks/views.py:384
|
||||||
msgid "Control status updated."
|
msgid "Control status updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:368
|
#: risks/views.py:398
|
||||||
msgid "Incident status updated."
|
msgid "Incident status updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: risks/views.py:384
|
#: risks/views.py:414
|
||||||
msgid "Residual review flag updated."
|
msgid "Residual review flag updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -392,32 +566,37 @@ msgstr ""
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr ""
|
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
|
#: templates/risks/list_risks.html:4
|
||||||
msgid "Risk analysis"
|
msgid "Risk analysis"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:73
|
#: templates/base.html:75
|
||||||
msgid "AdminCP"
|
msgid "AdminCP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:86
|
#: templates/base.html:88
|
||||||
msgid "Derk Mode"
|
msgid "Derk Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:92
|
#: templates/base.html:94
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:107
|
#: templates/base.html:109
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:142 templates/base.html:149
|
#: templates/base.html:144 templates/base.html:151
|
||||||
msgid "Light Mode"
|
msgid "Light Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/base.html:152
|
#: templates/base.html:154
|
||||||
msgid "Dark Mode"
|
msgid "Dark Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -477,97 +656,100 @@ msgstr ""
|
||||||
msgid "Resubmission"
|
msgid "Resubmission"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:76
|
#: templates/risks/item_risk.html:80
|
||||||
msgid "Risk assessment"
|
msgid "Risk assessment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:84
|
#: templates/risks/item_risk.html:88
|
||||||
msgid "Gross (before measures)"
|
msgid "Gross (before measures)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:89 templates/risks/item_risk.html:135
|
#: templates/risks/item_risk.html:93 templates/risks/item_risk.html:139
|
||||||
#: templates/risks/list_risks.html:86
|
#: templates/risks/list_risks.html:118 templates/risks/list_risks.html:122
|
||||||
|
#: templates/risks/risk_matrix.html:25
|
||||||
msgid "Likelihood"
|
msgid "Likelihood"
|
||||||
msgstr ""
|
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"
|
msgid "Probability of occurrence"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:98 templates/risks/item_risk.html:144
|
#: templates/risks/item_risk.html:102 templates/risks/item_risk.html:148
|
||||||
#: templates/risks/list_risks.html:87
|
#: templates/risks/list_risks.html:119 templates/risks/list_risks.html:123
|
||||||
|
#: templates/risks/risk_matrix.html:25
|
||||||
msgid "Impact"
|
msgid "Impact"
|
||||||
msgstr ""
|
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"
|
msgid "Extent of damage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:107 templates/risks/item_risk.html:108
|
#: templates/risks/item_risk.html:111 templates/risks/item_risk.html:112
|
||||||
#: templates/risks/item_risk.html:153 templates/risks/item_risk.html:154
|
#: templates/risks/item_risk.html:157 templates/risks/item_risk.html:158
|
||||||
#: templates/risks/list_risks.html:89
|
#: templates/risks/list_risks.html:121 templates/risks/list_risks.html:125
|
||||||
msgid "Level"
|
msgid "Level"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:116 templates/risks/item_risk.html:117
|
#: templates/risks/item_risk.html:120 templates/risks/item_risk.html:121
|
||||||
#: templates/risks/item_risk.html:161 templates/risks/item_risk.html:163
|
#: templates/risks/item_risk.html:165 templates/risks/item_risk.html:167
|
||||||
#: templates/risks/list_risks.html:88
|
#: templates/risks/list_risks.html:120 templates/risks/list_risks.html:124
|
||||||
|
#: templates/risks/risk_matrix.html:39
|
||||||
msgid "Score"
|
msgid "Score"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:130
|
#: templates/risks/item_risk.html:134
|
||||||
msgid "Net (after measures)"
|
msgid "Net (after measures)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:169
|
#: templates/risks/item_risk.html:173
|
||||||
msgid "No net risk recorded yet."
|
msgid "No net risk recorded yet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:180
|
#: templates/risks/item_risk.html:184
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:194
|
#: templates/risks/item_risk.html:198
|
||||||
msgid "Measures"
|
msgid "Measures"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:203
|
#: templates/risks/item_risk.html:207
|
||||||
msgid "Deadline"
|
msgid "Deadline"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:204
|
#: templates/risks/item_risk.html:208
|
||||||
msgid "Responsible"
|
msgid "Responsible"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:205
|
#: templates/risks/item_risk.html:209
|
||||||
msgid "Link"
|
msgid "Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:239
|
#: templates/risks/item_risk.html:243
|
||||||
msgid "No measures recorded."
|
msgid "No measures recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:257
|
#: templates/risks/item_risk.html:261
|
||||||
msgid "Reported on"
|
msgid "Reported on"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:271
|
#: templates/risks/item_risk.html:275
|
||||||
msgid "No incidents recorded."
|
msgid "No incidents recorded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:279
|
#: templates/risks/item_risk.html:283
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:286
|
#: templates/risks/item_risk.html:290
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:288
|
#: templates/risks/item_risk.html:292
|
||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/item_risk.html:302
|
#: templates/risks/item_risk.html:306
|
||||||
msgid "No History found."
|
msgid "No History found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -575,20 +757,31 @@ msgstr ""
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:22 templates/risks/list_risks.html:41
|
#: templates/risks/list_risks.html:83
|
||||||
#: templates/risks/list_risks.html:60 templates/risks/notifications.html:13
|
msgid "Owner"
|
||||||
msgid "All"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:56 templates/risks/list_risks.html:90
|
#: templates/risks/list_risks.html:111
|
||||||
msgid "Risk Owner"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/risks/list_risks.html:84
|
|
||||||
msgid "Asset / Process"
|
msgid "Asset / Process"
|
||||||
msgstr ""
|
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"
|
msgid "No risks present"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -596,6 +789,10 @@ msgstr ""
|
||||||
msgid "Unread"
|
msgid "Unread"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/risks/notifications.html:13
|
||||||
|
msgid "All"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: templates/risks/notifications.html:20
|
#: templates/risks/notifications.html:20
|
||||||
msgid "Mark all as read"
|
msgid "Mark all as read"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -611,3 +808,23 @@ msgstr ""
|
||||||
#: templates/risks/notifications.html:53
|
#: templates/risks/notifications.html:53
|
||||||
msgid "No notifications."
|
msgid "No notifications."
|
||||||
msgstr ""
|
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 ""
|
||||||
|
|
|
@ -10,6 +10,20 @@ _LIKELIHOOD_LABELS = dict(Risk.LIKELIHOOD_CHOICES)
|
||||||
_IMPACT_LABELS = dict(Risk.IMPACT_CHOICES)
|
_IMPACT_LABELS = dict(Risk.IMPACT_CHOICES)
|
||||||
LEVEL_ID_MAP = {"Low": 1, "Medium": 2, "High": 3, "Critical": 4}
|
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
|
@register.filter
|
||||||
def level_id(level):
|
def level_id(level):
|
||||||
return LEVEL_ID_MAP.get(str(level), "")
|
return LEVEL_ID_MAP.get(str(level), "")
|
||||||
|
@ -38,7 +52,7 @@ def likelihood_id_label(val):
|
||||||
return ""
|
return ""
|
||||||
label = _LIKELIHOOD_LABELS.get(i, "")
|
label = _LIKELIHOOD_LABELS.get(i, "")
|
||||||
short = _short(str(label)) if label else ""
|
short = _short(str(label)) if label else ""
|
||||||
return format_html("{}<br>({})", i, short) if label else format_html("{}", i)
|
return format_html("{} ({})", i, short) if label else format_html("{}", i)
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def impact_id_label(val):
|
def impact_id_label(val):
|
||||||
|
@ -48,7 +62,7 @@ def impact_id_label(val):
|
||||||
return ""
|
return ""
|
||||||
label = _IMPACT_LABELS.get(i, "")
|
label = _IMPACT_LABELS.get(i, "")
|
||||||
short = _short(str(label)) if label else ""
|
short = _short(str(label)) if label else ""
|
||||||
return format_html("{}<br>({})", i, short) if label else format_html("{}", i)
|
return format_html("{} ({})", i, short) if label else format_html("{}", i)
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
|
@ -131,4 +145,24 @@ def to_bg(css_class: str):
|
||||||
css = str(css_class)
|
css = str(css_class)
|
||||||
except Exception:
|
except Exception:
|
||||||
return ""
|
return ""
|
||||||
return css.replace("is-control-", "has-background-control-") if css.startswith("is-control-") else css
|
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"
|
|
@ -13,6 +13,7 @@ urlpatterns = [
|
||||||
path("risks/controls/<int:id>", views.show_control, name="show_control"),
|
path("risks/controls/<int:id>", views.show_control, name="show_control"),
|
||||||
path("risks/list_incidents", views.list_incidents, name="list_incidents"),
|
path("risks/list_incidents", views.list_incidents, name="list_incidents"),
|
||||||
path("risks/incidents/<int:id>", views.show_incident, name="show_incident"),
|
path("risks/incidents/<int:id>", views.show_incident, name="show_incident"),
|
||||||
|
path("risks/risk_matrix", views.risk_matrix, name="risk_matrix"),
|
||||||
|
|
||||||
# Notifications
|
# Notifications
|
||||||
path("notifications/", views.notifications, name="notifications"),
|
path("notifications/", views.notifications, name="notifications"),
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.shortcuts import redirect, render, get_object_or_404
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from collections import Counter
|
from collections import Counter, defaultdict
|
||||||
from .forms import RiskStatusForm, ControlStatusForm, IncidentStatusForm, ResidualReviewForm
|
from .forms import RiskStatusForm, ControlStatusForm, IncidentStatusForm, ResidualReviewForm
|
||||||
from .models import Risk, Control, ResidualRisk, AuditLog, Incident, Notification
|
from .models import Risk, Control, ResidualRisk, AuditLog, Incident, Notification
|
||||||
from .serializers import ControlSerializer, RiskSerializer, ResidualRiskSerializer, UserSerializer, AuditSerializer, IncidentSerializer
|
from .serializers import ControlSerializer, RiskSerializer, ResidualRiskSerializer, UserSerializer, AuditSerializer, IncidentSerializer
|
||||||
|
@ -119,12 +119,15 @@ def list_risks(request):
|
||||||
"""
|
"""
|
||||||
View for listing all Risks
|
View for listing all Risks
|
||||||
"""
|
"""
|
||||||
qs = Risk.objects.all().select_related("owner")
|
qs = Risk.objects.all().select_related("owner", "residual_risk")
|
||||||
|
|
||||||
# GET-Parameter lesen
|
# GET-Parameter lesen
|
||||||
risk_id = request.GET.get("risk")
|
risk_id = request.GET.get("risk")
|
||||||
control_id = request.GET.get("control")
|
control_id = request.GET.get("control")
|
||||||
owner_id = request.GET.get("owner")
|
owner_id = request.GET.get("owner")
|
||||||
|
category = request.GET.get("category")
|
||||||
|
asset = request.GET.get("asset")
|
||||||
|
process = request.GET.get("process")
|
||||||
|
|
||||||
if risk_id:
|
if risk_id:
|
||||||
qs = qs.filter(id=risk_id)
|
qs = qs.filter(id=risk_id)
|
||||||
|
@ -132,16 +135,43 @@ def list_risks(request):
|
||||||
qs = qs.filter(controls__id=control_id)
|
qs = qs.filter(controls__id=control_id)
|
||||||
if owner_id:
|
if owner_id:
|
||||||
qs = qs.filter(owner_id=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()
|
risks = qs.order_by("title").distinct()
|
||||||
|
|
||||||
controls = Control.objects.all().order_by("title")
|
controls = Control.objects.all().order_by("title")
|
||||||
owners = User.objects.filter(owned_risks__isnull=False).distinct().order_by("username")
|
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", {
|
return render(request, "risks/list_risks.html", {
|
||||||
"risks": risks,
|
"risks": risks,
|
||||||
"controls": controls,
|
"controls": controls,
|
||||||
"owners": owners,
|
"owners": owners,
|
||||||
|
"categories": categories,
|
||||||
|
"assets": assets,
|
||||||
|
"processes": processes,
|
||||||
})
|
})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -382,4 +412,31 @@ def update_residual_review(request, risk_id):
|
||||||
obj._changed_by = request.user
|
obj._changed_by = request.user
|
||||||
obj.save(update_fields=["review_required", "updated_at"])
|
obj.save(update_fields=["review_required", "updated_at"])
|
||||||
messages.success(request, _("Residual review flag updated."))
|
messages.success(request, _("Residual review flag updated."))
|
||||||
return redirect("risks:show_risk", id=risk.pk)
|
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,
|
||||||
|
})
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/* Base palette */
|
/* Base palette */
|
||||||
:root{
|
: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-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-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-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) */
|
/* Helpers (wie Bulma) */
|
||||||
|
@ -80,6 +80,9 @@
|
||||||
.progress.is-control-high::-moz-progress-bar{background:var(--c-high)}
|
.progress.is-control-high::-moz-progress-bar{background:var(--c-high)}
|
||||||
.progress.is-control-veryhigh::-moz-progress-bar{background:var(--c-veryhigh)}
|
.progress.is-control-veryhigh::-moz-progress-bar{background:var(--c-veryhigh)}
|
||||||
|
|
||||||
|
abbr {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Topbar-Farbe erzwingen (Bulma überschreibt sonst mit weiß) */
|
/* Topbar-Farbe erzwingen (Bulma überschreibt sonst mit weiß) */
|
||||||
.navbar.topbar-nav {
|
.navbar.topbar-nav {
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
<a class="navbar-link">{% trans "Risk Management" %}</a>
|
<a class="navbar-link">{% trans "Risk Management" %}</a>
|
||||||
<div class="navbar-dropdown">
|
<div class="navbar-dropdown">
|
||||||
<a class="navbar-item" href="/risks/index">{% trans "Dashboard" %}</a>
|
<a class="navbar-item" href="/risks/index">{% trans "Dashboard" %}</a>
|
||||||
|
<a class="navbar-item" href="/risks/risk_matrix">{% trans "Risk Matrix" %}</a>
|
||||||
|
<hr class="navbar-divider">
|
||||||
<a class="navbar-item" href="/risks/list_risks">{% trans "Risk analysis" %}</a>
|
<a class="navbar-item" href="/risks/list_risks">{% trans "Risk analysis" %}</a>
|
||||||
<a class="navbar-item" href="/risks/list_controls">{% trans "Controls" %}</a>
|
<a class="navbar-item" href="/risks/list_controls">{% trans "Controls" %}</a>
|
||||||
<a class="navbar-item" href="/risks/list_incidents">{% trans "Incidents" %}</a>
|
<a class="navbar-item" href="/risks/list_incidents">{% trans "Incidents" %}</a>
|
||||||
|
|
|
@ -9,68 +9,89 @@
|
||||||
<h2 class="title is-5">{% trans "Filter" %}</h2>
|
<h2 class="title is-5">{% trans "Filter" %}</h2>
|
||||||
|
|
||||||
<!-- Filter -->
|
<!-- Filter -->
|
||||||
<form method="get">
|
<form method="get" class="mb-4">
|
||||||
<div class="columns is-multiline">
|
<div class="columns is-multiline">
|
||||||
|
|
||||||
<!-- Risiko Filter -->
|
<div class="column is-2">
|
||||||
<div class="column is-3">
|
<div class="select is-small is-fullwidth">
|
||||||
<div class="field">
|
<select name="risk" onchange="this.form.submit()">
|
||||||
<label class="label">{% trans "Risk" %}</label>
|
<option value="">{% trans "Risk" %}</option>
|
||||||
<div class="control">
|
{% for r in risks %}
|
||||||
<div class="select is-fullwidth">
|
<option value="{{ r.id }}" {% if request.GET.risk == r.id|stringformat:"s" %}selected{% endif %}>
|
||||||
<select name="risk" onchange="this.form.submit()">
|
{{ r.title }}
|
||||||
<option value="">{% trans "All" %}</option>
|
</option>
|
||||||
{% for r in risks %}
|
{% endfor %}
|
||||||
<option value="{{ r.id }}" {% if request.GET.risk == r.id|stringformat:"s" %}selected{% endif %}>
|
</select>
|
||||||
{{ r.title }}
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Maßnahmen Filter -->
|
<div class="column is-2">
|
||||||
<div class="column is-3">
|
<div class="select is-small is-fullwidth">
|
||||||
<div class="field">
|
<select name="control" onchange="this.form.submit()">
|
||||||
<label class="label">{% trans "Controls" %}</label>
|
<option value="">{% trans "Controls" %}</option>
|
||||||
<div class="control">
|
{% for c in controls %}
|
||||||
<div class="select is-fullwidth">
|
<option value="{{ c.id }}" {% if request.GET.control == c.id|stringformat:"s" %}selected{% endif %}>
|
||||||
<select name="control" onchange="this.form.submit()">
|
{{ c.title }}
|
||||||
<option value="">{% trans "All" %}</option>
|
</option>
|
||||||
{% for c in controls %}
|
{% endfor %}
|
||||||
<option value="{{ c.id }}" {% if request.GET.control == c.id|stringformat:"s" %}selected{% endif %}>
|
</select>
|
||||||
{{ c.title }}
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Risikoeigner Filter -->
|
<div class="column is-2">
|
||||||
<div class="column is-3">
|
<div class="select is-small is-fullwidth">
|
||||||
<div class="field">
|
<select name="category" onchange="this.form.submit()">
|
||||||
<label class="label">{% trans "Risk Owner" %}</label>
|
<option value="">{% trans "Category" %}</option>
|
||||||
<div class="control">
|
{% for cat in categories %}
|
||||||
<div class="select is-fullwidth">
|
<option value="{{ cat }}" {% if request.GET.category == cat|stringformat:"s" %}selected{% endif %}>
|
||||||
<select name="owner" onchange="this.form.submit()">
|
{{ cat }}
|
||||||
<option value="">{% trans "All" %}</option>
|
</option>
|
||||||
{% for u in owners %}
|
{% endfor %}
|
||||||
<option value="{{ u.id }}" {% if request.GET.owner == u.id|stringformat:"s" %}selected{% endif %}>
|
</select>
|
||||||
{{ u.get_full_name|default:u.username }}
|
</div>
|
||||||
</option>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
</select>
|
<div class="column is-2">
|
||||||
</div>
|
<div class="select is-small is-fullwidth">
|
||||||
</div>
|
<select name="asset" onchange="this.form.submit()">
|
||||||
|
<option value="">{% trans "Asset" %}</option>
|
||||||
|
{% for a in assets %}
|
||||||
|
<option value="{{ a }}" {% if request.GET.asset == a|stringformat:"s" %}selected{% endif %}>
|
||||||
|
{{ a }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-2">
|
||||||
|
<div class="select is-small is-fullwidth">
|
||||||
|
<select name="process" onchange="this.form.submit()">
|
||||||
|
<option value="">{% trans "Process" %}</option>
|
||||||
|
{% for p in processes %}
|
||||||
|
<option value="{{ p }}" {% if request.GET.process == p|stringformat:"s" %}selected{% endif %}>
|
||||||
|
{{ p }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-2">
|
||||||
|
<div class="select is-small is-fullwidth">
|
||||||
|
<select name="owner" onchange="this.form.submit()">
|
||||||
|
<option value="">{% trans "Owner" %}</option>
|
||||||
|
{% for u in owners %}
|
||||||
|
<option value="{{ u.id }}" {% if request.GET.owner == u.id|stringformat:"s" %}selected{% endif %}>
|
||||||
|
{{ u.get_full_name|default:u.username }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form> <!-- Filter Ende -->
|
||||||
|
|
||||||
|
|
||||||
<h2 class="title is-5">{% trans "Risks" %}</h2>
|
<h2 class="title is-5">{% trans "Risks" %}</h2>
|
||||||
|
@ -79,36 +100,32 @@
|
||||||
<table class="table is-bordered is-striped is-hoverable is-fullwidth">
|
<table class="table is-bordered is-striped is-hoverable is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{% if request.user.is_staff %}<th></th>{% endif %}
|
{% if request.user.is_staff %}
|
||||||
<th>{% trans "Risk" %}</th>
|
<th rowspan="2" class="has-text-centered">
|
||||||
<th>{% trans "Asset / Process" %}</th>
|
|
||||||
<th>{% trans "Category" %}</th>
|
|
||||||
<th>{% trans "Likelihood" %}</th>
|
|
||||||
<th>{% trans "Impact" %}</th>
|
|
||||||
<th>{% trans "Score" %}</th>
|
|
||||||
<th>{% trans "Level" %}</th>
|
|
||||||
<th>{% trans "Risk Owner" %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% if request.user.is_staff %}
|
|
||||||
<tr>
|
|
||||||
|
|
||||||
<td class="has-text-centered">
|
|
||||||
<a class="icon has-text-success" href="{% url 'admin:risks_risk_add' %}" title="Risiko hinzufügen">
|
<a class="icon has-text-success" href="{% url 'admin:risks_risk_add' %}" title="Risiko hinzufügen">
|
||||||
<i class="fas fa-add"></i>
|
<i class="fas fa-add"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</th>
|
||||||
<td></td>
|
{% endif %}
|
||||||
<td></td>
|
<th rowspan="2" class="has-text-centered">{% trans "Risk" %}</th>
|
||||||
<td></td>
|
<th rowspan="2" class="has-text-centered">{% trans "Asset / Process" %}</th>
|
||||||
<td></td>
|
<th rowspan="2" class="has-text-centered">{% trans "Category" %}</th>
|
||||||
<td></td>
|
<th rowspan="2" class="has-text-centered">{% trans "Risk Owner" %}</th>
|
||||||
<td></td>
|
<th colspan="4" class="has-text-centered has-background-light">{% trans "Gross Risk" %}</th>
|
||||||
<td></td>
|
<th colspan="4" class="has-text-centered has-background-info-light">{% trans "Net Risk" %}</th>
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
<tr>
|
||||||
|
<th class="has-text-centered has-background-light">{% trans "Likelihood" %}</th>
|
||||||
|
<th class="has-text-centered has-background-light">{% trans "Impact" %}</th>
|
||||||
|
<th class="has-text-centered has-background-light">{% trans "Score" %}</th>
|
||||||
|
<th class="has-text-centered has-background-light">{% trans "Level" %}</th>
|
||||||
|
<th class="has-text-centered has-background-info-light">{% trans "Likelihood" %}</th>
|
||||||
|
<th class="has-text-centered has-background-info-light">{% trans "Impact" %}</th>
|
||||||
|
<th class="has-text-centered has-background-info-light">{% trans "Score" %}</th>
|
||||||
|
<th class="has-text-centered has-background-info-light">{% trans "Level" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{% for r in risks %}
|
{% for r in risks %}
|
||||||
<tr>
|
<tr>
|
||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
|
@ -126,19 +143,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" style="cursor:pointer;">{{ r.category }}</td>
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" style="cursor:pointer;">{{ r.category }}</td>
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.likelihood|likelihood_class|to_bg }}" style="cursor:pointer;">
|
|
||||||
{{ r.likelihood|likelihood_id_label }}
|
|
||||||
</td>
|
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.impact|impact_class|to_bg }}" style="cursor:pointer;">
|
|
||||||
{{ r.impact|impact_id_label }}
|
|
||||||
</td>
|
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.score|score_class|to_bg }}" style="cursor:pointer;">
|
|
||||||
{{ r.score }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.level|level_class|to_bg }}" style="cursor:pointer;">
|
|
||||||
{{ r.level }}
|
|
||||||
</td>
|
|
||||||
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" style="cursor:pointer;">
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" style="cursor:pointer;">
|
||||||
{% if r.owner %}
|
{% if r.owner %}
|
||||||
{{ r.owner|user_display }}
|
{{ r.owner|user_display }}
|
||||||
|
@ -146,6 +150,51 @@
|
||||||
–
|
–
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<!-- Brutto Risiko -->
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.likelihood|likelihood_class|to_bg }}" style="cursor:pointer;">
|
||||||
|
<abbr title="{{ r.likelihood|likelihood_id_label }}">{{ r.likelihood }}</abbr>
|
||||||
|
</td>
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.impact|impact_class|to_bg }}" style="cursor:pointer;">
|
||||||
|
<abbr title="{{ r.impact|impact_id_label }}">{{ r.impact }}</abbr>
|
||||||
|
</td>
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.score|score_class|to_bg }}" style="cursor:pointer;">
|
||||||
|
{{ r.score }} / 20
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'" class="has-text-centered {{ r.level|level_class|to_bg }}" style="cursor:pointer;">
|
||||||
|
{{ r.level }}
|
||||||
|
</td>
|
||||||
|
<!-- Netto Risiko -->
|
||||||
|
{% if r.residual_risk %}
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'"
|
||||||
|
class="has-text-centered {{ r.residual_risk.likelihood|likelihood_class|to_bg }}"
|
||||||
|
style="cursor:pointer;">
|
||||||
|
<abbr title="{{ r.residual_risk.likelihood|likelihood_id_label }}">
|
||||||
|
{{ r.residual_risk.likelihood }}
|
||||||
|
</abbr>
|
||||||
|
</td>
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'"
|
||||||
|
class="has-text-centered {{ r.residual_risk.impact|impact_class|to_bg }}"
|
||||||
|
style="cursor:pointer;">
|
||||||
|
<abbr title="{{ r.residual_risk.impact|impact_id_label }}">
|
||||||
|
{{ r.residual_risk.impact }}
|
||||||
|
</abbr>
|
||||||
|
</td>
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'"
|
||||||
|
class="has-text-centered {{ r.residual_risk.score|score_class|to_bg }}"
|
||||||
|
style="cursor:pointer;">
|
||||||
|
{{ r.residual_risk.score }} / 20
|
||||||
|
</td>
|
||||||
|
<td onclick="window.location.href='{% url 'risks:show_risk' r.id %}'"
|
||||||
|
class="has-text-centered {{ r.residual_risk.level|level_class|to_bg }}"
|
||||||
|
style="cursor:pointer;">
|
||||||
|
{{ r.residual_risk.level }}
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td colspan="4" class="has-text-centered has-text-grey">
|
||||||
|
{% trans "No residual risk defined" %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
|
|
185
templates/risks/risk_matrix.html
Normal file
185
templates/risks/risk_matrix.html
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load i18n risk_extras %}
|
||||||
|
{% block crumbs %}
|
||||||
|
<li><a href="{% url 'risks:risk_matrix' %}">{% trans "Risk Matrix" %}</a></li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<section class="section">
|
||||||
|
|
||||||
|
<!-- Tabs -->
|
||||||
|
<div class="tabs is-boxed" role="tablist">
|
||||||
|
<ul>
|
||||||
|
<li class="is-active" data-tab="riskmatrix" role="tab" aria-selected="true"><a>{% trans "Risk Matrix" %}</a></li>
|
||||||
|
<li data-tab="details" role="tab" aria-selected="false"><a>{% trans "Detail View" %}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<h2 class="title is-4">{% trans "Risk Matrix" %}</h2>
|
||||||
|
|
||||||
|
{# Panel: Brutto (Score-Matrix) #}
|
||||||
|
<div class="tab-panel" data-tab="riskmatrix">
|
||||||
|
<table class="table is-bordered has-text-centered risk-matrix-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-left">{% trans "Impact" %} / {% trans "Likelihood" %}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
<th class="py-6 {{ l_val|likelihood_class|to_bg }}">{{ l_label }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for i_val, i_label in impacts reversed %}
|
||||||
|
<tr>
|
||||||
|
<th class="py-6 has-text-left {{ i_val|impact_class|to_bg }}">{{ i_label }}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
{% with s=i_val|mul:l_val %}
|
||||||
|
<td class="risk-matrix-cell {{ s|score_bg_class }}">
|
||||||
|
<div class="is-flex is-justify-content-center is-align-items-center py-6">
|
||||||
|
<span class="tag is-light is-rounded">{% trans "Score" %} {{ s }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Panel: Details (Listen je Zelle, mit Brutto/Netto-Umschalter) #}
|
||||||
|
<div class="tab-panel is-hidden" data-tab="details">
|
||||||
|
<div class="level mb-3">
|
||||||
|
<div class="level-left">
|
||||||
|
<div class="level-item"><strong>{% trans "Show" %}:</strong></div>
|
||||||
|
<div class="level-item">
|
||||||
|
<div class="buttons has-addons">
|
||||||
|
<button type="button" class="button is-small is-info is-light details-toggle is-active" data-mode="gross">
|
||||||
|
{% trans "Gross" %}
|
||||||
|
</button>
|
||||||
|
<button type="button" class="button is-small is-info is-light details-toggle" data-mode="net">
|
||||||
|
{% trans "Net" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Brutto-Listen #}
|
||||||
|
<div class="details-table" data-mode="gross">
|
||||||
|
<table class="table is-bordered has-text-centered risk-matrix-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-left">{% trans "Impact" %} / {% trans "Likelihood" %}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
<th class="py-6 {{ l_val|likelihood_class|to_bg }}">{{ l_label }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for i_val, i_label in impacts reversed %}
|
||||||
|
<tr>
|
||||||
|
<th class="py-6 has-text-left {{ i_val|impact_class|to_bg }}">{{ i_label }}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
{% with row=gross_matrix|dict_get:i_val %}
|
||||||
|
{% with cell=row|dict_get:l_val %}
|
||||||
|
{% with s=i_val|mul:l_val %}
|
||||||
|
<td class="risk-matrix-cell {{ s|score_bg_class }}">
|
||||||
|
{% if cell and cell|length %}
|
||||||
|
<ul class="risk-cell-list">
|
||||||
|
{% for risk in cell %}
|
||||||
|
<li style="list-style: none;">
|
||||||
|
<a href="{% url 'risks:show_risk' risk.id %}" class="tag">{{ risk.title }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<span class="has-text-grey">–</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Netto-Listen #}
|
||||||
|
<div class="details-table is-hidden" data-mode="net">
|
||||||
|
<table class="table is-bordered has-text-centered risk-matrix-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-left">{% trans "Impact" %} / {% trans "Likelihood" %}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
<th class="py-6 {{ l_val|likelihood_class|to_bg }}">{{ l_label }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for i_val, i_label in impacts reversed %}
|
||||||
|
<tr>
|
||||||
|
<th class="py-6 has-text-left {{ i_val|impact_class|to_bg }}">{{ i_label }}</th>
|
||||||
|
{% for l_val, l_label in likelihoods %}
|
||||||
|
{% with row=net_matrix|dict_get:i_val %}
|
||||||
|
{% with cell=row|dict_get:l_val %}
|
||||||
|
{% with s=i_val|mul:l_val %}
|
||||||
|
<td class="risk-matrix-cell {{ s|score_bg_class }}">
|
||||||
|
{% if cell and cell|length %}
|
||||||
|
<ul class="risk-cell-list">
|
||||||
|
{% for risk in cell %}
|
||||||
|
<li style="list-style: none;">
|
||||||
|
<a href="{% url 'risks:show_risk' risk.id %}" class="tag">{{ risk.title }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<span class="has-text-grey">–</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.risk-matrix-table th, .risk-matrix-table td { padding: .5rem; }
|
||||||
|
.risk-matrix-cell { min-height: 120px; vertical-align: middle; }
|
||||||
|
.tab-panel.is-hidden { display: none; }
|
||||||
|
.risk-cell-list { text-align: left; margin: 0; padding-left: 1rem; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Tabs
|
||||||
|
const tabs = document.querySelectorAll('.tabs li[data-tab]');
|
||||||
|
const panels = document.querySelectorAll('.tab-panel');
|
||||||
|
tabs.forEach(t => t.addEventListener('click', () => {
|
||||||
|
tabs.forEach(x => { x.classList.remove('is-active'); x.setAttribute('aria-selected','false'); });
|
||||||
|
t.classList.add('is-active'); t.setAttribute('aria-selected','true');
|
||||||
|
const target = t.getAttribute('data-tab');
|
||||||
|
panels.forEach(p => p.classList.toggle('is-hidden', p.getAttribute('data-tab') !== target));
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Umschalter im „Details“-Tab
|
||||||
|
const toggles = document.querySelectorAll('.details-toggle');
|
||||||
|
const tables = document.querySelectorAll('.details-table');
|
||||||
|
toggles.forEach(btn => btn.addEventListener('click', () => {
|
||||||
|
const mode = btn.getAttribute('data-mode'); // 'gross' | 'net'
|
||||||
|
toggles.forEach(b => b.classList.toggle('is-active', b === btn));
|
||||||
|
tables.forEach(t => t.classList.toggle('is-hidden', t.getAttribute('data-mode') !== mode));
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
Loading…
Add table
Reference in a new issue