Refactor DashboardCollectionList: Simplify search input layout and improve tag selection logic for better user experience.

This commit is contained in:
Peter Meier
2026-03-12 16:36:20 +01:00
parent 22b4367c47
commit 7754d800f5
17 changed files with 759 additions and 151 deletions

View File

@@ -146,9 +146,9 @@ async fn main() -> anyhow::Result<()> {
let registry = Arc::new(RwLock::new(registry));
let openapi_spec = Arc::new(RwLock::new(openapi_spec));
let api_key = std::env::var("RUSTYCMS_API_KEY").ok();
if api_key.is_some() {
tracing::info!("API key auth enabled (POST/PUT/DELETE require key)");
let api_keys = rustycms::api::auth::ApiKeys::from_env();
if api_keys.as_ref().map(|k| k.is_enabled()).unwrap_or(false) {
tracing::info!("API key auth enabled (write operations require key with role)");
}
let cache_ttl_secs = std::env::var("RUSTYCMS_CACHE_TTL_SECS")
@@ -173,23 +173,72 @@ async fn main() -> anyhow::Result<()> {
let assets_dir = cli.content_dir.join("assets");
// RUSTYCMS_ENVIRONMENTS: comma-separated list (e.g. production,staging). File store only.
// Content for first env = content_dir; others = content_dir/<env>. Assets = content_dir/assets or content_dir/<env>/assets.
let store_kind = std::env::var("RUSTYCMS_STORE").unwrap_or_else(|_| "file".into());
let (environments, stores_map, assets_dirs_map, store, assets_dir) = match std::env::var("RUSTYCMS_ENVIRONMENTS").ok().as_deref() {
Some(s) if !s.trim().is_empty() && store_kind != "sqlite" => {
let env_list: Vec<String> = s.split(',').map(|e| e.trim().to_string()).filter(|e| !e.is_empty()).collect();
if env_list.is_empty() {
(None, None, None, store, assets_dir)
} else {
let mut stores = std::collections::HashMap::new();
let mut assets_dirs = std::collections::HashMap::new();
for (i, name) in env_list.iter().enumerate() {
let content_base = if i == 0 {
cli.content_dir.clone()
} else {
cli.content_dir.join(name)
};
let assets_path = if i == 0 {
cli.content_dir.join("assets")
} else {
cli.content_dir.join(name).join("assets")
};
let s = FileStore::new(&content_base);
stores.insert(name.clone(), Arc::new(s) as Arc<dyn rustycms::store::ContentStore>);
assets_dirs.insert(name.clone(), assets_path);
}
let default_store = stores.get(&env_list[0]).cloned().unwrap();
let default_assets = assets_dirs.get(&env_list[0]).cloned().unwrap();
tracing::info!("Environments enabled: {:?} (default: {})", env_list, &env_list[0]);
(Some(env_list), Some(stores), Some(assets_dirs), default_store, default_assets)
}
}
_ => {
if std::env::var("RUSTYCMS_ENVIRONMENTS").is_ok() && store_kind == "sqlite" {
tracing::warn!("RUSTYCMS_ENVIRONMENTS is ignored when using SQLite store");
}
(None, None, None, store, assets_dir)
}
};
// RUSTYCMS_BASE_URL is the public URL of the API (e.g. https://api.example.com).
// Used to expand relative /api/assets/ paths to absolute URLs in responses.
// Falls back to the local server_url (http://host:port).
let base_url = std::env::var("RUSTYCMS_BASE_URL").unwrap_or_else(|_| server_url.clone());
let webhook_urls = rustycms::api::webhooks::urls_from_env();
if !webhook_urls.is_empty() {
tracing::info!("Webhooks enabled: {} URL(s)", webhook_urls.len());
}
let state = Arc::new(AppState {
registry: Arc::clone(&registry),
store,
openapi_spec: Arc::clone(&openapi_spec),
types_dir: cli.types_dir.clone(),
api_key,
api_keys,
cache: Arc::clone(&cache),
transform_cache,
http_client,
locales,
assets_dir,
base_url,
webhook_urls,
environments,
stores: stores_map,
assets_dirs: assets_dirs_map,
});
// Hot-reload: watch types_dir and reload schemas on change