Skip to content

Commit f1c08cd

Browse files
authored
Merge pull request #167 from Xpirix/multiple_versions_select
Add a feature for version bulk delete
2 parents 67c3a44 + f06768f commit f1c08cd

File tree

6 files changed

+347
-79
lines changed

6 files changed

+347
-79
lines changed

.pre-commit-config.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ exclude: 'static/'
55
repos:
66
# Fix end of files
77
- repo: https://github.com/pre-commit/pre-commit-hooks
8-
rev: v3.2.0
8+
rev: v5.0.0
99
hooks:
1010
- id: trailing-whitespace
1111
- id: end-of-file-fixer
@@ -15,23 +15,23 @@ repos:
1515

1616
# Remove unused imports/variables
1717
- repo: https://github.com/myint/autoflake
18-
rev: v1.4
18+
rev: v2.3.1
1919
hooks:
2020
- id: autoflake
2121
args:
2222
- "--in-place"
2323
- "--remove-unused-variables"
24-
# - "--remove-all-unused-imports"
24+
- "--remove-all-unused-imports"
2525

2626
# Sort imports
2727
- repo: https://github.com/pycqa/isort
28-
rev: "5.7.0"
28+
rev: "6.0.1"
2929
hooks:
3030
- id: isort
3131
args: ["--profile", "black"]
3232

3333
# Black formatting
3434
- repo: https://github.com/psf/black
35-
rev: 20.8b1
35+
rev: 25.1.0
3636
hooks:
37-
- id: black
37+
- id: black

qgis-app/plugins/templates/plugins/plugin_detail.html

Lines changed: 116 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@
8888
$(window).scrollTop(0);
8989
});
9090

91+
updateBulkDeleteButton();
92+
9193
});
9294

