
- 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.
185 lines
7.4 KiB
HTML
185 lines
7.4 KiB
HTML
{% 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 %}
|