Skip to content

Commit 4c5e620

Browse files
committed
add filtering support
Signed-off-by: Aayush Kumar <[email protected]>
1 parent d7dfce4 commit 4c5e620

File tree

6 files changed

+236
-111
lines changed

6 files changed

+236
-111
lines changed

scanpipe/filters.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,13 +522,25 @@ def filter(self, qs, value):
522522

523523

524524
class ResourceFilterSet(FilterSetUtilsMixin, django_filters.FilterSet):
525+
526+
detected_license_expression = django_filters.ChoiceFilter(
527+
label="Detected license expression",
528+
choices=[
529+
("", "All"),
530+
("_EMPTY_", "None"),
531+
("_ANY_", "Any"),
532+
],
533+
widget=HasValueDropdownWidget(),
534+
)
535+
525536
dropdown_widget_fields = [
526537
"status",
527538
"type",
528539
"tag",
529540
"compliance_alert",
530541
"in_package",
531542
"relation_map_type",
543+
"detected_license_expression",
532544
]
533545

534546
search = QuerySearchFilter(
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1-
<div class="dropdown is-hoverable {% if is_right %}is-right{% endif %}">
1+
<div class="dropdown is-hoverable{% if is_right %} is-right{% endif %}">
22
<div class="dropdown-trigger">
3-
<a class="{% if filter.data %}has-text-link{% else %}is-grey-link{% endif %}" aria-haspopup="true" aria-controls="{{ filter.id_for_label }}">
3+
<a class="{% if filter.value or filter.data %}has-text-link{% else %}is-grey-link{% endif %}" aria-haspopup="true" aria-controls="{{ filter.id_for_label }}">
44
<span class="icon width-1 height-1"><i class="fa-solid fa-filter"></i></span>
55
</a>
66
</div>
77
<div class="dropdown-menu" id="{{ filter.id_for_label }}" role="menu">
8-
<div class="dropdown-content">
9-
{{ filter }}
8+
<div class="dropdown-content p-2">
9+
{% if is_htmx %}
10+
<form
11+
action=""
12+
method="get"
13+
hx-get="{% url 'codebase_resource_table' project.slug %}"
14+
hx-target="#right-pane"
15+
hx-push-url="false"
16+
hx-vals='{"path": "{{ path|escapejs }}"}'
17+
>
18+
<div class="select is-small">
19+
<select
20+
name="{{ filter.name }}"
21+
id="filter-select-{{ filter.name }}"
22+
onchange="this.form.requestSubmit()"
23+
>
24+
{% for val, label in filter.field.choices %}
25+
<option value="{{ val }}" {% if filter.value == val %}selected{% endif %}>{{ label }}</option>
26+
{% endfor %}
27+
</select>
28+
</div>
29+
</form>
30+
{% else %}
31+
{{ filter }}
32+
{% endif %}
1033
</div>
1134
</div>
1235
</div>
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
<a href="?{{ column.sort_query }}" class="is-black-link">
1+
<a
2+
class="is-black-link"
3+
href="?path={{ path|urlencode }}&sort={% if column.is_sorted and column.sort_direction == '-' %}{{ column.field_name }}{% else %}-{{ column.field_name }}{% endif %}"
4+
{% if is_htmx %}
5+
hx-get="{% url 'codebase_resource_table' project.slug %}"
6+
hx-target="#right-pane"
7+
hx-push-url="false"
8+
hx-vals='{"path": "{{ path|escapejs }}", "sort": "{% if column.is_sorted and column.sort_direction == '-' %}{{ column.field_name }}{% else %}-{{ column.field_name }}{% endif %}"}'
9+
onclick="return false;"
10+
style="cursor:pointer;"
11+
{% endif %}
12+
>
213
{{ column.label }}
3-
</a>
4-
{% if column.is_sorted %}
5-
<i class="fa-solid fa-sort-{% if column.sort_direction == "-" %}down{% else %}up{% endif %}"></i>
6-
{% endif %}
14+
{% if column.is_sorted %}
15+
<i class="fa-solid fa-sort-{% if column.sort_direction == '-' %}down{% else %}up{% endif %}"></i>
16+
{% endif %}
17+
</a>

scanpipe/templates/scanpipe/includes/list_view_thead.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
<div class="is-flex is-justify-content-space-between">
1111
<div>
1212
{% if column.sort_query %}
13-
{% include 'scanpipe/includes/filter_sort.html' with column=column only %}
13+
{% include 'scanpipe/includes/filter_sort.html' with column=column is_htmx=False path=path only %}
1414
{% else %}
1515
{{ column.label }}
1616
{% endif %}
1717
</div>
1818
{% if column.filter %}
1919
<div class="ml-1">
20-
{% include 'scanpipe/dropdowns/filter_dropdown_choices_field.html' with filter=column.filter is_right=column.filter_is_right only %}
20+
{% include 'scanpipe/dropdowns/filter_dropdown_choices_field.html' with filter=column.filter is_right=column.filter_is_right is_htmx=False path=path only %}
2121
</div>
2222
{% endif %}
2323
</div>
Lines changed: 81 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,90 @@
11
{% load humanize %}
22

3+
<div id="right-pane">
34
{% if resources %}
45
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
56
<thead class="is-sticky">
6-
<tr>
7-
<th>Path</th>
8-
<th>Status</th>
9-
<th>Type</th>
10-
<th>Size</th>
11-
<th>Name</th>
12-
<th>Extension</th>
13-
<th>Language</th>
14-
<th>MIME Type</th>
15-
<th>Tag</th>
16-
<th>License</th>
17-
<th>Alert</th>
18-
<th>Packages</th>
19-
</tr>
20-
</thead>
21-
<tbody>
22-
{% for resource in resources %}
23-
<tr>
24-
<td class="break-all" style="min-width: 200px;">
25-
{% if resource.is_dir %}
26-
{{ resource.path }}
27-
{% else %}
28-
<a href="{% url 'resource_detail' project.slug resource.path %}">{{ resource.path }}</a>
29-
{% endif %}
30-
</td>
31-
<td>
32-
{{ resource.status }}
33-
</td>
34-
<td>
35-
{{ resource.type }}
36-
</td>
37-
<td>
38-
{% if resource.is_file %}
39-
{{ resource.size|filesizeformat|default_if_none:"" }}
40-
{% endif %}
41-
</td>
42-
<td class="break-all" style="min-width: 100px;">
43-
{{ resource.name }}
44-
</td>
45-
<td>
46-
{{ resource.extension }}
47-
</td>
48-
<td class="break-all">
49-
{{ resource.programming_language }}
50-
</td>
51-
<td class="break-all">
52-
{{ resource.mime_type }}
53-
</td>
54-
<td>
55-
{{ resource.tag }}
56-
</td>
57-
<td>
58-
{{ resource.detected_license_expression }}
59-
</td>
60-
<td>
61-
{{ resource.compliance_alert }}
62-
</td>
63-
<td>
64-
{% if resource.discovered_packages.all %}
65-
{% for package in resource.discovered_packages.all|slice:":3" %}
66-
<a href="{% url 'project_packages' project.slug %}?purl={{ package.package_url }}">{{ package }}</a>{% if not forloop.last %}, {% endif %}
67-
{% endfor %}
68-
{% if resource.discovered_packages.all|length > 3 %}
69-
+{{ resource.discovered_packages.all|length|add:"-3" }} more
7+
<tr>
8+
{% if select_all %}
9+
<th class="p-2">
10+
<input type="checkbox" id="select-all">
11+
</th>
12+
{% endif %}
13+
{% for column in columns_data %}
14+
<th id="column-{{ column.field_name }}" {% if column.css_class %}class="{{ column.css_class }}"{% elif column.field_name in filter.data.sort %}class="nowrap"{% endif %}>
15+
<div class="is-flex is-justify-content-space-between">
16+
<div>
17+
{% if column.sort_query %}
18+
{% include 'scanpipe/includes/filter_sort.html' with column=column is_htmx=True project=project path=path only %}
19+
{% else %}
20+
{{ column.label }}
7021
{% endif %}
22+
</div>
23+
{% if column.filter %}
24+
<div class="ml-1">
25+
{% include 'scanpipe/dropdowns/filter_dropdown_choices_field.html' with filter=column.filter is_right=True is_htmx=True project=project path=path only %}
26+
</div>
7127
{% endif %}
72-
</td>
73-
</tr>
28+
</div>
29+
</th>
7430
{% endfor %}
75-
</tbody>
31+
</tr>
32+
</thead>
33+
<tbody>
34+
{% for resource in resources %}
35+
<tr>
36+
<td class="break-all" style="min-width: 200px;">
37+
{% if resource.type == "directory" %}
38+
{{ resource.path }}
39+
{% else %}
40+
<a href="{% url 'resource_detail' project.slug resource.path %}">{{ resource.path }}</a>
41+
{% endif %}
42+
</td>
43+
<td>
44+
{{ resource.status }}
45+
</td>
46+
<td>
47+
{{ resource.type }}
48+
</td>
49+
<td>
50+
{% if resource.type != "directory" %}
51+
{{ resource.size|filesizeformat|default_if_none:"" }}
52+
{% endif %}
53+
</td>
54+
<td class="break-all" style="min-width: 100px;">
55+
{{ resource.name }}
56+
</td>
57+
<td>
58+
{{ resource.extension }}
59+
</td>
60+
<td class="break-all">
61+
{{ resource.programming_language }}
62+
</td>
63+
<td class="break-all">
64+
{{ resource.mime_type }}
65+
</td>
66+
<td>
67+
{{ resource.tag }}
68+
</td>
69+
<td>
70+
{{ resource.detected_license_expression }}
71+
</td>
72+
<td>
73+
{{ resource.compliance_alert }}
74+
</td>
75+
<td>
76+
{% if resource.discovered_packages.all %}
77+
{% for package in resource.discovered_packages.all|slice:"0:3" %}
78+
<a href="{% url 'project_packages' project.slug %}?purl={{ package.package_url }}">{{ package }}</a>{% if not forloop.last %}, {% endif %}
79+
{% endfor %}
80+
{% if resource.discovered_packages.all|length > 3 %}
81+
+{{ resource.discovered_packages.all|length|add:"-3" }} more
82+
{% endif %}
83+
{% endif %}
84+
</td>
85+
</tr>
86+
{% endfor %}
87+
</tbody>
7688
</table>
7789

7890
{% if is_paginated %}
@@ -101,4 +113,5 @@
101113
{% endif %}
102114
</p>
103115
</div>
104-
{% endif %}
116+
{% endif %}
117+
</div>

0 commit comments

Comments
 (0)