Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions scancodeio/static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
cursor: not-allowed;
color: var(--bulma-text-weak);
}
.tabs.is-narrow {
--bulma-tabs-link-padding: 0.5em 0.75em;
}
.border-no-top-left-radius {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
Expand Down Expand Up @@ -340,6 +343,10 @@ a[target="_blank"] .fa-up-right-from-square {
#content-header input[name="search"] {
width: 225px;
}
.is-borderless {
--bulma-button-border-width: 0px;
--bulma-button-outer-shadow-a: 0;
}
button.as-link {
height: auto;
line-height: initial;
Expand Down
2 changes: 1 addition & 1 deletion scanpipe/templates/scanpipe/panels/project_codebase.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</a>
</div>
{% for node in codebase_root_tree %}
<a class="panel-block" href="{% url 'project_resource_tree' project.slug %}?path={{ node.name }}">
<a class="panel-block" href="{% url 'project_resource_tree' project.slug node.name %}">
<span class="panel-icon">
<i class="{% if node.is_dir %}fa-solid fa-folder{% else %}fa-regular fa-file{% endif %}"></i>
</span>
Expand Down
3 changes: 3 additions & 0 deletions scanpipe/templates/scanpipe/project_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
</li>
<li class="is-active">
<a href="#" aria-current="page">{{ project.name }}</a>
<button class="button is-borderless has-text-grey copy-to-clipboard p-2" aria-label="Copy name" data-copy="{{ project.name }}" data-copy-feedback="Name copied!">
<i class="fa-regular fa-clone"></i>
</button>
</li>
</ul>
</nav>
Expand Down
12 changes: 6 additions & 6 deletions scanpipe/templates/scanpipe/resource_tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,17 @@
</div>
<div id="resizer" class="resizer"></div>
<div id="right-pane" class="right-pane px-3">
{% if path %}
<div
{% if resource.is_file %}
hx-get="{% url 'resource_detail' project.slug resource.path %}"
{% elif path %}
hx-get="{% url 'project_resource_tree_right_pane' project.slug path %}"
{% else %}
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ path }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug %}"
{% endif %}
hx-trigger="load"
hx-target="this">
</div>
{% else %}
{% include "scanpipe/tree/resource_right_pane.html" %}
{% endif %}
</div>
</div>
</div>
Expand All @@ -65,7 +63,9 @@
}
} else {
target.classList.remove("is-hidden");
const response = await fetch(url + "&tree_panel=true");
const fullUrl = new URL(url, window.location.origin);
fullUrl.searchParams.append('tree_panel', 'true');
const response = await fetch(fullUrl.toString());
target.innerHTML = await response.text();
target.dataset.loaded = "true";
htmx.process(target);
Expand Down
2 changes: 1 addition & 1 deletion scanpipe/templates/scanpipe/tabset/tabset.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load humanize %}
<div class="tabs is-boxed mb-3">
<div class="tabs is-boxed is-narrow mb-3">
<ul>
{% for tab_id, tab_data in tabset_data.items %}
<li{% if forloop.first %} class="is-active"{% endif %}>
Expand Down
8 changes: 4 additions & 4 deletions scanpipe/templates/scanpipe/tree/resource_left_pane_tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
{% for node in children %}
<li>
{% if node.is_dir %}
<div class="tree-node is-flex is-align-items-center px-1" data-folder data-path="{{ node.path }}"{% if node.has_children %} data-target="{{ node.path|slugify }}" data-url="{% url 'project_resource_tree' slug=project.slug %}?path={{ node.path }}"{% endif %}>
<div class="tree-node is-flex is-align-items-center px-1" data-folder data-path="{{ node.path }}"{% if node.has_children %} data-target="{{ node.path|slugify }}" data-url="{% url 'project_resource_tree' project.slug node.path %}"{% endif %}>
<span class="icon is-small chevron mr-1{% if not node.has_children %} is-invisible{% endif %} is-clickable is-flex is-align-items-center" data-chevron>
<i class="fas fa-chevron-right"></i>
</span>
<span
class="is-flex is-align-items-center folder-meta is-clickable"
data-folder-click
data-path="{{ node.path }}"
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ node.path }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug node.path %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ node.path }}">
hx-push-url="{% url 'project_resource_tree' project.slug node.path %}">
<span class="icon is-small mr-2">
<i class="fas fa-folder"></i>
</span>
Expand All @@ -29,7 +29,7 @@
data-path="{{ node.path }}"
hx-get="{% url 'resource_detail' project.slug node.path %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ node.path }}">
hx-push-url="{% url 'project_resource_tree' project.slug node.path %}">
<span class="icon is-small mr-2">
<i class="far fa-file"></i>
</span>
Expand Down
58 changes: 29 additions & 29 deletions scanpipe/templates/scanpipe/tree/resource_path_breadcrumb.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{% if path_segments %}
<nav class="breadcrumb is-flex is-align-items-center mb-2" aria-label="breadcrumbs">
<button
id="expand-left-pane"
Expand All @@ -7,31 +6,32 @@
data-tooltip-position="bottom right">
<i class="fa-solid fa-square-caret-right"></i>
</button>
<ul>
{% for subpath, segment in path_segments %}
{% if not forloop.last %}
<li>
<a
href="{% url 'project_resource_tree' project.slug %}?path={{ subpath }}"
class="expand-in-tree"
data-path="{{ subpath }}"
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ subpath }}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ subpath }}">
{{ segment }}
</a>
</li>
{% else %}
<li class="is-active">
<a href="#" class="has-text-dark" aria-current="page">
{{ segment }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
<button class="button is-white copy-to-clipboard p-2" aria-label="Copy path" data-copy="{{ path }}" data-copy-feedback="Path copied!">
<i class="fa-regular fa-clone"></i>
</button>
</nav>
{% endif %}
{% if path %}
<ul>
{% for subpath, segment in path_segments %}
{% if not forloop.last %}
<li>
<a
href="{% url 'project_resource_tree' project.slug subpath %}"
class="expand-in-tree"
data-path="{{ subpath }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug subpath %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug subpath %}">
{{ segment }}
</a>
</li>
{% else %}
<li class="is-active">
<a href="#" class="has-text-dark" aria-current="page">
{{ segment }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
<button class="button is-borderless copy-to-clipboard p-2" aria-label="Copy path" data-copy="{{ path }}" data-copy-feedback="Path copied!">
<i class="fa-regular fa-clone"></i>
</button>
{% endif %}
</nav>
22 changes: 11 additions & 11 deletions scanpipe/templates/scanpipe/tree/resource_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<table class="table is-bordered is-hoverable is-fullwidth">
<thead class="is-sticky">
<tr>
<th>Name</th>
<th style="min-width:200px;">Name</th>
<th>Status</th>
<th>Language</th>
<th>License</th>
Expand All @@ -14,9 +14,9 @@
<tr
class="expand-in-tree is-clickable"
data-path="{{ parent_path }}"
hx-get="{% url 'project_resource_tree_table' project.slug %}{% if parent_path %}?path={{ parent_path }}{% endif %}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug parent_path %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}{% if parent_path %}?path={{ parent_path }}{% endif %}">
hx-push-url="{% url 'project_resource_tree' project.slug parent_path %}">
<td colspan="5">
<div class="is-flex is-align-items-center">
<span class="icon is-small mr-2">
Expand All @@ -41,19 +41,19 @@
{% if resource.is_dir %}
<a
class="expand-in-tree"
href="{% url 'project_resource_tree' project.slug %}?path={{ resource.path }}"
href="{% url 'project_resource_tree' project.slug resource.path %}"
data-path="{{ resource.path }}"
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ resource.path }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug resource.path %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ resource.path }}">
hx-push-url="{% url 'project_resource_tree' project.slug resource.path %}">
{{ resource.name }}
</a>
{% else %}
<a
href="{% url 'resource_detail' project.slug resource.path %}"
hx-get="{% url 'resource_detail' project.slug resource.path %}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ resource.path }}">
hx-push-url="{% url 'project_resource_tree' project.slug resource.path %}">
{{ resource.name }}
</a>
{% endif %}
Expand Down Expand Up @@ -84,18 +84,18 @@
{% if page_obj.has_previous %}
<a
class="pagination-previous"
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ path }}&page={{ page_obj.previous_page_number }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug path %}?page={{ page_obj.previous_page_number }}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ path }}&page={{ page_obj.previous_page_number }}">
hx-push-url="{% url 'project_resource_tree' project.slug path %}?page={{ page_obj.previous_page_number }}">
Previous
</a>
{% endif %}
{% if page_obj.has_next %}
<a
class="pagination-next"
hx-get="{% url 'project_resource_tree_table' project.slug %}?path={{ path }}&page={{ page_obj.next_page_number }}"
hx-get="{% url 'project_resource_tree_right_pane' project.slug path%}?page={{ page_obj.next_page_number }}"
hx-target="#right-pane"
hx-push-url="{% url 'project_resource_tree' project.slug %}?path={{ path }}&page={{ page_obj.next_page_number }}">
hx-push-url="{% url 'project_resource_tree' project.slug path %}?page={{ page_obj.next_page_number }}">
Next page
</a>
{% endif %}
Expand Down
68 changes: 43 additions & 25 deletions scanpipe/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,12 +672,17 @@ def test_scanpipe_views_project_codebase_view(self):

