- {% include "scanpipe/tree/resource_left_pane_header.html" only %}
+ {% include "scanpipe/tree/resource_left_pane_header.html" with project=project %}
{% include "scanpipe/tree/resource_left_pane_tree.html" with children=children path=path %}
@@ -161,6 +161,50 @@
});
});
+ const searchInput = document.getElementById('file-search-input');
+ const searchResults = document.getElementById('search-results');
+ const clearSearchBtn = document.getElementById('clear-search');
+
+ function toggleSearchResults(show = null) {
+ const shouldShow = show !== null ? show : searchInput.value.trim();
+ searchResults.classList.toggle('is-hidden', !shouldShow);
+ }
+
+ function clearSearch() {
+ searchInput.value = '';
+ toggleSearchResults(false);
+ searchInput.focus();
+ }
+
+ clearSearchBtn.addEventListener('click', clearSearch);
+ searchInput.addEventListener('focus', () => toggleSearchResults());
+
+ searchInput.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') {
+ toggleSearchResults(false);
+ searchInput.blur();
+ }
+ });
+
+ document.addEventListener('click', function(e) {
+ const searchResultItem = e.target.closest('.dropdown-item');
+ if (searchResultItem && searchResultItem.hasAttribute('hx-get')) {
+ toggleSearchResults(false);
+ searchInput.blur();
+ expandToPath(searchResultItem.dataset.path);
+ return;
+ }
+
+ if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
+ toggleSearchResults(false);
+ }
+ });
+
+ document.body.addEventListener('htmx:afterSettle', function(evt) {
+ if (evt.target === searchResults) {
+ toggleSearchResults();
+ }
+ });
});
{% endblock %}
\ No newline at end of file
diff --git a/scanpipe/templates/scanpipe/tree/resource_left_pane_header.html b/scanpipe/templates/scanpipe/tree/resource_left_pane_header.html
index 1dfbc8482c..9395a2b141 100644
--- a/scanpipe/templates/scanpipe/tree/resource_left_pane_header.html
+++ b/scanpipe/templates/scanpipe/tree/resource_left_pane_header.html
@@ -9,4 +9,6 @@
Resources
-
\ No newline at end of file
+
+
+{% include "scanpipe/tree/resource_search_container.html" with project=project %}
\ No newline at end of file
diff --git a/scanpipe/templates/scanpipe/tree/resource_search_container.html b/scanpipe/templates/scanpipe/tree/resource_search_container.html
new file mode 100644
index 0000000000..0e85450ae6
--- /dev/null
+++ b/scanpipe/templates/scanpipe/tree/resource_search_container.html
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/scanpipe/templates/scanpipe/tree/resource_search_results.html b/scanpipe/templates/scanpipe/tree/resource_search_results.html
new file mode 100644
index 0000000000..dfe3ba21c4
--- /dev/null
+++ b/scanpipe/templates/scanpipe/tree/resource_search_results.html
@@ -0,0 +1,36 @@
+{% if search_results %}
+
+
+
+
+
No files found matching "{{ query }}"
+
+{% endif %}
\ No newline at end of file
diff --git a/scanpipe/urls.py b/scanpipe/urls.py
index 05a8a8a8ef..450cc28996 100644
--- a/scanpipe/urls.py
+++ b/scanpipe/urls.py
@@ -151,6 +151,11 @@
views.ProjectResourceTreeRightPaneView.as_view(),
name="project_resource_tree_right_pane",
),
+ path(
+ "project/