Skip to content

Commit dd20d4d

Browse files
committed
Add features to the dependency tree view #1145
Signed-off-by: tdruez <tdruez@nexb.com>
1 parent f0efc3a commit dd20d4d

4 files changed

Lines changed: 78 additions & 2 deletions

File tree

scanpipe/templates/scanpipe/includes/project_list_table.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
<a href="{% url 'project_dependencies' project.slug %}">
2929
{{ project.discovereddependencies_count|intcomma }}
3030
</a>
31+
<a href="{% url 'project_dependency_tree' project.slug %}">
32+
<span class="icon">
33+
<i class="fa-solid fa-sitemap"></i>
34+
</span>
35+
</a>
3136
{% else %}
3237
<span>0</span>
3338
{% endif %}

scanpipe/templates/scanpipe/project_dependency_tree.html

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
line-height: 1.8rem;
1111
--spacing : 2rem;
1212
}
13+
.tree summary {
14+
display: inline-block;
15+
}
1316
.tree summary::before{
1417
background-color: rgb(72, 199, 142);
1518
background-image: url('{% static "tree-views/expand-collapse.svg" %}');
@@ -51,9 +54,21 @@
5154
<i class="fas fa-plus"></i>
5255
</span>
5356
</button>
57+
<button id="showVulnerableOnlyButton" class="button is-outlined is-small">
58+
<span>Show Vulnerable only</span>
59+
<span class="icon is-small">
60+
<i class="fa-solid fa-bug"></i>
61+
</span>
62+
</button>
63+
<button id="showComplianceAlertOnlyButton" class="button is-outlined is-small">
64+
<span>Show Compliance Alert only</span>
65+
<span class="icon is-small ">
66+
<i class="fa-solid fa-scale-balanced"></i>
67+
</span>
68+
</button>
5469
</div>
5570

56-
<ul class="tree">
71+
<ul id="tree" class="tree">
5772
<li>
5873
<details open>
5974
<summary class="has-text-weight-semibold">
@@ -69,22 +84,74 @@
6984

7085
{% block scripts %}
7186
<script>
87+
document.addEventListener('DOMContentLoaded', () => {
88+
const treeContainer = document.getElementById('tree');
7289
const collapseAllButton = document.getElementById('collapseAll');
7390
const expendAllButton = document.getElementById('expendAll');
7491

7592
function collapseAllDetails() {
7693
document.querySelectorAll('details').forEach(details => {
7794
details.removeAttribute('open');
7895
});
96+
showAllListItems();
7997
}
8098

8199
function expendAllDetails() {
82100
document.querySelectorAll('details').forEach(details => {
83101
details.setAttribute('open', ''); // Adding 'open' attribute to open the details
84102
});
103+
showAllListItems();
85104
}
86105

87106
collapseAllButton.addEventListener('click', collapseAllDetails);
88107
expendAllButton.addEventListener('click', expendAllDetails);
108+
109+
// Following function are use to limit the display to specific elements.
110+
111+
function expandAncestors(detailsElement) {
112+
let parent = detailsElement.parentElement.closest('details');
113+
while (parent) {
114+
parent.setAttribute('open', '');
115+
parent.parentElement.style.display = '';
116+
parent = parent.parentElement.closest('details');
117+
}
118+
}
119+
120+
function showAllListItems() {
121+
const listItems = treeContainer.querySelectorAll('li');
122+
listItems.forEach(item => {
123+
item.style.display = '';
124+
});
125+
}
126+
127+
function hideAllListItems() {
128+
const listItems = treeContainer.querySelectorAll('li');
129+
listItems.forEach(item => {
130+
item.style.display = 'none';
131+
});
132+
}
133+
134+
function handleItems(attribute, value) {
135+
collapseAllDetails();
136+
hideAllListItems();
137+
138+
const items = document.querySelectorAll(`li[${attribute}="${value}"]`);
139+
items.forEach(item => {
140+
item.style.display = 'block';
141+
expandAncestors(item);
142+
});
143+
}
144+
145+
function handleVulnerableItems() {
146+
handleItems('data-is-vulnerable', 'true');
147+
}
148+
149+
function handleComplianceAlertItems() {
150+
handleItems('data-compliance-alert', 'true');
151+
}
152+
153+
showVulnerableOnlyButton.addEventListener('click', handleVulnerableItems);
154+
showComplianceAlertOnlyButton.addEventListener('click', handleComplianceAlertItems);
155+
});
89156
</script>
90157
{% endblock %}

scanpipe/templates/scanpipe/tree/children.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<ul>
22
{% for node in children %}
3-
<li>
3+
<li
4+
{% if node.is_vulnerable %} data-is-vulnerable="true"{% endif %}
5+
{% if node.compliance_alert == "warning" or node.compliance_alert == "error" %} data-compliance-alert="true"{% endif %}
6+
>
47
{% if node.children %}
58
<details class="my-1" open>
69
<summary>

scanpipe/views.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,7 @@ class DiscoveredPackageDetailsView(
19271927
"field_name": "other_license_expression_spdx",
19281928
"label": "Other license expression (SPDX)",
19291929
},
1930+
"compliance_alert",
19301931
"extracted_license_statement",
19311932
"copyright",
19321933
"holder",

0 commit comments

Comments
 (0)