Skip to content

Commit

Permalink
Add a select_across checkbox on the ProjectReportForm #1524 (#1534)
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <[email protected]>
  • Loading branch information
tdruez authored Jan 21, 2025
1 parent 54e63b6 commit a6f7c86
Show file tree
Hide file tree
Showing 15 changed files with 309 additions and 86 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ v34.9.4 (unreleased)
multiple projects at once using labels and searching by project name.
https://github.com/aboutcode-org/scancode.io/issues/1524

- Add the ability to "select across" in Projects list when using the "select all"
checkbox on paginated list.
https://github.com/aboutcode-org/scancode.io/issues/1524

v34.9.3 (2024-12-31)
--------------------

Expand Down
3 changes: 2 additions & 1 deletion scancodeio/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ function setupSelectCheckbox() {
updateButtonAndDropdownState();

// Check if all row checkboxes are checked and update the "Select All" checkbox accordingly
selectAllCheckbox.checked = Array.from(rowCheckboxes).every((cb) => cb.checked);
const allRowCheckboxesChecked = Array.from(rowCheckboxes).every((cb) => cb.checked);
selectAllCheckbox.checked = allRowCheckboxesChecked;
});
});

Expand Down
27 changes: 24 additions & 3 deletions scanpipe/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,21 @@ def save(self, project):
return input_source


class ArchiveProjectForm(forms.Form):
class BaseProjectActionForm(forms.Form):
select_across = forms.BooleanField(
label="",
required=False,
initial=0,
help_text="All project matching current search and filters will be included.",
)
url_query = forms.CharField(
widget=forms.HiddenInput,
required=False,
help_text="Stores the current URL filters.",
)


class ArchiveProjectForm(BaseProjectActionForm):
remove_input = forms.BooleanField(
label="Remove inputs",
initial=True,
Expand All @@ -255,8 +269,15 @@ class ArchiveProjectForm(forms.Form):
required=False,
)

def get_action_kwargs(self):
return {
"remove_input": self.cleaned_data["remove_input"],
"remove_codebase": self.cleaned_data["remove_codebase"],
"remove_output": self.cleaned_data["remove_output"],
}


