feat: DEFAULT_LANGUAGE/DEFAULT_TIMEZONE config + public GET /api/config
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
use axum::{Json, Router, extract::State, routing::get};
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
/// Public, non-sensitive instance configuration the SPA needs before login.
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub(crate) struct ConfigView {
|
||||
/// User-facing product name.
|
||||
pub app_name: String,
|
||||
/// Default UI/content language (i18n key, e.g. "sv").
|
||||
pub default_language: String,
|
||||
/// Default display timezone (IANA name). Storage is UTC; this is a display hint.
|
||||
pub default_timezone: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(get, path = "/api/config", responses((status = 200, body = ConfigView)))]
|
||||
pub(crate) async fn get_config(State(state): State<AppState>) -> Json<ConfigView> {
|
||||
Json(ConfigView {
|
||||
app_name: state.app_name.clone(),
|
||||
default_language: state.default_language.clone(),
|
||||
default_timezone: state.default_timezone.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn routes() -> Router<AppState> {
|
||||
Router::new().route("/api/config", get(get_config))
|
||||
}
|
||||
@@ -5,6 +5,7 @@ mod admin_authorities;
|
||||
mod admin_objects;
|
||||
mod admin_search;
|
||||
mod admin_vocab;
|
||||
mod config;
|
||||
mod health;
|
||||
mod openapi;
|
||||
mod pagination;
|
||||
@@ -30,6 +31,10 @@ pub struct AppState {
|
||||
/// Search client for on-write index sync. `None` disables indexing (search is a
|
||||
/// best-effort feature; absent when Meilisearch is not configured).
|
||||
pub search: Option<search::SearchClient>,
|
||||
/// Instance default UI/content language (from config).
|
||||
pub default_language: String,
|
||||
/// Instance default display timezone, IANA name (from config). Storage stays UTC.
|
||||
pub default_timezone: String,
|
||||
}
|
||||
|
||||
/// Best-effort: keep the search index in step with a catalogue write that has already
|
||||
@@ -58,6 +63,7 @@ pub fn build_app(state: AppState) -> Router {
|
||||
.with_expiry(Expiry::OnInactivity(Duration::hours(8)));
|
||||
|
||||
Router::new()
|
||||
.merge(config::routes())
|
||||
.merge(health::routes())
|
||||
.merge(openapi::routes())
|
||||
.merge(public::routes())
|
||||
|
||||
@@ -2,12 +2,14 @@ use axum::{Json, Router, extract::State, routing::get};
|
||||
use utoipa::OpenApi;
|
||||
|
||||
use crate::{
|
||||
AppState, admin, admin_authorities, admin_objects, admin_search, admin_vocab, health, public,
|
||||
AppState, admin, admin_authorities, admin_objects, admin_search, admin_vocab, config, health,
|
||||
public,
|
||||
};
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
config::get_config,
|
||||
health::live,
|
||||
health::ready,
|
||||
public::list_objects,
|
||||
@@ -34,6 +36,7 @@ use crate::{
|
||||
admin_authorities::create_authority
|
||||
),
|
||||
components(schemas(
|
||||
config::ConfigView,
|
||||
health::Live,
|
||||
health::Ready,
|
||||
public::PublicView,
|
||||
|
||||
Reference in New Issue
Block a user