9395
function copyToClipBoard(plugin_id) {
@@ -123,8 +125,8 @@
123125
var columnDefs;
124126
if (isUserAllowedToManage()) {
125127
columnDefsValue = [
126-
{ sortable: false, targets: [-1, -3] },
127-
{ searchable: false, targets: [1, 2, 5, 7, -1] },
128+
{ sortable: false, targets: [0, -1, -3] },
129+
{ searchable: false, targets: [0, 1, 2, 5, 7, -1] },
128130
{ type: 'date', targets: [-2], orderDataType: 'dom-data-order'}
129131
];
130132
} else {
@@ -141,6 +143,27 @@
141143
order: [[-1, 'desc']]
142144
});
143145
});
146+
147+
function toggleAllVersions(source) {
148+
const checkboxes = document.querySelectorAll('.version-checkbox');
149+
checkboxes.forEach(cb => {
150+
cb.checked = source.checked;
151+
});
152+
updateBulkDeleteButton();
153+
}
154+
155+
function updateBulkDeleteButton() {
156+
const checkboxes = document.querySelectorAll('.version-checkbox:checked');
157+
const btn = document.getElementById('bulk-delete-btn');
158+
if (btn) {
159+
document.getElementById('selected-count').innerText = checkboxes.length;
160+
if (checkboxes.length > 0) {
161+
btn.disabled = false;
162+
} else {
163+
btn.disabled = true;
164+
}
165+
}
166+
}
144167
</script>
145168
{% endblock %}
146169
{% block extracss %}
@@ -476,85 +499,105 @@ <h2>
476499
</div>
477500
<div class="tab-pane" id="plugin-versions">
478501
{% if object.pluginversion_set.count %}
479-
<div class="table-container">
480-
<table id="plugin-versions-table" class="table versions-list-table">
481-
<thead>
482-
<tr>
483-
<th>{% trans "Version" %}</th>
484-
{% if not user.is_anonymous %}<th title="{% trans "Approved" %}"><i class="fa-solid fa-plug-circle-check"></i></th>{% endif %}
485-
<th title="{% trans "Experimental" %}"><i class="fa-solid fa-flask"></i></th>
486-
<th title="{% trans "Min QGIS version" %}">{% trans "QGIS >=" %}</th>
487-
<th title="{% trans "Max QGIS version" %}">{% trans "QGIS <=" %}</th>
488-
<th title="{% trans "Downloads" %}"><i class="fa-solid fa-download"></i></th>
489-
<th title="{% trans "Uploaded by" %}"><i class="fa-solid fa-user"></i></th>
490-
<th title="{% trans "Date" %}"><i class="fa-regular fa-calendar"></i> {% trans "Date" %}</th>
491-
{% if user.is_staff or user in object.approvers or user in object.editors %}<th title="{% trans "Manage" %}"><i class="fa-solid fa-gear"></i> {% trans "Manage" %}</th>{% endif %}
492-
</tr>
493-
</thead>
494-
<tbody>
495-
{% for version in plugin_versions_sorted %}
496-
{% if version.approved or not user.is_anonymous %}
497-
<tr onclick="window.location.href='{% url "version_detail" object.package_name version.version %}';">
498-
<td class="has-text-centered">
499-
<a href="{% url 'version_detail' object.package_name version.version %}">{{ version.version }}</a>
500-
</td>
501-
{% if not user.is_anonymous %}
502-
<td class="has-text-centered">
503-
{% if version.approved %}
504-
<i class="fas fa-check-circle has-text-success"></i>
505-
{% else %}
506-
<i class="fas fa-times-circle has-text-danger"></i>
502+
<form id="bulk-delete-form" method="post" action="{% url "versions_bulk_delete" object.package_name %}">
503+
{% csrf_token %}
504+
505+
<div class="table-container">
506+
<table id="plugin-versions-table" class="table versions-list-table">
507+
<thead>
508+
<tr>
509+
{% if user.is_staff or user in version.plugin.editors %}
510+
<th><input type="checkbox" id="select-all-versions" onclick="toggleAllVersions(this)"></th>
507511
{% endif %}
508-
</td>
509-
{% endif %}
510-
<td class="has-text-centered">
511-
{% if version.experimental %}
512-
<i class="fas fa-flask has-text-warning"></i>
513-
{% else %}
514-
-
512+
<th>{% trans "Version" %}</th>
513+
{% if not user.is_anonymous %}<th title="{% trans "Approved" %}"><i class="fa-solid fa-plug-circle-check"></i></th>{% endif %}
514+
<th title="{% trans "Experimental" %}"><i class="fa-solid fa-flask"></i></th>
515+
<th title="{% trans "Min QGIS version" %}">{% trans "QGIS >=" %}</th>
516+
<th title="{% trans "Max QGIS version" %}">{% trans "QGIS <=" %}</th>
517+
<th title="{% trans "Downloads" %}"><i class="fa-solid fa-download"></i></th>
518+
<th title="{% trans "Uploaded by" %}"><i class="fa-solid fa-user"></i></th>
519+
<th title="{% trans "Date" %}"><i class="fa-regular fa-calendar"></i> {% trans "Date" %}</th>
520+
{% if user.is_staff or user in object.approvers or user in object.editors %}<th title="{% trans "Manage" %}"><i class="fa-solid fa-gear"></i> {% trans "Manage" %}</th>{% endif %}
521+
</tr>
522+
</thead>
523+
<tbody>
524+
{% for version in plugin_versions_sorted %}
525+
{% if version.approved or not user.is_anonymous %}
526+
<tr>
527+
{% if user.is_staff or user in version.plugin.editors %}
528+
<td class="has-text-centered">
529+
<input type="checkbox" class="version-checkbox" name="selected_versions" value="{{ version.pk }}" onclick="updateBulkDeleteButton()">
530+
</td>
515531
{% endif %}
516-
</td>
517-
<td class="has-text-centered">{{ version.min_qg_version }}</td>
518-
<td class="has-text-centered">{{ version.max_qg_version }}</td>
519-
<td class="downloads">{{ version.downloads }}</td>
520-
{% if version.is_from_token %}
521-
<td class="has-text-centered">Token {{ version.token.description|default:"" }}</td>
522-
{% else %}
523-
<td class="has-text-centered"><a href="{% url "user_details" version.created_by.username %}">{{ version.created_by }}</a></td>
524-
{% endif %}
525-
<td class="has-text-centered" data-order="{{ version.created_on.isoformat }}">{{ version.created_on|local_timezone }}</td>
526-
{% if user.is_staff or user in version.plugin.approvers or user in version.plugin.editors %}
527-
<td class="has-text-centered" style="min-width: 200px;">
528-
<form method="post" action="{% url "version_manage" object.package_name version.version %}">{% csrf_token %}
529-
{% if user.is_staff or user in version.plugin.approvers %}
530-
{% if not version.approved %}
531-
<button class="button is-success is-small is-outlined" type="submit" name="version_approve" title="{% trans "Approve" %}">
532-
<i class="fas fa-thumbs-up"></i>
533-
</button>
532+
<td class="has-text-centered">
533+
<a href="{% url 'version_detail' object.package_name version.version %}">{{ version.version }}</a>
534+
</td>
535+
{% if not user.is_anonymous %}
536+
<td class="has-text-centered">
537+
{% if version.approved %}
538+
<i class="fas fa-check-circle has-text-success"></i>
534539
{% else %}
535-
<button class="button is-warning is-small is-outlined" type="submit" name="version_unapprove" title="{% trans "Unapprove" %}">
536-
<i class="fas fa-thumbs-down"></i></button>
540+
<i class="fas fa-times-circle has-text-danger"></i>
537541
{% endif %}
542+
</td>
538543
{% endif %}
539-
<a class="button is-small is-outlined {% if version.feedback|feedbacks_not_completed|length >= 1 %}is-warning{% else %}is-success{% endif %}" href="{% url "version_feedback" object.package_name version.version %}" title="{% trans "Feedback" %}">
540-
<i class="fas fa-comments"></i>
541-
{% if version.feedback|feedbacks_not_completed|length >= 2 %}
542-
{{ version.feedback|feedbacks_not_completed|length }}
544+
<td class="has-text-centered">
545+
{% if version.experimental %}
546+
<i class="fas fa-flask has-text-warning"></i>
547+
{% else %}
548+
-
543549
{% endif %}
544-
</a>
545-
{% if user.is_staff or user in version.plugin.editors %}
546-
<a class="button is-success is-small is-outlined" href="{% url "version_update" object.package_name version.version %}" title="{% trans "Edit" %}"><i class="fas fa-pencil"></i></a>
547-
<a class="button is-danger is-small is-outlined" href="{% url "version_delete" object.package_name version.version %}" title="{% trans "Delete" %}"><i class="fas fa-remove"></i></a>
550+
</td>
551+
<td class="has-text-centered">{{ version.min_qg_version }}</td>
552+
<td class="has-text-centered">{{ version.max_qg_version }}</td>
553+
<td class="downloads">{{ version.downloads }}</td>
554+
{% if version.is_from_token %}
555+
<td class="has-text-centered">Token {{ version.token.description|default:"" }}</td>
556+
{% else %}
557+
<td class="has-text-centered"><a href="{% url "user_details" version.created_by.username %}">{{ version.created_by }}</a></td>
558+
{% endif %}
559+
<td class="has-text-centered" data-order="{{ version.created_on.isoformat }}">{{ version.created_on|local_timezone }}</td>
560+
{% if user.is_staff or user in version.plugin.approvers or user in version.plugin.editors %}
561+
<td class="has-text-centered" style="min-width: 200px;">
562+
<form method="post" action="{% url "version_manage" object.package_name version.version %}">{% csrf_token %}
563+
{% if user.is_staff or user in version.plugin.approvers %}
564+
{% if not version.approved %}
565+
<button class="button is-success is-small is-outlined" type="submit" name="version_approve" title="{% trans "Approve" %}">
566+
<i class="fas fa-thumbs-up"></i>
567+
</button>
568+
{% else %}
569+
<button class="button is-warning is-small is-outlined" type="submit" name="version_unapprove" title="{% trans "Unapprove" %}">
570+
<i class="fas fa-thumbs-down"></i></button>
571+
{% endif %}
572+
{% endif %}
573+
<a class="button is-small is-outlined {% if version.feedback|feedbacks_not_completed|length >= 1 %}is-warning{% else %}is-success{% endif %}" href="{% url "version_feedback" object.package_name version.version %}" title="{% trans "Feedback" %}">
574+
<i class="fas fa-comments"></i>
575+
{% if version.feedback|feedbacks_not_completed|length >= 2 %}
576+
{{ version.feedback|feedbacks_not_completed|length }}
577+
{% endif %}
578+
</a>
579+
{% if user.is_staff or user in version.plugin.editors %}
580+
<a class="button is-success is-small is-outlined" href="{% url "version_update" object.package_name version.version %}" title="{% trans "Edit" %}"><i class="fas fa-pencil"></i></a>
581+
<a class="button is-danger is-small is-outlined" href="{% url "version_delete" object.package_name version.version %}" title="{% trans "Delete" %}"><i class="fas fa-remove"></i></a>
582+
{% endif %}
583+
</form>
584+
</td>
548585
{% endif %}
549-
</form>
550-
</td>
586+
</tr>
551587
{% endif %}
552-
</tr>
553-
{% endif %}
554-
{% endfor %}
555-
</tbody>
556-
</table>
557-
</div>
588+
{% endfor %}
589+
</tbody>
590+
</table>
591+
</div>
592+
{% if user.is_staff or user in object.editors %}
593+
<button id="bulk-delete-btn" class="button is-danger is-light" type="submit" disabled>
594+
<span class="icon">
595+
<i class="fas fa-trash"></i>
596+
</span>
597+
<span>{% trans "Delete selected versions:" %} <span id="selected-count">0</span></span>
598+
</button>
599+
{% endif %}
600+
</form>
558601
{% endif %}
559602
</div>
560603
{% if user.is_staff or user in object.editors %}

0 commit comments

Comments
 (0)