class ProjectOutputDownloadForm(forms.Form):
class ProjectOutputDownloadForm(BaseProjectActionForm):
output_format = forms.ChoiceField(
label="Choose the output format to include in the ZIP file",
choices=[
Expand All @@ -272,7 +293,7 @@ class ProjectOutputDownloadForm(forms.Form):
)


class ProjectReportForm(forms.Form):
class ProjectReportForm(BaseProjectActionForm):
model_name = forms.ChoiceField(
label="Choose the object type to include in the XLSX file",
choices=[
Expand Down
2 changes: 1 addition & 1 deletion scanpipe/pipes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def collect_and_create_codebase_resources(project, batch_size=5000):
Collect and create codebase resources including the "to/" and "from/" context using
the resource tag field.
The default ``batch_size`` can be overriden, although the benefits of a value
The default ``batch_size`` can be overridden, although the benefits of a value
greater than 5000 objects are usually not significant.
"""
model_class = CodebaseResource
Expand Down
2 changes: 0 additions & 2 deletions scanpipe/templates/registration/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<div class="field">
<label class="label">Username</label>
<div class="control has-icons-left">
<!-- {{ form.username }}-->
<input class="input" type="text" name="username" autofocus autocomplete="username" maxlength="150" required id="id_username">
<span class="icon is-small is-left">
<i class="fa-solid fa-user"></i>
Expand All @@ -32,7 +31,6 @@
<div class="field mb-5">
<label class="label">Password</label>
<div class="control has-icons-left">
<!-- {{ form.password }}-->
<input class="input" type="password" name="password" autocomplete="current-password" required id="id_password">
<span class="icon is-small is-left">
<i class="fa-solid fa-lock"></i>
Expand Down
21 changes: 18 additions & 3 deletions scanpipe/templates/scanpipe/modals/project_archive_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,24 @@
<p class="mb-2">
The selected directories will be removed:
</p>
<ul class="mb-5">
{{ archive_form.as_ul }}
</ul>
<div class="field">
<label class="label">
{{ archive_form.remove_input }}
{{ archive_form.remove_input.label }}
</label>
</div>
<div class="field">
<label class="label">
{{ archive_form.remove_codebase }}
{{ archive_form.remove_codebase.label }}
</label>
</div>
<div class="field">
<label class="label">
{{ archive_form.remove_output }}
{{ archive_form.remove_output.label }}
</label>
</div>
<p>
Are you sure you want to do this?
</p>
Expand Down
40 changes: 33 additions & 7 deletions scanpipe/templates/scanpipe/modals/projects_archive_modal.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load humanize %}
<div class="modal" id="modal-projects-archive">
<div class="modal-background"></div>
<div class="modal-card">
Expand All @@ -9,18 +10,43 @@
<section class="modal-card-body">
<div class="notification is-warning has-text-weight-semibold">
The selected projects will be marked as archived and will become read-only.
Those will not appear in the project list by default anymore.
Those will not appear in the project list by default anymore.<br>
</div>
<p class="mb-2">
The selected directories will be removed:
</p>
<ul class="mb-5">
{{ archive_form.as_ul }}
</ul>
<p>
Are you sure you want to do this?
</p>
<div class="field">
<label class="label">
{{ archive_form.remove_input }}
{{ archive_form.remove_input.label }}
</label>
</div>
<div class="field">
<label class="label">
{{ archive_form.remove_codebase }}
{{ archive_form.remove_codebase.label }}
</label>
</div>
<div class="field">
<label class="label">
{{ archive_form.remove_output }}
{{ archive_form.remove_output.label }}
</label>
</div>
{% if page_obj.paginator.num_pages > 1 %}
<div class="show-on-all-checked">
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ archive_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ archive_form.select_across.name }}" id="{{ archive_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ archive_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="archive">
<footer class="modal-card-foot is-flex is-justify-content-space-between">
<button class="button has-text-weight-semibold" type="reset">No, Cancel</button>
Expand Down
2 changes: 2 additions & 0 deletions scanpipe/templates/scanpipe/modals/projects_delete_modal.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load humanize %}
<div class="modal" id="modal-projects-delete">
<div class="modal-background"></div>
<div class="modal-card">
Expand All @@ -21,6 +22,7 @@
</p>
</section>
<form action="{% url 'project_action' %}" method="post" id="delete-projects-form">{% csrf_token %}
<input type="hidden" name="{{ action_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="delete">
<footer class="modal-card-foot is-flex is-justify-content-space-between">
<button class="button has-text-weight-semibold" type="reset">No, Cancel</button>
Expand Down
23 changes: 20 additions & 3 deletions scanpipe/templates/scanpipe/modals/projects_download_modal.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load humanize %}
<div class="modal" id="modal-projects-download">
<div class="modal-background"></div>
<div class="modal-card">
Expand All @@ -7,10 +8,26 @@
</header>
<form action="{% url 'project_action' %}" method="post" id="download-projects-form">{% csrf_token %}
<section class="modal-card-body">
<ul class="mb-3">
{{ outputs_download_form.as_ul }}
</ul>
<div class="field">
<label class="label">{{ outputs_download_form.output_format.label }}</label>
<div class="control">
{{ outputs_download_form.output_format }}
</div>
</div>
{% if page_obj.paginator.num_pages > 1 %}
<div class="show-on-all-checked">
<hr>
<div class="field">
<label class="checkbox" for="{{ outputs_download_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ outputs_download_form.select_across.name }}" id="{{ outputs_download_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ outputs_download_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="download">
<footer class="modal-card-foot is-flex is-justify-content-space-between">
<button class="button has-text-weight-semibold" type="reset">Cancel</button>
Expand Down
23 changes: 20 additions & 3 deletions scanpipe/templates/scanpipe/modals/projects_report_modal.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load humanize %}
<div class="modal" id="modal-projects-report">
<div class="modal-background"></div>
<div class="modal-card">
Expand All @@ -7,10 +8,26 @@
</header>
<form action="{% url 'project_action' %}" method="post" id="report-projects-form">{% csrf_token %}
<section class="modal-card-body">
<ul class="mb-3">
{{ report_form.as_ul }}
</ul>
<div class="field">
<label class="label">{{ report_form.model_name.label }}</label>
<div class="control">
{{ report_form.model_name }}
</div>
</div>
{% if page_obj.paginator.num_pages > 1 %}
<div class="show-on-all-checked">
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ report_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ report_form.select_across.name }}" id="{{ report_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ report_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ report_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="report">
<footer class="modal-card-foot is-flex is-justify-content-space-between">
<button class="button has-text-weight-semibold" type="reset">Cancel</button>
Expand Down
14 changes: 14 additions & 0 deletions scanpipe/templates/scanpipe/modals/projects_reset_modal.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load humanize %}
<div class="modal" id="modal-projects-reset">
<div class="modal-background"></div>
<div class="modal-card">
Expand All @@ -15,8 +16,21 @@
<p class="mb-5">
Are you sure you want to do this?
</p>
{% if page_obj.paginator.num_pages > 1 %}
<div class="show-on-all-checked">
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ archive_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ archive_form.select_across.name }}" id="{{ archive_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<form action="{% url 'project_action' %}" method="post" id="reset-projects-form">{% csrf_token %}
<input type="hidden" name="{{ action_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="reset">
<footer class="modal-card-foot is-flex is-justify-content-space-between">
<button class="button has-text-weight-semibold" type="reset">No, Cancel</button>
Expand Down
8 changes: 5 additions & 3 deletions scanpipe/templates/scanpipe/panels/project_inputs.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@
{% if project.can_change_inputs and input_source.uuid %}
<a class="modal-button is-grey-link is-clickable ml-1" data-target="modal-inputs-delete" aria-haspopup="true" data-url="{% url 'project_delete_input' project.slug input_source.uuid %}" data-filename="{{ input_source.filename }}" href="#"><i class="fa-regular fa-trash-can"></i></a>
{% endif %}
<a class="modal-button is-grey-link is-clickable ml-1" data-input-source-uuid="{{ input_source.uuid }}" data-tag-value="{{ input_source.tag }}" data-target="edit-input-tag-modal" aria-haspopup="true">
<span class="icon width-1 height-1"><i class="fa-solid fa-tag"></i></span>
</a>
{% if input_source.uuid %}{# File added in directory manually, no InputSource object available #}
<a class="modal-button is-grey-link is-clickable ml-1" data-input-source-uuid="{{ input_source.uuid }}" data-tag-value="{{ input_source.tag }}" data-target="edit-input-tag-modal" aria-haspopup="true">
<span class="icon width-1 height-1"><i class="fa-solid fa-tag"></i></span>
</a>
{% endif %}
</div>
</div>
{% endfor %}
Expand Down
18 changes: 18 additions & 0 deletions scanpipe/templates/scanpipe/project_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@
}
});
});

document.addEventListener("openModal", function(event) {
// Get all elements that should be shown or hidden based on the state of the checkboxes
const elementsForAllRowsChecked = getAll(".show-on-all-checked");
const selectAllCheckbox = document.getElementById("select-all");
const displayValue = selectAllCheckbox.checked ? "block" : "none";

// Iterate through all elements that need to be shown or hidden and apply the display style
elementsForAllRowsChecked.forEach((field) => {
field.style.display = displayValue;
});
});

});
</script>


<script>

</script>
{% endblock %}
Loading

0 comments on commit a6f7c86

Please sign in to comment.