Backend and frontend fixes
This commit is contained in:
@@ -260,6 +260,7 @@ pub async fn main() {
|
|||||||
.route("/api/update", post(update_book))
|
.route("/api/update", post(update_book))
|
||||||
.route("/api/delete/:id", get(delete_book))
|
.route("/api/delete/:id", get(delete_book))
|
||||||
.route("/api/authentication_check", get(authentication_check))
|
.route("/api/authentication_check", get(authentication_check))
|
||||||
|
.route("/api/refresh_search_index", get(refresh_meili_index))
|
||||||
.route_layer(RequireAuthorizationLayer::<booksman_orm::AxumUser>::login())
|
.route_layer(RequireAuthorizationLayer::<booksman_orm::AxumUser>::login())
|
||||||
.route("/api/list", get(list_book))
|
.route("/api/list", get(list_book))
|
||||||
.route("/api/list_search", get(list_search_book))
|
.route("/api/list_search", get(list_search_book))
|
||||||
@@ -713,6 +714,122 @@ async fn delete_book(
|
|||||||
"success"
|
"success"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn refresh_meili_index(
|
||||||
|
Extension(ref conn): Extension<DatabaseConnection>,
|
||||||
|
Extension(ref meili_client): Extension<Client>,
|
||||||
|
Extension(user): Extension<booksman_orm::AxumUser>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
|
let userid = user.id;
|
||||||
|
|
||||||
|
let page: usize = 0;
|
||||||
|
let sort: String = "desc".to_string();
|
||||||
|
let per_page: usize = 12;
|
||||||
|
|
||||||
|
let books = QueryCore::find_books_plus_meta_in_page(conn, page, per_page, userid, sort.clone())
|
||||||
|
.await
|
||||||
|
.expect("could not list books");
|
||||||
|
|
||||||
|
let num_pages = books.1;
|
||||||
|
for pg_idx in 0..num_pages {
|
||||||
|
let books = QueryCore::find_books_plus_meta_in_page(conn, pg_idx.try_into().unwrap(), per_page, userid, sort.clone())
|
||||||
|
.await
|
||||||
|
.expect("could not list books");
|
||||||
|
|
||||||
|
for bookandmeta in books.0.into_iter() {
|
||||||
|
let bookui = BookUI {
|
||||||
|
id: bookandmeta.clone().book.id,
|
||||||
|
title: bookandmeta.clone().book.title,
|
||||||
|
open_library_key: bookandmeta.clone().book.open_library_key,
|
||||||
|
edition_count: bookandmeta.clone().book.edition_count,
|
||||||
|
first_publish_year: bookandmeta.clone().book.first_publish_year,
|
||||||
|
median_page_count: bookandmeta.clone().book.median_page_count,
|
||||||
|
goodread_id: bookandmeta.clone().book.goodread_id,
|
||||||
|
description: bookandmeta.clone().book.description,
|
||||||
|
cover: bookandmeta.clone().book.cover,
|
||||||
|
location: bookandmeta.clone().book.location,
|
||||||
|
time_added: bookandmeta.clone().book.time_added,
|
||||||
|
rating: bookandmeta.clone().book.rating,
|
||||||
|
comments: bookandmeta.clone().book.comments,
|
||||||
|
author_name: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.authors
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.author_name)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
person: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.persons
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.person)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
place: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.places
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.place)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
subject: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.subjects
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.subject)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
time: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.times
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.time)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
isbn: Some(
|
||||||
|
bookandmeta
|
||||||
|
.clone()
|
||||||
|
.isbns
|
||||||
|
.into_iter()
|
||||||
|
.map(|u| u.isbn)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let book_meili = BookMeili {
|
||||||
|
id: bookui.id,
|
||||||
|
open_library_key: bookui.open_library_key.unwrap_or("".to_string()),
|
||||||
|
title: bookui.title,
|
||||||
|
edition_count: bookui.edition_count.unwrap_or(0),
|
||||||
|
first_publish_year: bookui.first_publish_year.unwrap_or(0),
|
||||||
|
median_page_count: bookui.median_page_count.unwrap_or(0),
|
||||||
|
goodread_id: bookui.goodread_id.unwrap_or("".to_string()),
|
||||||
|
description: bookui.description.unwrap_or("".to_string()),
|
||||||
|
cover: bookui.cover.unwrap_or("".to_string()),
|
||||||
|
location: bookui.location.unwrap_or("".to_string()),
|
||||||
|
time_added: bookui.time_added.unwrap_or("".to_string()),
|
||||||
|
rating: bookui.rating.unwrap_or(0),
|
||||||
|
comments: bookui.comments.unwrap_or("".to_string()),
|
||||||
|
author_name: bookui.author_name.unwrap_or(vec!["".to_string()]),
|
||||||
|
person: bookui.person.unwrap_or(vec!["".to_string()]),
|
||||||
|
place: bookui.place.unwrap_or(vec!["".to_string()]),
|
||||||
|
subject: bookui.subject.unwrap_or(vec!["".to_string()]),
|
||||||
|
time: bookui.time.unwrap_or(vec!["".to_string()]),
|
||||||
|
isbn: bookui.isbn.unwrap_or(vec!["".to_string()]),
|
||||||
|
};
|
||||||
|
booksman_search::create_or_update_book(book_meili, userid, meili_client).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"success"
|
||||||
|
}
|
||||||
|
|
||||||
async fn list_book(
|
async fn list_book(
|
||||||
Extension(ref conn): Extension<DatabaseConnection>,
|
Extension(ref conn): Extension<DatabaseConnection>,
|
||||||
axum::extract::Query(params): axum::extract::Query<HashMap<String, String>>,
|
axum::extract::Query(params): axum::extract::Query<HashMap<String, String>>,
|
||||||
@@ -734,7 +851,11 @@ async fn list_book(
|
|||||||
for bookandmeta in books.0.into_iter() {
|
for bookandmeta in books.0.into_iter() {
|
||||||
let mut cover = bookandmeta.clone().book.cover;
|
let mut cover = bookandmeta.clone().book.cover;
|
||||||
if !cover.is_none() {
|
if !cover.is_none() {
|
||||||
cover = Some(format!("{}/images/{}", backend_url, cover.unwrap()));
|
if cover.clone().unwrap() != "".to_string() {
|
||||||
|
cover = Some(format!("{}/images/{}", backend_url, cover.unwrap()));
|
||||||
|
} else {
|
||||||
|
cover = Some(format!("{}/images/placeholder.jpg", backend_url));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cover = Some(format!("{}/images/placeholder.jpg", backend_url));
|
cover = Some(format!("{}/images/placeholder.jpg", backend_url));
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1143,7 @@ async fn create_book(
|
|||||||
.expect("could not create book");
|
.expect("could not create book");
|
||||||
}
|
}
|
||||||
let book_meili = BookMeili {
|
let book_meili = BookMeili {
|
||||||
id: doc_sent.id,
|
id: created_book.last_insert_id,
|
||||||
open_library_key: doc_sent.open_library_key.unwrap_or("".to_string()),
|
open_library_key: doc_sent.open_library_key.unwrap_or("".to_string()),
|
||||||
title: doc_sent.title,
|
title: doc_sent.title,
|
||||||
edition_count: doc_sent.edition_count.unwrap_or(0),
|
edition_count: doc_sent.edition_count.unwrap_or(0),
|
||||||
|
|||||||
@@ -291,6 +291,8 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
app_state.search.set(task);
|
app_state.search.set(task);
|
||||||
app_state.openlibrary.set(false);
|
app_state.openlibrary.set(false);
|
||||||
app_state.internalsearch.set(true);
|
app_state.internalsearch.set(true);
|
||||||
|
app_state.pagenum.set(1);
|
||||||
|
app_state.pagedisplay.set(1);
|
||||||
app_state.refreshing.set(true);
|
app_state.refreshing.set(true);
|
||||||
info!("Fetching search 2\n");
|
info!("Fetching search 2\n");
|
||||||
}
|
}
|
||||||
@@ -300,6 +302,8 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
let click_listall = |_| {
|
let click_listall = |_| {
|
||||||
app_state.openlibrary.set(false);
|
app_state.openlibrary.set(false);
|
||||||
app_state.internalsearch.set(false);
|
app_state.internalsearch.set(false);
|
||||||
|
app_state.pagenum.set(1);
|
||||||
|
app_state.pagedisplay.set(1);
|
||||||
app_state.refreshing.set(true);
|
app_state.refreshing.set(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -432,7 +436,7 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
(if *app_state.editmode.get() == true {
|
(if *app_state.editmode.get() == true {
|
||||||
view!{ cx,
|
view!{ cx,
|
||||||
|
|
||||||
div(class="w-1/2 flex"){
|
div(class="w-2/5 flex"){
|
||||||
(if *app_state.userid.get() != 0 {
|
(if *app_state.userid.get() != 0 {
|
||||||
view!{ cx,
|
view!{ cx,
|
||||||
button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }}
|
button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }}
|
||||||
@@ -447,7 +451,7 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
view!{cx, ""}
|
view!{cx, ""}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
div(class="w-1/2 flex"){
|
div(class="w-2/5 flex"){
|
||||||
button(on:click=click_addbook, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-circle-plus") span(class="inline-block"){"Add" }}
|
button(on:click=click_addbook, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-circle-plus") span(class="inline-block"){"Add" }}
|
||||||
//button(on:click=click_addbook) { "+ Add New" }
|
//button(on:click=click_addbook) { "+ Add New" }
|
||||||
//input(ref=input_ref3,
|
//input(ref=input_ref3,
|
||||||
@@ -469,6 +473,7 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
view!{cx,
|
view!{cx,
|
||||||
(if *app_state.userid.get() != 0 {
|
(if *app_state.userid.get() != 0 {
|
||||||
view!{ cx,
|
view!{ cx,
|
||||||
|
div(class="w-2/5 flex"){
|
||||||
button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }}
|
button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }}
|
||||||
div(class="min-w-40 inline-flex"){
|
div(class="min-w-40 inline-flex"){
|
||||||
input(ref=input_ref2,
|
input(ref=input_ref2,
|
||||||
@@ -477,7 +482,9 @@ pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
|||||||
bind:value=value2,
|
bind:value=value2,
|
||||||
on:keyup=handle_submit_seachall,
|
on:keyup=handle_submit_seachall,
|
||||||
)}
|
)}
|
||||||
}} else {
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
view!{cx, ""}
|
view!{cx, ""}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -794,7 +801,8 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
let mut currbooks = (*app_state_scr.clone().books.get()).clone();
|
let mut currbooks = (*app_state_scr.clone().books.get()).clone();
|
||||||
currbooks.extend(res.books.iter().cloned());
|
currbooks.extend(res.books.iter().cloned());
|
||||||
app_state_scr.books.set(currbooks);
|
app_state_scr.books.set(currbooks);
|
||||||
app_state_scr.maxpage.set(res.num_pages)
|
app_state_scr.maxpage.set(res.num_pages);
|
||||||
|
app_state_scr.scrolling.set(false);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
info!("IntSearch triggered2");
|
info!("IntSearch triggered2");
|
||||||
@@ -810,10 +818,10 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
let mut currbooks = (*app_state_scr.clone().books.get()).clone();
|
let mut currbooks = (*app_state_scr.clone().books.get()).clone();
|
||||||
currbooks.extend(res.books.iter().cloned());
|
currbooks.extend(res.books.iter().cloned());
|
||||||
app_state_scr.books.set(currbooks);
|
app_state_scr.books.set(currbooks);
|
||||||
app_state_scr.maxpage.set(res.num_pages)
|
app_state_scr.maxpage.set(res.num_pages);
|
||||||
|
app_state_scr.scrolling.set(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
app_state.scrolling.set(false);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//info!("LibrarySearch triggered?");
|
//info!("LibrarySearch triggered?");
|
||||||
@@ -837,7 +845,7 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
|
|
||||||
let handle_load_more = move |_| {
|
let handle_load_more = move |_| {
|
||||||
let app_state = app_state.clone();
|
let app_state = app_state.clone();
|
||||||
if *app_state.scrolling.get() == true {
|
if *app_state.scrolling.get() == false {
|
||||||
app_state.scrollevent.set(true);
|
app_state.scrollevent.set(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -846,7 +854,7 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
//let csignal = csignal.clone();
|
//let csignal = csignal.clone();
|
||||||
//csignal.set(true);
|
//csignal.set(true);
|
||||||
let app_state2 = app_state2.clone();
|
let app_state2 = app_state2.clone();
|
||||||
if *app_state2.scrolling.get() == true {
|
if *app_state2.scrolling.get() == false {
|
||||||
app_state2.scrollevent.set(true);
|
app_state2.scrollevent.set(true);
|
||||||
}
|
}
|
||||||
info!("Got scroll event");
|
info!("Got scroll event");
|
||||||
@@ -879,13 +887,21 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
key =|x| x.id )
|
key =|x| x.id )
|
||||||
}
|
}
|
||||||
br{}
|
br{}
|
||||||
(if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() {
|
(if *app_state.scrolling.get() == true {
|
||||||
view!{ cx,
|
view!{ cx,
|
||||||
div(class="flex flex-col items-center"){
|
div(class="flex flex-col items-center m-5"){
|
||||||
button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" }
|
div(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"){ "Loading ..." }
|
||||||
}
|
}
|
||||||
}} else {
|
}} else {
|
||||||
view!{ cx, ""}
|
view!{ cx,
|
||||||
|
(if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() {
|
||||||
|
view!{ cx,
|
||||||
|
div(class="flex flex-col items-center m-5"){
|
||||||
|
button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" }
|
||||||
|
}
|
||||||
|
}} else {
|
||||||
|
view!{ cx, ""}
|
||||||
|
})}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,13 +917,22 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|||||||
key =|x| x.id )
|
key =|x| x.id )
|
||||||
}
|
}
|
||||||
br{}
|
br{}
|
||||||
(if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() {
|
|
||||||
|
(if *app_state.scrolling.get() == true {
|
||||||
view!{ cx,
|
view!{ cx,
|
||||||
div(class="flex flex-col items-center"){
|
div(class="flex flex-col items-center m-5"){
|
||||||
button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" }
|
div(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"){ "Loading ..." }
|
||||||
}
|
}
|
||||||
}} else {
|
}} else {
|
||||||
view!{ cx, ""}
|
view!{ cx,
|
||||||
|
(if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() {
|
||||||
|
view!{ cx,
|
||||||
|
div(class="flex flex-col items-center m-5"){
|
||||||
|
button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" }
|
||||||
|
}
|
||||||
|
}} else {
|
||||||
|
view!{ cx, ""}
|
||||||
|
})}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +966,7 @@ pub fn BookDB<G: Html>(cx: Scope, bookitem: BookUIProp) -> View<G> {
|
|||||||
.description
|
.description
|
||||||
.unwrap_or("".to_string());
|
.unwrap_or("".to_string());
|
||||||
let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string());
|
let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string());
|
||||||
if locdesc.clone().len() > 200 {
|
if locdesc.clone().chars().count() > 200 {
|
||||||
locdesc = format!("{:.200}...", locdesc.clone())
|
locdesc = format!("{:.200}...", locdesc.clone())
|
||||||
}
|
}
|
||||||
//let locref = create_rc_signal(false);
|
//let locref = create_rc_signal(false);
|
||||||
@@ -1038,7 +1063,7 @@ pub fn BookDB_View<G: Html>(cx: Scope, bookitem: BookUIProp) -> View<G> {
|
|||||||
.description
|
.description
|
||||||
.unwrap_or("".to_string());
|
.unwrap_or("".to_string());
|
||||||
let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string());
|
let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string());
|
||||||
if locdesc.clone().len() > 200 {
|
if locdesc.clone().chars().count() > 200 {
|
||||||
locdesc = format!("{:.200}...", locdesc.clone())
|
locdesc = format!("{:.200}...", locdesc.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,7 +1085,7 @@ pub fn BookDB_View<G: Html>(cx: Scope, bookitem: BookUIProp) -> View<G> {
|
|||||||
app_state.displayingbook.set(bookdisplay_div.clone());
|
app_state.displayingbook.set(bookdisplay_div.clone());
|
||||||
};
|
};
|
||||||
view! { cx,
|
view! { cx,
|
||||||
div(class="col-span-1 px-4 py-4 bg-gray-200 border-2 border-gray-400 rounded m-3"){
|
div(class="col-span-1 px-4 py-4 bg-gray-200 border-2 border-gray-400 rounded m-3", on:click=handle_display_div){
|
||||||
|
|
||||||
|
|
||||||
div(class="card-buttons"){
|
div(class="card-buttons"){
|
||||||
@@ -1068,7 +1093,7 @@ pub fn BookDB_View<G: Html>(cx: Scope, bookitem: BookUIProp) -> View<G> {
|
|||||||
button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_display){ i(class="fa-solid fa-circle-info") }
|
button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_display){ i(class="fa-solid fa-circle-info") }
|
||||||
|
|
||||||
}
|
}
|
||||||
div(class="card-main", on:click=handle_display_div){
|
div(class="card-main"){
|
||||||
img(class="float-right m-1",src=coverurl,width="100")
|
img(class="float-right m-1",src=coverurl,width="100")
|
||||||
|
|
||||||
div(class="card-title font-bold text-lg"){
|
div(class="card-title font-bold text-lg"){
|
||||||
@@ -2226,7 +2251,6 @@ fn App<G: Html>(cx: Scope) -> View<G> {
|
|||||||
ListOL {}
|
ListOL {}
|
||||||
ListDB{}
|
ListDB{}
|
||||||
}
|
}
|
||||||
//PageBar{}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user