acme_proxy_admin/webadmin/pages/
upstream_orders.rs1use axum::extract::{Path, Query, State};
10use axum::response::Html;
11use serde_json::Value;
12
13use crate::admin;
14use crate::webadmin::AdminState;
15use crate::webadmin::error::AdminError;
16use crate::webadmin::handlers::paging::PageParams;
17use crate::webadmin::handlers::upstream_orders::UpstreamOrderListParams;
18use crate::webadmin::pages::auth::PageSession;
19use crate::webadmin::pages::error::PageError;
20use crate::webadmin::pages::{ListFilters, chrome, page_value, pager, respond, vocabulary};
21use acme_proxy_store::status::UpstreamOrderStatus;
22use acme_proxy_store::upstream_order::UpstreamOrder;
23
24pub async fn list_upstream_orders(
26 State(state): State<AdminState>,
27 Query(params): Query<UpstreamOrderListParams>,
28 session: PageSession,
29) -> Result<Html<String>, PageError> {
30 let page = PageParams::from(params.limit, params.offset).resolve(&state.config);
31 let filters = ListFilters::new()
32 .with("profile", params.profile.as_deref())
33 .with("status", params.status.as_deref());
34 let query = crate::webadmin::handlers::upstream_orders::upstream_order_query(¶ms, page)?;
36 let (rows, total) = UpstreamOrder::search(&query, &state.database).await?;
37 let items: Vec<Value> = rows.iter().map(admin::render_upstream_order_json).collect();
38
39 let mut context = chrome(&session, "upstream_orders", "Upstream orders");
40 context.insert("page".to_string(), page_value(items, total));
41 context.insert(
42 "pager".to_string(),
43 pager(
44 page,
45 total,
46 "/ui/upstream-orders",
47 &filters.pairs(),
48 "#upstream-orders-table",
49 ),
50 );
51 context.insert("filters".to_string(), filters.to_value());
52 context.insert(
53 "statuses".to_string(),
54 vocabulary(UpstreamOrderStatus::ALL, |status| status.as_str()),
55 );
56 context.insert(
57 "profiles".to_string(),
58 Value::Array(crate::webadmin::handlers::misc::profile_rows(&state)),
59 );
60
61 respond(
62 &state,
63 session.hx,
64 "upstream_orders/list.html",
65 "upstream_orders/_table.html",
66 context,
67 )
68}
69
70pub async fn get_upstream_order(
72 State(state): State<AdminState>,
73 Path(id): Path<String>,
74 session: PageSession,
75) -> Result<Html<String>, PageError> {
76 let detail = admin::load_upstream_order_detail(&id, state.database.clone())
77 .await?
78 .ok_or_else(|| not_found(&id))?;
79
80 let mut context = chrome(&session, "upstream_orders", "Upstream order");
81 context.insert(
82 "detail".to_string(),
83 admin::render_upstream_order_detail_json(&detail),
84 );
85 respond(
86 &state,
87 session.hx,
88 "upstream_orders/detail.html",
89 "upstream_orders/_card.html",
90 context,
91 )
92}
93
94fn not_found(id: &str) -> PageError {
95 AdminError::not_found(format!("no upstream order for local order {id}")).into()
96}