1
0
mirror of https://github.com/janeczku/calibre-web synced 2025-04-28 13:43:14 +00:00

Add bulk archive/unarchive buttons

This commit is contained in:
James Armstong 2024-08-01 21:34:55 -07:00
parent d0d9985370
commit d9a2a7a1e8
3 changed files with 149 additions and 9 deletions

View File

@ -472,7 +472,6 @@ def get_sorted_entry(field, bookid):
return json.dumps({'authors': " & ".join([a.name for a in calibre_db.order_authors([book])])})
return ""
@editbook.route("/ajax/simulatemerge", methods=['POST'])
@user_login_required
@edit_required
@ -488,10 +487,10 @@ def simulate_merge_list_book():
return json.dumps({'to': to_book, 'from': from_book})
return ""
@editbook.route("/ajax/simulatedeleteselectedbooks", methods=['POST'])
@editbook.route("/ajax/displayselectedbooks", methods=['POST'])
@user_login_required
@edit_required
def simulate_delete_selected_books():
def display_selected_books():
vals = request.get_json().get('selections')
books = []
if vals:
@ -500,6 +499,21 @@ def simulate_delete_selected_books():
return json.dumps({'books': books})
return ""
@editbook.route("/ajax/archiveselectedbooks", methods=['POST'])
@login_required_if_no_ano
@edit_required
def archive_selected_books():
vals = request.get_json().get('selections')
state = request.get_json().get('archive')
if vals:
for book_id in vals:
is_archived = change_archived_books(book_id, state,
message="Book {} archive bit set to: {}".format(book_id, state))
if is_archived:
kobo_sync_status.remove_synced_book(book_id)
return json.dumps({'success': True})
return ""
@editbook.route("/ajax/deleteselectedbooks", methods=['POST'])
@user_login_required
@edit_required

View File

