Skip to content

Commit b301111

Browse files
committed
feat(app): add entry count to cache table
1 parent 91afeb8 commit b301111

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

crates/site-app/src/pages/dashboard/cache.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ use crate::{
77
CacheItemLink, CreateCacheButton, DataTableRefreshButton,
88
LockClosedHeroIcon,
99
},
10+
formatting_utils::ThousandsSeparated,
1011
hooks::OrgHook,
11-
resources::cache::caches_in_org_query_scope,
12+
resources::cache::{
13+
caches_in_org_query_scope, entry_count_in_cache_query_scope,
14+
},
1215
};
1316

1417
#[island]
@@ -51,6 +54,7 @@ pub(super) fn CacheTable() -> impl IntoView {
5154
<thead>
5255
<th>"Name"</th>
5356
<th>"Visibility"</th>
57+
<th>"Entry Count"</th>
5458
</thead>
5559
<Transition fallback=|| ()>
5660
{ suspend }
@@ -62,6 +66,21 @@ pub(super) fn CacheTable() -> impl IntoView {
6266

6367
#[component]
6468
fn CacheDataRow(cache: PvCache) -> impl IntoView {
69+
let query_client = expect_context::<QueryClient>();
70+
71+
let entry_count_query_scope = entry_count_in_cache_query_scope();
72+
let entry_count_key = move || cache.id;
73+
let entry_count_resource =
74+
query_client.resource(entry_count_query_scope, entry_count_key);
75+
let entry_count_suspend = move || {
76+
Suspend::new(async move {
77+
match entry_count_resource.await {
78+
Ok(count) => ThousandsSeparated(count).to_string().into_any(),
79+
Err(_) => "[error]".into_any(),
80+
}
81+
})
82+
};
83+
6584
view! {
6685
<tr>
6786
<th scope="row"><CacheItemLink id=cache.id extra_class="text-link-primary"/></th>
@@ -71,6 +90,9 @@ fn CacheDataRow(cache: PvCache) -> impl IntoView {
7190
<LockClosedHeroIcon {..} class="size-4 stroke-base-11/75 stroke-[2.0]" />
7291
})}
7392
</td>
93+
<td><Transition fallback=|| "[loading]">
94+
{ entry_count_suspend }
95+
</Transition></td>
7496
</tr>
7597
}
7698
}

crates/site-app/src/resources/cache.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use leptos::prelude::*;
22
use leptos_fetch::{QueryClient, QueryScope};
3-
use models::{dvf::RecordId, model::Model, Cache, Org, PvCache};
3+
use models::{dvf::RecordId, model::Model, Cache, Entry, Org, PvCache};
44

55
#[cfg(feature = "ssr")]
66
use crate::resources::{authenticate, authorize_for_org};
@@ -122,3 +122,41 @@ pub async fn check_if_cache_name_is_available(
122122

123123
Ok(!occupied)
124124
}
125+
126+
pub fn entry_count_in_cache_query_scope(
127+
) -> QueryScope<RecordId<Cache>, Result<u32, ServerFnError>> {
128+
QueryScope::new(count_entries_in_cache).with_invalidation_link(move |s| {
129+
[
130+
Cache::TABLE_NAME.to_string(),
131+
s.to_string(),
132+
Entry::TABLE_NAME.to_string(),
133+
]
134+
})
135+
}
136+
137+
#[server(prefix = "/api/sfn")]
138+
pub async fn count_entries_in_cache(
139+
cache: RecordId<Cache>,
140+
) -> Result<u32, ServerFnError> {
141+
use prime_domain::PrimeDomainService;
142+
143+
let prime_domain_service: PrimeDomainService = expect_context();
144+
let cache = prime_domain_service
145+
.fetch_cache_by_id(cache)
146+
.await
147+
.map_err(|e| {
148+
tracing::error!("failed to fetch cache: {e}");
149+
ServerFnError::new("internal error")
150+
})?
151+
.ok_or(ServerFnError::new("cache does not exist"))?;
152+
153+
authorize_for_org(cache.org)?;
154+
155+
prime_domain_service
156+
.count_entries_in_cache(cache.id)
157+
.await
158+
.map_err(|e| {
159+
tracing::error!("failed to count entries in cache ({}): {e}", cache.id);
160+
ServerFnError::new("internal error")
161+
})
162+
}

0 commit comments

Comments
 (0)