use api::users::UserDto; use models::issue::issue_event_line::{self, IssueEventType}; use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect}; use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use utoipa::{IntoParams, ToSchema}; use uuid::Uuid; use crate::errors::IssueError; use crate::services::service::IssueService; use crate::share::lookup; #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct EventDto { pub id: Uuid, pub issue_id: Option, pub user: Option, pub event_type: IssueEventType, pub comment_id: Option, pub commit_sha: Option, pub old_title: Option, pub new_title: Option, pub old_ref: Option, pub new_ref: Option, pub content: Option, pub created_at: OffsetDateTime, } pub type EventPage = api::pagination::Page; #[derive(Debug, Clone, Deserialize, IntoParams, ToSchema)] #[serde(deny_unknown_fields)] pub struct ListEventQuery { pub limit: Option, pub offset: Option, } #[derive(Debug, Clone, Deserialize, IntoParams, ToSchema)] pub struct EventPath { pub space_name: String, pub board_id: Uuid, pub issue_id: String, } impl IssueService { pub async fn list_events( &self, caller: i64, space_name: &str, board_id: Uuid, issue_id: Uuid, q: ListEventQuery, ) -> Result { lookup::require_issue_access(self, caller, space_name, board_id, issue_id).await?; let (limit, offset) = self.paginate(q.limit, q.offset)?; let select = issue_event_line::Entity::find() .filter(issue_event_line::Column::IssueId.eq(Some(issue_id))) .order_by_desc(issue_event_line::Column::CreatedAt); let total = select.clone().count(self.database.read()).await?; let rows = select .limit(limit) .offset(offset) .all(self.database.read()) .await?; let user_ids: Vec = rows.iter().map(|e| e.user_id).collect(); let user_map = self.audience.load_user_briefs(&user_ids).await?; let items = rows .into_iter() .map(|e| { let user = user_map.get(&e.user_id).cloned(); EventDto { id: e.id, issue_id: e.issue_id, user, event_type: e.event_type, comment_id: e.comment_id, commit_sha: e.commit_sha, old_title: e.old_title, new_title: e.new_title, old_ref: e.old_ref, new_ref: e.new_ref, content: e.content, created_at: e.created_at, } }) .collect(); Ok(EventPage { items, total, limit, offset, }) } }