(self.project1.codebase_path / "dir1").mkdir()
(self.project1.codebase_path / "dir1/dir2").mkdir()
(self.project1.codebase_path / "file.txt").touch()
(self.project1.codebase_path / "file+.txt").touch()

response = self.client.get(url)
resource_tree_url = reverse("project_resource_tree", args=[self.project1.slug])
self.assertContains(response, f"{resource_tree_url}?path=dir1")
self.assertContains(response, f"{resource_tree_url}?path=file.txt")
resource_tree_url = reverse(
"project_resource_tree", args=[self.project1.slug, "dir1"]
)
self.assertContains(response, resource_tree_url)
resource_tree_url = reverse(
"project_resource_tree", args=[self.project1.slug, "file+.txt"]
)
self.assertContains(response, resource_tree_url)

def test_scanpipe_views_project_codebase_view_ordering(self):
url = reverse("project_codebase", args=[self.project1.slug])
Expand Down Expand Up @@ -1622,8 +1627,11 @@ def test_scanpipe_views_resource_tree_children_path(self):
make_resource_file(self.project1, path="parent/dir1")
make_resource_file(self.project1, path="parent/dir1/child2.txt")

url = reverse("project_resource_tree", kwargs={"slug": self.project1.slug})
response = self.client.get(url + "?path=parent&tree_panel=true")
url = reverse(
"project_resource_tree",
kwargs={"slug": self.project1.slug, "path": "parent"},
)
response = self.client.get(url + "?tree_panel=true")
children = response.context["children"]