@ -84,10 +84,21 @@ $(function() {
if (selections.length >= 1) {
$("#delete_selected_books").removeClass("disabled");
$("#delete_selected_books").attr("aria-disabled", false);
$("#archive_selected_books").removeClass("disabled");
$("#archive_selected_books").attr("aria-disabled", false);
$("#unarchive_selected_books").removeClass("disabled");
$("#unarchive_selected_books").attr("aria-disabled", false);
} else {
$("#delete_selected_books").addClass("disabled");
$("#delete_selected_books").attr("aria-disabled", true);
$("#archive_selected_books").addClass("disabled");
$("#archive_selected_books").attr("aria-disabled", true);
$("#unarchive_selected_books").addClass("disabled");
$("#unarchive_selected_books").attr("aria-disabled", true);
}
if (selections.length < 1) {
$("#delete_selection").addClass("disabled");
@ -143,6 +154,78 @@ $(function() {
});
});
$("#archive_selected_books").click(function(event) {
if ($(this).hasClass("disabled")) {
event.stopPropagation()
} else {
$('#archive_selected_modal').modal("show");
}
$.ajax({
method:"post",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: window.location.pathname + "/../ajax/displayselectedbooks",
data: JSON.stringify({"selections":selections}),
success: function success(booTitles) {
$('#display-archive-selected-books').empty();
$.each(booTitles.books, function(i, item) {
$("<span>- " + item + "</span><p></p>").appendTo("#display-archive-selected-books");
});
}
});
});
$("#archive_selected_confirm").click(function(event) {
$.ajax({
method:"post",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: window.location.pathname + "/../ajax/archiveselectedbooks",
data: JSON.stringify({"selections":selections, "archive": true}),
success: function success(booTitles) {
$("#books-table").bootstrapTable("refresh");
$("#books-table").bootstrapTable("uncheckAll");
}
});
});
$("#unarchive_selected_books").click(function(event) {
if ($(this).hasClass("disabled")) {
event.stopPropagation()
} else {
$('#unarchive_selected_modal').modal("show");
}
$.ajax({
method:"post",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: window.location.pathname + "/../ajax/displayselectedbooks",
data: JSON.stringify({"selections":selections}),
success: function success(booTitles) {
$('#display-unarchive-selected-books').empty();
$.each(booTitles.books, function(i, item) {
$("<span>- " + item + "</span><p></p>").appendTo("#display-unarchive-selected-books");
});
}
});
});
$("#unarchive_selected_confirm").click(function(event) {
$.ajax({
method:"post",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: window.location.pathname + "/../ajax/archiveselectedbooks",
data: JSON.stringify({"selections":selections, "archive": false}),
success: function success(booTitles) {
$("#books-table").bootstrapTable("refresh");
$("#books-table").bootstrapTable("uncheckAll");
}
});
});
$("#delete_selected_books").click(function(event) {
if ($(this).hasClass("disabled")) {
event.stopPropagation()
@ -153,12 +236,12 @@ $(function() {
method:"post",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: window.location.pathname + "/../ajax/simulatedeleteselectedbooks",
url: window.location.pathname + "/../ajax/displayselectedbooks",
data: JSON.stringify({"selections":selections}),
success: function success(booTitles) {
$('#selected-books').empty();
$('#display-delete-selected-books').empty();
$.each(booTitles.books, function(i, item) {
$("<span>- " + item + "</span><p></p>").appendTo("#selected-books");
$("<span>- " + item + "</span><p></p>").appendTo("#display-delete-selected-books");
});
}
@ -895,7 +978,6 @@ function BookCheckboxChange(checkbox, userId, field) {
});
}
function selectHeader(element, field) {
if (element.value !== "None") {
confirmDialog(element.id, "GeneralChangeModal", 0, function () {

View File

@ -36,6 +36,8 @@
<div class="row form-group">
<div class="btn btn-default disabled" id="merge_books" aria-disabled="true">{{_('Merge selected books')}}</div>
<div class="btn btn-default disabled" id="delete_selected_books" aria-disabled="true">{{_('Delete selected books')}}</div>
<div class="btn btn-default disabled" id="archive_selected_books" aria-disabled="true">{{_('Archive selected books')}}</div>
<div class="btn btn-default disabled" id="unarchive_selected_books" aria-disabled="true">{{_('Unarchive selected books')}}</div>
<div class="btn btn-default disabled" id="delete_selection" aria-disabled="true">{{_('Remove Selections')}}</div>
</div>
<div class="row form-group">
@ -103,6 +105,7 @@
</tr>
</thead>
</table>
{% endblock %}
{% block modal %}
{{ delete_book(current_user.role_delete_books()) }}
@ -141,17 +144,58 @@
<p></p>
<div class="text-left">{{_('The following books will be deleted:')}}</div>
<p></p>
<div class="text-left" id="selected-books"></div>
<div class="text-left" id="display-delete-selected-books"></div>
<div class="modal-footer">
<input id="delete_selected_confirm" type="button" class="btn btn-danger" value="{{_('Delete')}}" name="delete_selected_confirm" id="delete_selected_confirm" data-dismiss="modal">
<button id="delete_selected_abort" type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="archive_selected_modal" role="dialog" aria-labelledby="metaArchiveSelectedLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-center">
<span>{{_('Are you really sure?')}}</span>
</div>
<div class="modal-body">
<p></p>
<div class="text-left">{{_('The following books will be archived:')}}</div>
<p></p>
<div class="text-left" id="display-archive-selected-books"></div>
<div class="modal-footer">
<input id="archive_selected_confirm" type="button" class="btn btn-danger" value="{{_('Archive')}}" name="archive_selected_confirm" id="archive_selected_confirm" data-dismiss="modal">
<button id="archive_selected_abort" type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="unarchive_selected_modal" role="dialog" aria-labelledby="metaUnArchiveSelectedLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-center">
<span>{{_('Are you really sure?')}}</span>
</div>
<div class="modal-body">
<p></p>
<div class="text-left">{{_('The following books will be unarchived:')}}</div>
<p></p>
<div class="text-left" id="display-unarchive-selected-books"></div>
<div class="modal-footer">
<input id="unarchive_selected_confirm" type="button" class="btn btn-danger" value="{{_('Archive')}}" name="unarchive_selected_confirm" id="unarchive_selected_confirm" data-dismiss="modal">
<button id="unarchive_selected_abort" type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block js %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-locale-all.min.js') }}"></script>