Added modal to main index page

This commit is contained in:
phil.borman@gmail.com 2025-06-30 09:40:42 +02:00
parent 11d1b4f8cb
commit 06631f0ced
2 changed files with 107 additions and 9 deletions

View File

@ -308,12 +308,12 @@
}
},
callback: function (result) {
if (result) { document.getElementById("mark_authors").submit(); }
if (result) { submitFormAjax(); }
}
});
return false;
}
else { document.getElementById("mark_authors").submit(); }
else { submitFormAjax(); }
}
function bookinfo(bookid) {
@ -339,5 +339,78 @@
});
};
function submitFormAjax() {
var form = document.getElementById("mark_authors");
var formData = new FormData(form);
// Show loading modal
bootbox.dialog({
message: '<div class="text-center"><i class="fa fa-spinner fa-spin fa-2x"></i><br><br>Processing...</div>',
size: 'small',
backdrop: false
});
// Convert FormData to URLSearchParams for the AJAX call
var params = new URLSearchParams();
var formDataEntries = formData.entries();
for (var pair of formDataEntries) {
params.append(pair[0], pair[1]);
}
// Make AJAX call to the new endpoint
fetch('mark_authors_ajax', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params
})
.then(response => response.json())
.then(data => {
// Close loading modal
bootbox.hideAll();
// Show result modal
var message = '<div class="alert alert-info"><strong>Summary:</strong><br>' + data.summary + '</div>';
if (data.passed > 0 || data.failed > 0) {
message += '<div class="row">';
message += '<div class="col-md-6"><span class="label label-success">Successful: ' + data.passed + '</span></div>';
if (data.failed > 0) {
message += '<div class="col-md-6"><span class="label label-danger">Failed: ' + data.failed + '</span></div>';
}
message += '</div>';
}
bootbox.dialog({
title: 'Mark Authors Complete',
message: message,
buttons: {
ok: {
label: 'OK',
className: 'btn-primary',
callback: function() {
window.location.reload();
}
}
}
});
})
.catch(error => {
// Close loading modal
bootbox.hideAll();
// Show error modal
bootbox.dialog({
title: 'Error',
message: '<div class="alert alert-danger">An error occurred: ' + error.message + '</div>',
buttons: {
primary: {
label: "Close",
className: 'btn-primary',
callback: function(result){ window.location.reload('series'); }
},
}
});
});
}
</script>
</%def>

View File

@ -448,7 +448,7 @@ class WebInterface:
title = 'Inactive Authors'
else:
title = 'Ignored Authors'
return serve_template(templatename="index.html", title=title)
return serve_template(templatename="index.html", title=title, redirect=title.lower())
@cherrypy.expose
def home(self):
@ -512,7 +512,7 @@ class WebInterface:
typelist=get_list(CONFIG['EBOOK_TYPE']), themelist=themelist)
finally:
db.close()
return serve_template(templatename="index.html", title=title)
return serve_template(templatename="index.html", title='Authors', redirect='authors')
# noinspection PyUnusedLocal
@cherrypy.expose
@ -2116,13 +2116,14 @@ class WebInterface:
# AUTHOR ############################################################
@cherrypy.expose
def mark_authors(self, action=None, redirect=None, **args):
@cherrypy.tools.json_out()
def mark_authors_ajax(self, action=None, **args):
self.check_permitted(lazylibrarian.perm_status)
logger = logging.getLogger(__name__)
for arg in ['author_table_length', 'ignored']:
args.pop(arg, None)
if not self.valid_source(redirect):
redirect = "authors"
passed = 0
failed = 0
if action:
db = database.DBConnection()
try:
@ -2130,9 +2131,11 @@ class WebInterface:
check = db.match("SELECT AuthorName from authors WHERE AuthorID=?", (authorid,))
if not check:
logger.warning(f'Unable to set Status to "{action}" for "{authorid}"')
failed += 1
elif action in ["Active", "Wanted", "Paused", "Ignored"]:
db.upsert("authors", {'Status': action}, {'AuthorID': authorid})
logger.info(f'Status set to "{action}" for "{check["AuthorName"]}"')
passed += 1
elif action == "Delete":
logger.info(f"Deleting author and books: {check['AuthorName']}")
books = db.select("SELECT BookFile from books WHERE AuthorID=? AND BookFile is not null",
@ -2147,9 +2150,11 @@ class WebInterface:
logger.warning(f'rmtree failed on {book["BookFile"]}, {type(e).__name__} {str(e)}')
db.action('DELETE from authors WHERE AuthorID=?', (authorid,))
passed += 1
elif action == "Remove":
logger.info(f"Removing author: {check['AuthorName']}")
db.action('DELETE from authors WHERE AuthorID=?', (authorid,))
passed += 1
elif action == 'Subscribe':
cookie = cherrypy.request.cookie
if cookie and 'll_uid' in list(cookie.keys()):
@ -2158,10 +2163,12 @@ class WebInterface:
(userid, 'author', authorid))
if res:
logger.debug(f"User {userid} is already subscribed to {authorid}")
failed += 1
else:
db.action('INSERT into subscribers (UserID, Type, WantID) VALUES (?, ?, ?)',
(userid, 'author', authorid))
logger.debug(f"Subscribe {userid} to author {authorid}")
passed += 1
elif action == 'Unsubscribe':
cookie = cherrypy.request.cookie
if cookie and 'll_uid' in list(cookie.keys()):
@ -2173,12 +2180,29 @@ class WebInterface:
db.action('DELETE from subscribers WHERE UserID=? and Type=? and WantID=?',
(userid, 'ebook', iss['bookid']))
logger.debug(f"Unsubscribe {userid} author {authorid}")
passed += 1
finally:
db.close()
raise cherrypy.HTTPRedirect(redirect)
# Return JSON response instead of redirect
total = passed + failed
summary = f"Mark Authors '{action}' completed."
if total > 0:
summary += f" {passed} successful"
if failed > 0:
summary += f", {failed} failed"
summary += f" out of {total} total items."
else:
summary += " No items were processed."
return {
'success': True,
'action': action,
'passed': passed,
'failed': failed,
'total': total,
'summary': summary
}
# noinspection PyGlobalUndefined
@cherrypy.expose
def author_page(self, authorid, book_lang=None, library='eBook', ignored=False, book_filter=''):
global lastauthor
@ -5395,6 +5419,7 @@ class WebInterface:
# noinspection PyBroadException
@cherrypy.expose
@cherrypy.tools.json_out()
def magazine_update(self, **kwargs):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
self.check_permitted(lazylibrarian.perm_edit)