diff --git a/libs/service/project/invitation.rs b/libs/service/project/invitation.rs index 3d180c8..596800e 100644 --- a/libs/service/project/invitation.rs +++ b/libs/service/project/invitation.rs @@ -1,8 +1,9 @@ use crate::AppService; use crate::error::AppError; use chrono::{DateTime, Utc}; +use futures::future::join_all; use models::projects::{ - MemberRole, project_audit_log, project_member_invitations, project_members, + project, MemberRole, project_audit_log, project_member_invitations, project_members, }; use models::users::{user, user_email}; use sea_orm::*; @@ -13,8 +14,10 @@ use uuid::Uuid; #[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)] pub struct InvitationResponse { pub project_uid: Uuid, + pub project_name: String, pub user_uid: Uuid, pub invited_by: Uuid, + pub invited_by_username: Option, pub scope: String, pub accepted: bool, pub accepted_at: Option>, @@ -31,18 +34,36 @@ pub struct InvitationListResponse { pub per_page: u64, } -impl From for InvitationResponse { - fn from(invitation: project_member_invitations::Model) -> Self { +impl InvitationResponse { + pub async fn from_model( + inv: project_member_invitations::Model, + db: &DatabaseConnection, + ) -> Self { + let project_name = project::Entity::find_by_id(inv.project) + .one(db) + .await + .ok() + .flatten() + .map(|p| p.name) + .unwrap_or_default(); + let invited_by_username = user::Entity::find_by_id(inv.invited_by) + .one(db) + .await + .ok() + .flatten() + .map(|u| u.username); InvitationResponse { - project_uid: invitation.project, - user_uid: invitation.user, - invited_by: invitation.invited_by, - scope: invitation.scope, - accepted: invitation.accepted, - accepted_at: invitation.accepted_at, - rejected: invitation.rejected, - rejected_at: invitation.rejected_at, - created_at: invitation.created_at, + project_uid: inv.project, + project_name, + user_uid: inv.user, + invited_by: inv.invited_by, + invited_by_username, + scope: inv.scope, + accepted: inv.accepted, + accepted_at: inv.accepted_at, + rejected: inv.rejected, + rejected_at: inv.rejected_at, + created_at: inv.created_at, } } } @@ -82,9 +103,31 @@ impl AppService { .count(&self.db) .await?; + let project_name = project.name.clone(); + let inviter_ids: Vec = invitations.iter().map(|i| i.invited_by).collect(); + let inviters: std::collections::HashMap> = user::Entity::find() + .filter(user::Column::Uid.is_in(inviter_ids)) + .all(&self.db) + .await? + .into_iter() + .map(|u| (u.uid, Some(u.username))) + .collect(); + let invitations = invitations .into_iter() - .map(InvitationResponse::from) + .map(|inv| InvitationResponse { + project_uid: inv.project, + project_name: project_name.clone(), + user_uid: inv.user, + invited_by: inv.invited_by, + invited_by_username: inviters.get(&inv.invited_by).cloned().flatten(), + scope: inv.scope, + accepted: inv.accepted, + accepted_at: inv.accepted_at, + rejected: inv.rejected, + rejected_at: inv.rejected_at, + created_at: inv.created_at, + }) .collect(); Ok(InvitationListResponse { @@ -122,9 +165,12 @@ impl AppService { .count(&self.db) .await?; - let invitations = invitations - .into_iter() - .map(InvitationResponse::from) + let invitations = join_all( + invitations + .into_iter() + .map(|inv| InvitationResponse::from_model(inv, self.db.writer())), + ) + .await; .collect(); Ok(InvitationListResponse {