child1 = children[0]
Expand All @@ -1635,66 +1643,76 @@ def test_scanpipe_views_resource_tree_children_path(self):
self.assertFalse(child1.has_children)
self.assertTrue(dir1.has_children)

def test_scanpipe_views_project_resource_tree_table_view_with_path_directory(self):
make_resource_directory(self.project1, path="parent")
make_resource_file(self.project1, path="parent/child1.txt")
make_resource_file(self.project1, path="parent/child2.py")
def test_scanpipe_views_project_resource_tree_right_pane_view_with_path_directory(
self,
):
resource1 = make_resource_directory(self.project1, path="parent+special&chars")
make_resource_file(self.project1, path="parent+special&chars/child1.txt")
make_resource_file(self.project1, path="parent+special&chars/child2.py")

url = reverse(
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
"project_resource_tree_right_pane",
kwargs={"slug": self.project1.slug, "path": resource1.path},
)
response = self.client.get(url + "?path=parent")
response = self.client.get(url)

self.assertEqual(200, response.status_code)
self.assertEqual("parent", response.context["path"])
self.assertEqual(resource1.path, response.context["path"])
resources = list(response.context["resources"])
self.assertEqual(2, len(resources))

resource_paths = [r.path for r in resources]
self.assertEqual(["parent/child1.txt", "parent/child2.py"], resource_paths)
self.assertEqual(
["parent+special&chars/child1.txt", "parent+special&chars/child2.py"],
resource_paths,
)

def test_scanpipe_views_project_resource_tree_view_with_path_file(self):
resource = make_resource_file(self.project1, path="specific_file.txt")

url = reverse("project_resource_tree", kwargs={"slug": self.project1.slug})
response = self.client.get(url + f"?path={resource.path}")
url = reverse(
"project_resource_tree",
kwargs={"slug": self.project1.slug, "path": resource.path},
)
response = self.client.get(url)

self.assertEqual(200, response.status_code)
self.assertEqual("specific_file.txt", response.context["path"])
self.assertEqual(resource, response.context["resource"])

def test_scanpipe_views_project_resource_tree_table_view_empty_directory(self):
def test_scanpipe_views_project_resource_tree_right_pane_view_empty_directory(self):
make_resource_directory(self.project1, path="empty_dir")

url = reverse(
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
"project_resource_tree_right_pane",
kwargs={"slug": self.project1.slug, "path": "empty_dir"},
)
response = self.client.get(url + "?path=empty_dir")

response = self.client.get(url)
self.assertEqual(200, response.status_code)
self.assertEqual("empty_dir", response.context["path"])
resources = list(response.context["resources"])
self.assertEqual(0, len(resources))

@mock.patch("scanpipe.views.ProjectResourceTreeTableView.paginate_by", 2)
def test_scanpipe_views_project_resource_tree_table_view_pagination(self):
@mock.patch("scanpipe.views.ProjectResourceTreeRightPaneView.paginate_by", 2)
def test_scanpipe_views_project_resource_tree_right_pane_view_pagination(self):
make_resource_directory(self.project1, path="parent")
make_resource_file(self.project1, path="parent/file1.txt", parent_path="parent")
make_resource_file(self.project1, path="parent/file2.txt", parent_path="parent")
make_resource_file(self.project1, path="parent/file3.txt", parent_path="parent")

url = reverse(
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
"project_resource_tree_right_pane",
kwargs={"slug": self.project1.slug, "path": "parent"},
)

response = self.client.get(url + "?path=parent")
response = self.client.get(url)
self.assertEqual(200, response.status_code)
self.assertTrue(response.context["is_paginated"])
self.assertEqual(1, response.context["page_obj"].number)
self.assertTrue(response.context["page_obj"].has_next())
self.assertFalse(response.context["page_obj"].has_previous())

response = self.client.get(url + "?path=parent&page=2")
response = self.client.get(url + "?page=2")
self.assertEqual(200, response.status_code)
self.assertEqual(2, response.context["page_obj"].number)
self.assertFalse(response.context["page_obj"].has_next())
Expand Down
Loading
Loading