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::task::spawn_local;
|
||||
use std::collections::HashSet;
|
||||
use icons::{ArrowUpDown};
|
||||
use icons::{ArrowUpDown, Inbox};
|
||||
use crate::store::{get_action_messages, show_toast};
|
||||
use crate::api;
|
||||
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::checkbox::Checkbox;
|
||||
use crate::components::ui::button::{Button, ButtonVariant};
|
||||
use crate::components::ui::empty::*;
|
||||
|
||||
fn format_bytes(bytes: i64) -> String {
|
||||
const UNITS: [&str; 6] = ["B", "KB", "MB", "GB", "TB", "PB"];
|
||||
@@ -220,6 +221,44 @@ pub fn TorrentTable() -> impl IntoView {
|
||||
</DataTableRow>
|
||||
</DataTableHeader>
|
||||
<DataTableBody>
|
||||
<Show
|
||||
when=move || !filtered_hashes.get().is_empty()
|
||||
fallback=move || view! {
|
||||
<DataTableRow class="hover:bg-transparent">
|
||||
<DataTableCell attr:colspan="9" class="h-[400px]">
|
||||
<Empty class="h-full">
|
||||
<EmptyHeader>
|
||||
<EmptyMedia variant=EmptyMediaVariant::Icon>
|
||||
<Inbox class="size-10" />
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>"Torrent Bulunamadı"</EmptyTitle>
|
||||
<EmptyDescription>
|
||||
{move || {
|
||||
let query = store.search_query.get();
|
||||
if query.is_empty() {
|
||||
"Henüz eklenmiş bir torrent bulunmuyor.".to_string()
|
||||
} 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| {
|
||||
@@ -243,6 +282,7 @@ pub fn TorrentTable() -> impl IntoView {
|
||||
}
|
||||
}
|
||||
} />
|
||||
</Show>
|
||||
</DataTableBody>
|
||||
</DataTable>
|
||||
</div>
|
||||
@@ -259,6 +299,20 @@ pub fn TorrentTable() -> impl IntoView {
|
||||
// --- MOBILE VIEW ---
|
||||
<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">
|
||||
<Show
|
||||
when=move || !filtered_hashes.get().is_empty()
|
||||
fallback=move || view! {
|
||||
<Empty class="h-64 mt-10">
|
||||
<EmptyHeader>
|
||||
<EmptyMedia variant=EmptyMediaVariant::Icon>
|
||||
<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| {
|
||||
@@ -269,6 +323,7 @@ pub fn TorrentTable() -> impl IntoView {
|
||||
}
|
||||
}
|
||||
} />
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,3 +7,4 @@ pub mod theme_toggle;
|
||||
pub mod svg_icon;
|
||||
pub mod table;
|
||||
pub mod data_table;pub mod checkbox;
|
||||
pub mod empty;
|
||||
|
||||
Reference in New Issue
Block a user