feat(web): add users active search

signup-links
Jef Roosens 2025-06-29 11:09:54 +02:00
parent fce301080c
commit 6c8183c1e3
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
3 changed files with 48 additions and 7 deletions

View File

@ -4,6 +4,7 @@ use axum::{
http::HeaderMap,
routing::{delete, get},
};
use serde::Deserialize;
use crate::{
server::{
@ -22,24 +23,46 @@ pub fn router(ctx: Context) -> Router<Context> {
))
}
pub async fn get_users(
#[derive(Deserialize, Clone)]
struct UserFilter {
username: Option<String>,
}
impl From<UserFilter> for gpodder::UserFilter {
fn from(value: UserFilter) -> Self {
Self {
username: value.username,
}
}
}
impl ToQuery for UserFilter {
fn to_query(self) -> crate::web::Query {
crate::web::Query::default().opt_parameter("username", self.username)
}
}
async fn get_users(
State(ctx): State<Context>,
headers: HeaderMap,
Extension(session): Extension<gpodder::Session>,
Query(page): Query<super::Pagination>,
Query(filter): Query<UserFilter>,
) -> AppResult<TemplateResponse<Page<View>>> {
let next_page = page.next_page();
let filter_clone = filter.clone();
let user_id = session.user.id;
let users = tokio::task::spawn_blocking(move || {
ctx.store
.admin(&session.user)?
.paginated_users(page.into(), &gpodder::UserFilter::default())
.paginated_users(page.into(), &filter.into())
})
.await
.unwrap()?;
let next_page_query =
(users.len() == next_page.per_page as usize).then_some(next_page.to_query());
let next_page_query = (users.len() == next_page.per_page as usize)
.then_some(next_page.to_query().join(filter_clone));
Ok(View::Users(users, user_id, next_page_query)
.page(&headers)

View File

@ -23,6 +23,15 @@ impl Query {
self
}
/// Convenience method for adding possibly empty parameter values from options
pub fn opt_parameter(self, key: impl ToString, value: Option<impl ToString>) -> Self {
if let Some(value) = value {
self.parameter(key, value)
} else {
self
}
}
}
/// Allows objects to be converted into queries

View File

@ -1,15 +1,24 @@
<h1>Users</h1>
<table>
<input
type="text" id="username" name="username"
hx-get="/users"
hx-target="#users > tbody"
hx-swap="innerHTML"
hx-select="table > tbody > tr"
hx-trigger="input changed delay:500ms"
placeholder="Search..."
/>
<table id="users">
<thead>
<th>Username</th>
</thead>
<tbody>
{% for user in users %}
{%- for user in users %}
<tr>
<th>{{ user.username }}</th>
</tr>
{% endfor %}
{% endfor -%}
{%- if next_page_query %}
<tr