Lines
26.67 %
Functions
16.67 %
Branches
100 %
use askama::Template;
use axum::{Extension, Json, extract::State, response::IntoResponse};
use serde::Deserialize;
use server::command::{CmdResult, FinanceEntity, account::ListAccounts};
use sqlx::types::Uuid;
use std::sync::Arc;
use crate::{AppState, jwt_auth::JWTAuthMiddleware, pages::HtmlTemplate};
#[derive(Deserialize)]
pub struct AccountSearch {
#[serde(rename = "parent-search")]
query: Option<String>,
}
#[derive(Template)]
#[template(path = "components/account/search_results.html")]
struct AccountSearchResults {
accounts: Vec<AccountView>,
struct AccountView {
id: Uuid,
name: String,
pub async fn search_accounts(
State(_data): State<Arc<AppState>>,
Extension(jwt_auth): Extension<JWTAuthMiddleware>,
Json(form): Json<AccountSearch>,
) -> impl IntoResponse {
let result = match ListAccounts::new().user_id(jwt_auth.user.id).run().await {
Ok(Some(CmdResult::TaggedEntities(entities))) => entities,
_ => return HtmlTemplate(AccountSearchResults { accounts: vec![] }),
};
let mut accounts = Vec::new();
for (entity, tags) in result {
if let FinanceEntity::Account(account) = entity {
// Find name tag
let name = if let FinanceEntity::Tag(n) = &tags["name"] {
n.tag_value.clone()
} else {
continue;
// Filter by search query if provided
if let Some(query) = &form.query {
if query.is_empty() || name.to_lowercase().contains(&query.to_lowercase()) {
accounts.push(AccountView {
id: account.id,
name,
});
HtmlTemplate(AccountSearchResults { accounts })