feat: add empty state to torrent table for better user feedback
Some checks failed
Build MIPS Binary / build (push) Failing after 1m33s
Some checks failed
Build MIPS Binary / build (push) Failing after 1m33s
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos::task::spawn_local;
|
use leptos::task::spawn_local;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use icons::{ArrowUpDown};
|
use icons::{ArrowUpDown, Inbox};
|
||||||
use crate::store::{get_action_messages, show_toast};
|
use crate::store::{get_action_messages, show_toast};
|
||||||
use crate::api;
|
use crate::api;
|
||||||
use shared::NotificationLevel;
|
use shared::NotificationLevel;
|
||||||
@@ -10,6 +10,7 @@ use crate::components::ui::card::{Card, CardHeader, CardTitle, CardContent as Ca
|
|||||||
use crate::components::ui::data_table::*;
|
use crate::components::ui::data_table::*;
|
||||||
use crate::components::ui::checkbox::Checkbox;
|
use crate::components::ui::checkbox::Checkbox;
|
||||||
use crate::components::ui::button::{Button, ButtonVariant};
|
use crate::components::ui::button::{Button, ButtonVariant};
|
||||||
|
use crate::components::ui::empty::*;
|
||||||
|
|
||||||
fn format_bytes(bytes: i64) -> String {
|
fn format_bytes(bytes: i64) -> String {
|
||||||
const UNITS: [&str; 6] = ["B", "KB", "MB", "GB", "TB", "PB"];
|
const UNITS: [&str; 6] = ["B", "KB", "MB", "GB", "TB", "PB"];
|
||||||
@@ -220,29 +221,68 @@ pub fn TorrentTable() -> impl IntoView {
|
|||||||
</DataTableRow>
|
</DataTableRow>
|
||||||
</DataTableHeader>
|
</DataTableHeader>
|
||||||
<DataTableBody>
|
<DataTableBody>
|
||||||
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
|
<Show
|
||||||
let on_action = on_action.clone();
|
when=move || !filtered_hashes.get().is_empty()
|
||||||
move |hash| {
|
fallback=move || view! {
|
||||||
let h = hash.clone();
|
<DataTableRow class="hover:bg-transparent">
|
||||||
let is_selected = Signal::derive(move || {
|
<DataTableCell attr:colspan="9" class="h-[400px]">
|
||||||
selected_hashes.with(|selected| selected.contains(&h))
|
<Empty class="h-full">
|
||||||
});
|
<EmptyHeader>
|
||||||
let h_for_change = hash.clone();
|
<EmptyMedia variant=EmptyMediaVariant::Icon>
|
||||||
view! {
|
<Inbox class="size-10" />
|
||||||
<TorrentRow
|
</EmptyMedia>
|
||||||
hash=hash.clone()
|
<EmptyTitle>"Torrent Bulunamadı"</EmptyTitle>
|
||||||
on_action=on_action.clone()
|
<EmptyDescription>
|
||||||
is_selected=is_selected
|
{move || {
|
||||||
on_select=Callback::new(move |checked| {
|
let query = store.search_query.get();
|
||||||
selected_hashes.update(|selected| {
|
if query.is_empty() {
|
||||||
if checked { selected.insert(h_for_change.clone()); }
|
"Henüz eklenmiş bir torrent bulunmuyor.".to_string()
|
||||||
else { selected.remove(&h_for_change); }
|
} else {
|
||||||
});
|
format!("'{}' araması için sonuç bulunamadı.", query)
|
||||||
})
|
}
|
||||||
/>
|
}}
|
||||||
}
|
</EmptyDescription>
|
||||||
|
</EmptyHeader>
|
||||||
|
<EmptyContent>
|
||||||
|
<Button
|
||||||
|
variant=ButtonVariant::Outline
|
||||||
|
on:click=move |_| {
|
||||||
|
store.search_query.set(String::new());
|
||||||
|
store.filter.set(crate::store::FilterStatus::All);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
"Tümünü Göster"
|
||||||
|
</Button>
|
||||||
|
</EmptyContent>
|
||||||
|
</Empty>
|
||||||
|
</DataTableCell>
|
||||||
|
</DataTableRow>
|
||||||
}
|
}
|
||||||
} />
|
>
|
||||||
|
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
|
||||||
|
let on_action = on_action.clone();
|
||||||
|
move |hash| {
|
||||||
|
let h = hash.clone();
|
||||||
|
let is_selected = Signal::derive(move || {
|
||||||
|
selected_hashes.with(|selected| selected.contains(&h))
|
||||||
|
});
|
||||||
|
let h_for_change = hash.clone();
|
||||||
|
view! {
|
||||||
|
<TorrentRow
|
||||||
|
hash=hash.clone()
|
||||||
|
on_action=on_action.clone()
|
||||||
|
is_selected=is_selected
|
||||||
|
on_select=Callback::new(move |checked| {
|
||||||
|
selected_hashes.update(|selected| {
|
||||||
|
if checked { selected.insert(h_for_change.clone()); }
|
||||||
|
else { selected.remove(&h_for_change); }
|
||||||
|
});
|
||||||
|
})
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} />
|
||||||
|
</Show>
|
||||||
</DataTableBody>
|
</DataTableBody>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
@@ -259,16 +299,31 @@ pub fn TorrentTable() -> impl IntoView {
|
|||||||
// --- MOBILE VIEW ---
|
// --- MOBILE VIEW ---
|
||||||
<div class="md:hidden flex flex-col h-full bg-muted/10 relative overflow-hidden">
|
<div class="md:hidden flex flex-col h-full bg-muted/10 relative overflow-hidden">
|
||||||
<div class="flex-1 overflow-y-auto p-3 min-h-0">
|
<div class="flex-1 overflow-y-auto p-3 min-h-0">
|
||||||
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
|
<Show
|
||||||
let on_action = on_action.clone();
|
when=move || !filtered_hashes.get().is_empty()
|
||||||
move |hash| {
|
fallback=move || view! {
|
||||||
view! {
|
<Empty class="h-64 mt-10">
|
||||||
<div class="pb-3">
|
<EmptyHeader>
|
||||||
<TorrentCard hash=hash.clone() on_action=on_action.clone() />
|
<EmptyMedia variant=EmptyMediaVariant::Icon>
|
||||||
</div>
|
<Inbox class="size-10" />
|
||||||
}
|
</EmptyMedia>
|
||||||
|
<EmptyTitle>"Boş Görünüyor"</EmptyTitle>
|
||||||
|
<EmptyDescription>"Burada gösterilecek bir şey yok."</EmptyDescription>
|
||||||
|
</EmptyHeader>
|
||||||
|
</Empty>
|
||||||
}
|
}
|
||||||
} />
|
>
|
||||||
|
<For each=move || filtered_hashes.get() key=|hash| hash.clone() children={
|
||||||
|
let on_action = on_action.clone();
|
||||||
|
move |hash| {
|
||||||
|
view! {
|
||||||
|
<div class="pb-3">
|
||||||
|
<TorrentCard hash=hash.clone() on_action=on_action.clone() />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} />
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ pub mod theme_toggle;
|
|||||||
pub mod svg_icon;
|
pub mod svg_icon;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
pub mod data_table;pub mod checkbox;
|
pub mod data_table;pub mod checkbox;
|
||||||
|
pub mod empty;
|
||||||
|
|||||||
Reference in New Issue
Block a user