diff --git a/api/libs/database/src/enums.rs b/api/libs/database/src/enums.rs index 0bcb1e66b..33d7740fd 100644 --- a/api/libs/database/src/enums.rs +++ b/api/libs/database/src/enums.rs @@ -240,10 +240,11 @@ pub enum AssetType { Thread, Collection, Chat, - #[serde(alias = "metric")] + #[serde(rename = "metric")] MetricFile, - #[serde(alias = "dashboard")] + #[serde(rename = "dashboard")] DashboardFile, + } #[derive( diff --git a/api/libs/handlers/src/favorites/favorites_utils.rs b/api/libs/handlers/src/favorites/favorites_utils.rs index d24296787..8e661a904 100644 --- a/api/libs/handlers/src/favorites/favorites_utils.rs +++ b/api/libs/handlers/src/favorites/favorites_utils.rs @@ -10,7 +10,7 @@ use database::{ enums::AssetType, pool::get_pg_pool, models::UserFavorite, - schema::{collections, collections_to_assets, dashboards, messages_deprecated, threads_deprecated, user_favorites}, + schema::{collections, collections_to_assets, dashboards, messages_deprecated, threads_deprecated, user_favorites, metric_files}, }; use middleware::AuthenticatedUser; @@ -90,6 +90,7 @@ pub async fn list_user_favorites(user: &AuthenticatedUser) -> Result Result { - (dashboard_fav_res, collection_fav_res, threads_fav_res) + let metrics_favorites = { + let metric_ids = Arc::new( + user_favorites + .iter() + .filter(|(_, f)| f == &AssetType::MetricFile) + .map(|f| f.0) + .collect::>(), + ); + tokio::spawn(async move { get_favorite_metrics(metric_ids) }) + }; + + let (dashboard_fav_res, collection_fav_res, threads_fav_res, metrics_fav_res) = + match tokio::try_join!(dashboard_favorites, collection_favorites, threads_favorites, metrics_favorites) { + Ok((dashboard_fav_res, collection_fav_res, threads_fav_res, metrics_fav_res)) => { + (dashboard_fav_res, collection_fav_res, threads_fav_res, metrics_fav_res) } Err(e) => { tracing::error!("Error getting favorite assets: {}", e); @@ -136,6 +148,14 @@ pub async fn list_user_favorites(user: &AuthenticatedUser) -> Result metrics, + Err(e) => { + tracing::error!("Error getting favorite metrics: {}", e); + return Err(anyhow!("Error getting favorite metrics: {}", e)); + } + }; + let mut favorites: Vec = Vec::with_capacity(user_favorites.len()); for favorite in &user_favorites { @@ -158,6 +178,11 @@ pub async fn list_user_favorites(user: &AuthenticatedUser) -> Result { + if let Some(metric) = favorite_metrics.iter().find(|m| m.id == favorite.0) { + favorites.push(FavoriteEnum::Object(metric.clone())); + } + } _ => {} } } @@ -426,6 +451,35 @@ async fn get_threads_from_collections( Ok(thread_objects) } +async fn get_favorite_metrics(metric_ids: Arc>) -> Result> { + let mut conn = match get_pg_pool().get().await { + Ok(conn) => conn, + Err(e) => return Err(anyhow!("Error getting connection from pool: {:?}", e)), + }; + + let metric_records: Vec<(Uuid, String)> = match metric_files::table + .select((metric_files::id, metric_files::name)) + .filter(metric_files::id.eq_any(metric_ids.as_ref())) + .filter(metric_files::deleted_at.is_null()) + .load::<(Uuid, String)>(&mut conn) + .await + { + Ok(metric_records) => metric_records, + Err(diesel::NotFound) => return Err(anyhow!("Metrics not found")), + Err(e) => return Err(anyhow!("Error loading metric records: {:?}", e)), + }; + + let favorite_metrics = metric_records + .iter() + .map(|(id, name)| FavoriteObject { + id: id.clone(), + name: name.clone(), + type_: AssetType::MetricFile, + }) + .collect(); + Ok(favorite_metrics) +} + pub async fn update_favorites(user: &AuthenticatedUser, favorites: &Vec) -> Result<()> { let mut conn = match get_pg_pool().get().await { Ok(conn) => conn, diff --git a/api/src/routes/rest/routes/users/favorites/mod.rs b/api/src/routes/rest/routes/users/favorites/mod.rs index 6818afcd8..b31f25190 100644 --- a/api/src/routes/rest/routes/users/favorites/mod.rs +++ b/api/src/routes/rest/routes/users/favorites/mod.rs @@ -14,5 +14,5 @@ pub fn router() -> Router { .route("/", get(list_favorites::list_favorites_handler)) .route("/", post(create_favorite::create_favorite_handler)) .route("/:id", delete(delete_favorite::delete_favorite_handler)) - .route("/order", put(update_favorites::update_favorites_handler)) + .route("/", put(update_favorites::update_favorites_handler)) } diff --git a/api/src/routes/rest/routes/users/favorites/update_favorites.rs b/api/src/routes/rest/routes/users/favorites/update_favorites.rs index 4f16e43bf..cf95ac841 100644 --- a/api/src/routes/rest/routes/users/favorites/update_favorites.rs +++ b/api/src/routes/rest/routes/users/favorites/update_favorites.rs @@ -1,21 +1,14 @@ -use axum::{ - extract::Json, - http::StatusCode, Extension, -}; -use uuid::Uuid; -use handlers::favorites::{FavoriteEnum, UserFavoritesReq, update_favorites}; +use axum::{extract::Json, http::StatusCode, Extension}; +use handlers::favorites::{update_favorites, FavoriteEnum}; use middleware::AuthenticatedUser; +use uuid::Uuid; pub async fn update_favorites_handler( - Extension(user): Extension, Json(payload): Json, + Extension(user): Extension, + Json(payload): Json>, ) -> Result>, (StatusCode, String)> { - let favorite_ids: Vec = payload - .favorites - .into_iter() - .map(|favorite| favorite.id) - .collect(); - match update_favorites(&user, &favorite_ids).await { + match update_favorites(&user, &payload).await { Ok(_) => { // After updating, fetch the updated list to return match handlers::favorites::list_favorites(&user).await { @@ -28,7 +21,7 @@ pub async fn update_favorites_handler( )) } } - }, + } Err(e) => { tracing::error!("Error updating favorites: {:?}", e); Err((