ISO-27001-Risk-Management/templates/risks/risk_matrix.html
Kevin Heyer 9d02badf14 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.
2025-09-11 10:22:20 +02:00

185 lines
7.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% 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 %}