From e967cc8a633df5f4a065a6a1adf89632e392d10a Mon Sep 17 00:00:00 2001 From: "benjamin.747" Date: Fri, 18 Oct 2024 17:19:49 +0800 Subject: [PATCH] add pagination in some api --- ceres/src/api_service/mod.rs | 8 +- ceres/src/api_service/mono_api_service.rs | 29 ++++-- ceres/src/lfs/handler.rs | 11 +-- ceres/src/pack/import_repo.rs | 8 +- ceres/src/pack/monorepo.rs | 4 +- common/src/model.rs | 28 ++++++ jupiter/Cargo.toml | 2 +- jupiter/callisto/src/db_enums.rs | 2 + jupiter/src/storage/git_db_storage.rs | 14 ++- jupiter/src/storage/lfs_db_storage.rs | 10 +- jupiter/src/storage/mono_storage.rs | 16 ++-- mega/Cargo.toml | 7 -- mono/Cargo.toml | 11 --- mono/src/api/mod.rs | 1 + mono/src/api/model.rs | 7 ++ mono/src/api/mr_router.rs | 45 +++++---- mono/src/api/oauth/model.rs | 4 +- mono/src/api/user/model.rs | 4 +- moon/src/app/(dashboard)/mr/[id]/page.tsx | 4 +- moon/src/app/(dashboard)/mr/page.tsx | 112 ++++++++++++++++++---- moon/src/app/api/mr/list/route.ts | 12 ++- moon/src/components/MergeList.tsx | 68 ------------- 22 files changed, 228 insertions(+), 179 deletions(-) create mode 100644 mono/src/api/model.rs delete mode 100644 moon/src/components/MergeList.tsx diff --git a/ceres/src/api_service/mod.rs b/ceres/src/api_service/mod.rs index dff6a4e8f..41fc99431 100644 --- a/ceres/src/api_service/mod.rs +++ b/ceres/src/api_service/mod.rs @@ -238,9 +238,8 @@ pub trait ApiHandler: Send + Sync { let root_tree = self.get_root_tree().await; let mut search_tree = root_tree.clone(); let mut update_tree = vec![root_tree]; - let component_num = relative_path.components().count(); - for (index, component) in relative_path.components().enumerate() { + for component in relative_path.components() { // root tree already found if component != Component::RootDir { let target_name = component.as_os_str().to_str().unwrap(); @@ -252,10 +251,7 @@ pub trait ApiHandler: Send + Sync { if let Some(search_res) = search_res { let res = self.get_tree_by_hash(&search_res.id.to_plain_str()).await; search_tree = res.clone(); - // skip last component - if index != component_num - 1 { - update_tree.push(res); - } + update_tree.push(res); } else { return Err(GitError::CustomError( "Path not exist, please create path first!".to_string(), diff --git a/ceres/src/api_service/mono_api_service.rs b/ceres/src/api_service/mono_api_service.rs index 992221267..027641804 100644 --- a/ceres/src/api_service/mono_api_service.rs +++ b/ceres/src/api_service/mono_api_service.rs @@ -7,6 +7,7 @@ use axum::async_trait; use callisto::db_enums::{ConvType, MergeStatus}; use callisto::{mega_blob, mega_tree, raw_blob}; use common::errors::MegaError; +use common::model::PageParams; use jupiter::context::Context; use jupiter::storage::batch_save_model; use jupiter::utils::converter::generate_git_keep_with_timestamp; @@ -195,7 +196,11 @@ impl ApiHandler for MonoApiService { } impl MonoApiService { - pub async fn mr_list(&self, status: &str) -> Result, MegaError> { + pub async fn mr_list( + &self, + status: &str, + pagination: PageParams, + ) -> Result<(Vec, u64), MegaError> { let status = if status == "open" { vec![MergeStatus::Open] } else if status == "closed" { @@ -204,8 +209,11 @@ impl MonoApiService { vec![MergeStatus::Open, MergeStatus::Closed, MergeStatus::Merged] }; let storage = self.context.services.mono_storage.clone(); - let mr_list = storage.get_mr_by_status(status).await.unwrap(); - Ok(mr_list.into_iter().map(|m| m.into()).collect()) + let (mr_list, total) = storage + .get_mr_by_status(status, pagination.page, pagination.per_page) + .await + .unwrap(); + Ok((mr_list.into_iter().map(|m| m.into()).collect(), total)) } pub async fn mr_detail(&self, mr_link: &str) -> Result, MegaError> { @@ -280,19 +288,13 @@ impl MonoApiService { let refs = storage.get_ref(&mr.path).await.unwrap().unwrap(); if mr.from_hash == refs.ref_commit_hash { - // update mr - mr.merge(); let commit: Commit = storage .get_commit_by_hash(&mr.to_hash) .await .unwrap() .unwrap() .into(); - // add conversation - storage - .add_mr_conversation(&mr.mr_link, 0, ConvType::Merged, None) - .await - .unwrap(); + if mr.path != "/" { let path = PathBuf::from(mr.path.clone()); // beacuse only parent tree is needed so we skip current directory @@ -307,6 +309,13 @@ impl MonoApiService { storage.remove_refs(&mr.path).await.unwrap(); // TODO: self.clean_dangling_commits().await; } + // update mr + mr.merge(); + // add conversation + storage + .add_mr_conversation(&mr.mr_link, 0, ConvType::Merged, None) + .await + .unwrap(); // update mr status last storage.update_mr(mr.clone().into()).await.unwrap(); } else { diff --git a/ceres/src/lfs/handler.rs b/ceres/src/lfs/handler.rs index 891a52fdb..d2cc861da 100644 --- a/ceres/src/lfs/handler.rs +++ b/ceres/src/lfs/handler.rs @@ -16,7 +16,6 @@ use futures::Stream; use jupiter::context::Context; use jupiter::storage::lfs_db_storage::LfsDbStorage; use rand::prelude::*; -use sea_orm::ActiveValue::Set; use sea_orm::{DatabaseTransaction, EntityTrait, IntoActiveModel, TransactionTrait}; use tokio_stream::wrappers::ReceiverStream; @@ -603,9 +602,9 @@ async fn lfs_add_lock( let d = serde_json::to_string(&locks_from_data).unwrap(); // must turn into `ActiveModel` before modify, or update failed. - let mut val = val.into_active_model(); - val.data = Set(d); - let res = storage.update_lock(val).await; + // let mut val = val.into_active_model(); + // val.data = Set(d); + let res = storage.update_lock(val, &d).await; match res.is_ok() { true => Ok(()), false => Err(GitLFSError::GeneralError("".to_string())), @@ -757,9 +756,7 @@ async fn delete_lock( // Update remaining locks. let data = serde_json::to_string(&new_locks).unwrap(); - let mut val = val.into_active_model(); - val.data = Set(data); - let res = storage.update_lock(val).await; + let res = storage.update_lock(val, &data).await; match res.is_ok() { true => Ok(lock_to_delete), false => Err(GitLFSError::GeneralError("".to_string())), diff --git a/ceres/src/pack/import_repo.rs b/ceres/src/pack/import_repo.rs index 38eae2ce0..8d9c09418 100644 --- a/ceres/src/pack/import_repo.rs +++ b/ceres/src/pack/import_repo.rs @@ -59,14 +59,14 @@ impl PackHandler for ImportRepo { let storage = self.context.services.git_db_storage.clone(); let mut entry_list = vec![]; let mut join_tasks = vec![]; + let repo_id = self.repo.repo_id; for entry in receiver { entry_list.push(entry); - if entry_list.len() >= 1000 { + if entry_list.len() >= 10000 { let stg_clone = storage.clone(); - let repo_clone = self.repo.clone(); let handle = tokio::spawn(async move { stg_clone - .save_entry(repo_clone.repo_id, entry_list) + .save_entry(repo_id, entry_list) .await .unwrap(); }); @@ -76,7 +76,7 @@ impl PackHandler for ImportRepo { } join_all(join_tasks).await; storage - .save_entry(self.repo.repo_id, entry_list) + .save_entry(repo_id, entry_list) .await .unwrap(); self.attach_to_monorepo_parent().await.unwrap(); diff --git a/ceres/src/pack/monorepo.rs b/ceres/src/pack/monorepo.rs index db1d41948..df3c9a96a 100644 --- a/ceres/src/pack/monorepo.rs +++ b/ceres/src/pack/monorepo.rs @@ -341,7 +341,7 @@ impl MonoRepo { let comment = self.comment_for_force_update(&mr.to_hash, &self.to_hash); mr.to_hash = self.to_hash.clone(); storage - .add_mr_conversation(&mr.mr_link, 0, ConvType::Comment, Some(comment)) + .add_mr_conversation(&mr.mr_link, 0, ConvType::ForcePush, Some(comment)) .await .unwrap(); } else { @@ -353,7 +353,7 @@ impl MonoRepo { .add_mr_conversation( &mr.mr_link, 0, - ConvType::Comment, + ConvType::Closed, Some("Mega closed MR due to conflict".to_string()), ) .await diff --git a/common/src/model.rs b/common/src/model.rs index 8ed9e57f5..aa7a56c69 100644 --- a/common/src/model.rs +++ b/common/src/model.rs @@ -48,3 +48,31 @@ impl CommonResult { } } } + +#[derive(Deserialize)] +pub struct PageParams { + pub page: u64, + pub per_page: u64, +} + +impl Default for PageParams { + fn default() -> Self { + PageParams { + page: 1, + per_page: 20, + } + } +} + +#[derive(Deserialize)] +pub struct RequestParams { + pub pagination: PageParams, + pub additional: T, +} + +#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] + +pub struct CommonPage { + pub total: u64, + pub items: Vec, +} \ No newline at end of file diff --git a/jupiter/Cargo.toml b/jupiter/Cargo.toml index b40d839c7..4d82aecd8 100644 --- a/jupiter/Cargo.toml +++ b/jupiter/Cargo.toml @@ -31,7 +31,7 @@ futures = { workspace = true } serde_json = { workspace = true } idgenerator = { workspace = true } serde = { workspace = true } -handlebars = "6.0.0" +tokio = { workspace = true, features = ["macros"] } [dev-dependencies] tokio = { workspace = true, features = ["macros"] } diff --git a/jupiter/callisto/src/db_enums.rs b/jupiter/callisto/src/db_enums.rs index 4f4110e1a..db287223c 100644 --- a/jupiter/callisto/src/db_enums.rs +++ b/jupiter/callisto/src/db_enums.rs @@ -76,6 +76,7 @@ pub enum ConvType { Approve, MergeQueue, Merged, + Closed, } impl Display for ConvType { @@ -90,6 +91,7 @@ impl Display for ConvType { ConvType::Approve => "Approve", ConvType::MergeQueue => "MergeQueue", ConvType::Merged => "Merged", + ConvType::Closed => "Closed", }; write!(f, "{}", s) } diff --git a/jupiter/src/storage/git_db_storage.rs b/jupiter/src/storage/git_db_storage.rs index 089ddca89..7c95f0053 100644 --- a/jupiter/src/storage/git_db_storage.rs +++ b/jupiter/src/storage/git_db_storage.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use futures::{stream, Stream, StreamExt}; use sea_orm::sea_query::Expr; @@ -7,6 +7,7 @@ use sea_orm::{ IntoActiveModel, QueryFilter, QueryTrait, Set, }; use sea_orm::{PaginatorTrait, QueryOrder}; +use tokio::sync::Mutex; use callisto::{git_blob, git_commit, git_repo, git_tag, git_tree, import_refs, raw_blob}; use common::errors::MegaError; @@ -44,7 +45,11 @@ impl GitDbStorage { } } - pub async fn save_ref(&self, repo_id: i64, mut refs: import_refs::Model) -> Result<(), MegaError> { + pub async fn save_ref( + &self, + repo_id: i64, + mut refs: import_refs::Model, + ) -> Result<(), MegaError> { refs.repo_id = repo_id; let a_model = refs.into_active_model(); import_refs::Entity::insert(a_model) @@ -129,7 +134,7 @@ impl GitDbStorage { async move { let raw_obj = entry.process_entry(); let model = raw_obj.convert_to_git_model(); - let mut git_objects = git_objects.lock().unwrap(); + let mut git_objects = git_objects.lock().await; match model { GitObjectModel::Commit(mut commit) => { @@ -156,8 +161,7 @@ impl GitDbStorage { let git_objects = Arc::try_unwrap(git_objects) .expect("Failed to unwrap Arc") - .into_inner() - .unwrap(); + .into_inner(); batch_save_model(self.get_connection(), git_objects.commits) .await .unwrap(); diff --git a/jupiter/src/storage/lfs_db_storage.rs b/jupiter/src/storage/lfs_db_storage.rs index b55d2b65b..b03a922bd 100644 --- a/jupiter/src/storage/lfs_db_storage.rs +++ b/jupiter/src/storage/lfs_db_storage.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use sea_orm::{ - ColumnTrait, DatabaseConnection, EntityTrait, InsertResult, IntoActiveModel, QueryFilter, QueryOrder, + ColumnTrait, DatabaseConnection, EntityTrait, InsertResult, IntoActiveModel, QueryFilter, + QueryOrder, Set, }; use callisto::{lfs_locks, lfs_objects, lfs_split_relations}; @@ -120,9 +121,12 @@ impl LfsDbStorage { pub async fn update_lock( &self, - lfs_lock: lfs_locks::ActiveModel, + lfs_lock: lfs_locks::Model, + data: &str, ) -> Result { - Ok(lfs_locks::Entity::update(lfs_lock) + let mut val = lfs_lock.into_active_model(); + val.data = Set(data.to_owned()); + Ok(lfs_locks::Entity::update(val) .exec(self.get_connection()) .await .unwrap()) diff --git a/jupiter/src/storage/mono_storage.rs b/jupiter/src/storage/mono_storage.rs index 0d092c65f..9d11a45ef 100644 --- a/jupiter/src/storage/mono_storage.rs +++ b/jupiter/src/storage/mono_storage.rs @@ -3,8 +3,7 @@ use std::sync::{Arc, Mutex}; use futures::{stream, StreamExt}; use sea_orm::ActiveValue::NotSet; use sea_orm::{ - ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter, - QueryOrder, QuerySelect, + ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect }; use callisto::db_enums::{ConvType, MergeStatus}; @@ -119,14 +118,15 @@ impl MonoStorage { pub async fn get_mr_by_status( &self, status: Vec, - ) -> Result, MegaError> { - let model = mega_mr::Entity::find() + page: u64, + per_page: u64, + ) -> Result<(Vec, u64), MegaError> { + let paginator = mega_mr::Entity::find() .filter(mega_mr::Column::Status.is_in(status)) .order_by_desc(mega_mr::Column::CreatedAt) - .all(self.get_connection()) - .await - .unwrap(); - Ok(model) + .paginate(self.get_connection(),per_page); + let num_pages = paginator.num_items().await?; + Ok(paginator.fetch_page(page -1).await.map(|m| (m, num_pages))?) } pub async fn get_mr(&self, mr_link: &str) -> Result, MegaError> { diff --git a/mega/Cargo.toml b/mega/Cargo.toml index ec6c52296..86733545f 100644 --- a/mega/Cargo.toml +++ b/mega/Cargo.toml @@ -36,13 +36,6 @@ shadow-rs = { workspace = true } ctrlc = { workspace = true } [dev-dependencies] -reqwest = { workspace = true, features = ["stream", "json"] } -russh = { workspace = true } -russh-keys = { workspace = true } -async-trait = { workspace = true } -bytes = { workspace = true } -go-defer = { workspace = true } -git2 = { workspace = true } tempfile = { workspace = true } serial_test = "3.1.1" lazy_static = {workspace = true} diff --git a/mono/Cargo.toml b/mono/Cargo.toml index 22e711b70..4f5dfa12b 100644 --- a/mono/Cargo.toml +++ b/mono/Cargo.toml @@ -56,20 +56,9 @@ shadow-rs = { workspace = true } oauth2 = "4.4.2" async-session = "3.0.0" http = "1.1.0" -sea-orm = { workspace = true, features = [] } cedar-policy = { workspace = true } [dev-dependencies] -reqwest = { workspace = true, features = ["stream", "json"] } -russh = { workspace = true } -russh-keys = { workspace = true } -async-trait = { workspace = true } -bytes = { workspace = true } -go-defer = { workspace = true } -git2 = { workspace = true } -tempfile = { workspace = true } -rand = { workspace = true } - [build-dependencies] shadow-rs = { workspace = true } diff --git a/mono/src/api/mod.rs b/mono/src/api/mod.rs index c87100c72..fd6d37f99 100644 --- a/mono/src/api/mod.rs +++ b/mono/src/api/mod.rs @@ -16,6 +16,7 @@ use jupiter::{context::Context, storage::user_storage::UserStorage}; pub mod api_router; pub mod error; pub mod lfs; +pub mod model; pub mod mr_router; pub mod oauth; pub mod user; diff --git a/mono/src/api/model.rs b/mono/src/api/model.rs new file mode 100644 index 000000000..8ebb341c8 --- /dev/null +++ b/mono/src/api/model.rs @@ -0,0 +1,7 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +pub struct MRStatusParams { + pub status: String, +} + diff --git a/mono/src/api/mr_router.rs b/mono/src/api/mr_router.rs index 1a10ad3db..1fe21b5e4 100644 --- a/mono/src/api/mr_router.rs +++ b/mono/src/api/mr_router.rs @@ -1,7 +1,7 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::path::PathBuf; use axum::{ - extract::{Path, Query, State}, + extract::{Path, State}, routing::{get, post}, Json, Router, }; @@ -9,18 +9,19 @@ use axum::{ use bytes::Bytes; use ceres::model::mr::{MRDetail, MrInfoItem}; -use common::model::CommonResult; +use common::model::{CommonPage, CommonResult, RequestParams}; use saturn::ActionEnum; use taurus::event::api_request::{ApiRequestEvent, ApiType}; use crate::api::error::ApiError; +use crate::api::model::MRStatusParams; use crate::api::oauth::model::LoginUser; use crate::api::util; use crate::api::MonoApiServiceState; pub fn routers() -> Router { Router::new() - .route("/mr/list", get(get_mr_list)) + .route("/mr/list", post(fetch_mr_list)) .route("/mr/:mr_link/detail", get(mr_detail)) .route("/mr/:mr_link/merge", post(merge)) .route("/mr/:mr_link/files", get(get_mr_files)) @@ -33,11 +34,10 @@ async fn merge( Path(mr_link): Path, state: State, ) -> Result>, ApiError> { - ApiRequestEvent::notify(ApiType::MergeRequest, &state.0.context.config); let storage = state.context.services.mono_storage.clone(); if let Some(model) = storage.get_open_mr_by_link(&mr_link).await.unwrap() { let path = model.path.clone(); - assert!(util::check_permissions( + if util::check_permissions( &user.name, // "admin", &path, @@ -45,27 +45,32 @@ async fn merge( state.clone(), ) .await - .is_ok()); - let res = state.monorepo().merge_mr(&mut model.into()).await; - let res = match res { - Ok(_) => CommonResult::success(None), - Err(err) => CommonResult::failed(&err.to_string()), - }; - ApiRequestEvent::notify(ApiType::MergeDone, &state.0.context.config); - return Ok(Json(res)); + .is_ok() + { + ApiRequestEvent::notify(ApiType::MergeRequest, &state.0.context.config); + let res = state.monorepo().merge_mr(&mut model.into()).await; + let res = match res { + Ok(_) => CommonResult::success(None), + Err(err) => CommonResult::failed(&err.to_string()), + }; + ApiRequestEvent::notify(ApiType::MergeDone, &state.0.context.config); + return Ok(Json(res)); + } } Ok(Json(CommonResult::failed("not found"))) } -async fn get_mr_list( - Query(query): Query>, +async fn fetch_mr_list( state: State, -) -> Result>>, ApiError> { + Json(json): Json>, +) -> Result>>, ApiError> { ApiRequestEvent::notify(ApiType::MergeList, &state.0.context.config); - let status = query.get("status").unwrap(); - let res = state.monorepo().mr_list(status).await; + let res = state + .monorepo() + .mr_list(&json.additional.status, json.pagination) + .await; let res = match res { - Ok(data) => CommonResult::success(Some(data)), + Ok((items, total)) => CommonResult::success(Some(CommonPage { items, total })), Err(err) => CommonResult::failed(&err.to_string()), }; Ok(Json(res)) diff --git a/mono/src/api/oauth/model.rs b/mono/src/api/oauth/model.rs index b2011d3d5..503dccdfe 100644 --- a/mono/src/api/oauth/model.rs +++ b/mono/src/api/oauth/model.rs @@ -1,4 +1,4 @@ -use sea_orm::entity::prelude::*; +use chrono::NaiveDateTime; use common::utils::generate_id; use serde::{Deserialize, Serialize}; @@ -47,7 +47,7 @@ pub struct LoginUser { pub name: String, pub avatar_url: String, pub email: String, - pub created_at: DateTime, + pub created_at: NaiveDateTime, } impl From for LoginUser { diff --git a/mono/src/api/user/model.rs b/mono/src/api/user/model.rs index 4de86bb20..d44f29b4d 100644 --- a/mono/src/api/user/model.rs +++ b/mono/src/api/user/model.rs @@ -1,5 +1,5 @@ use callisto::ssh_keys; -use sea_orm::entity::prelude::*; +use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize)] @@ -14,7 +14,7 @@ pub struct ListSSHKey { pub title: String, pub ssh_key: String, pub finger: String, - pub created_at: DateTime, + pub created_at: NaiveDateTime, } impl From for ListSSHKey { diff --git a/moon/src/app/(dashboard)/mr/[id]/page.tsx b/moon/src/app/(dashboard)/mr/[id]/page.tsx index 253619199..6f992526e 100644 --- a/moon/src/app/(dashboard)/mr/[id]/page.tsx +++ b/moon/src/app/(dashboard)/mr/[id]/page.tsx @@ -1,7 +1,7 @@ 'use client' import { useEffect, useState } from "react"; import { Card, Button, List, Tabs, TabsProps, Space, Timeline, Flex } from 'antd/lib'; -import { CommentOutlined, MergeOutlined } from '@ant-design/icons'; +import { CommentOutlined, MergeOutlined, CloseCircleOutlined } from '@ant-design/icons'; import { formatDistance, fromUnixTime } from 'date-fns'; import RichEditor from "@/components/rich-editor/RichEditor"; import MRComment from "@/components/MRComment"; @@ -106,7 +106,7 @@ export default function MRDetailPage({ params }: { params: { id: string } }) { switch (conv.conv_type) { case "Comment": icon = ; children = ; break case "Merged": icon = ; children = "Merged via the queue into main " + formatDistance(fromUnixTime(conv.created_at), new Date(), { addSuffix: true }); break; - // default: icon = ; children = conv.comment; + case "Closed": icon = ; children = conv.comment; }; const element = { diff --git a/moon/src/app/(dashboard)/mr/page.tsx b/moon/src/app/(dashboard)/mr/page.tsx index 4e22bcb0a..c66085ad5 100644 --- a/moon/src/app/(dashboard)/mr/page.tsx +++ b/moon/src/app/(dashboard)/mr/page.tsx @@ -1,25 +1,103 @@ 'use client' -import MergeList from "@/components/MergeList"; import { useEffect, useState } from 'react'; +import React from 'react'; +import { List, PaginationProps, Tag } from 'antd/lib'; +import { format, formatDistance, fromUnixTime } from 'date-fns' +import { MergeOutlined } from '@ant-design/icons'; +import Link from 'next/link'; + + +interface MrInfoItem { + mr_link: string, + title: string, + status: string, + open_timestamp: number, + merge_timestamp: number | null, + updated_at: number, +} export default function MergeRequestPage() { - const [mrList, setMrList] = useState([]); + const [mrList, setMrList] = useState([]); + const [numTotal, setNumTotal] = useState(0); + const [pageSize, setPageSize] = useState(10); + + const fetchData = async (page: number, per_page: number) => { + try { + const res = await fetch(`/api/mr/list`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + pagination: { + page: page, + per_page: per_page + }, + additional: { + status: "" + } + }), + }); + const response = await res.json(); + const data = response.data.data; + setMrList(data.items); + setNumTotal(data.total) + } catch (error) { + console.error('Error fetching data:', error); + } + }; + useEffect(() => { - const fetchData = async () => { - try { - const res = await fetch(`/api/mr/list?status=`); - const response = await res.json(); - const mrList = response.data.data; - setMrList(mrList); - } catch (error) { - console.error('Error fetching data:', error); - } - }; - fetchData(); - }, []); + + fetchData(1, pageSize); + }, [pageSize]); + + const getStatusTag = (status: string) => { + switch (status) { + case 'open': + return open; + case 'merged': + return merged; + case 'closed': + return closed; + } + }; + + const getDescription = (item: MrInfoItem) => { + switch (item.status) { + case 'open': + return `MergeRequest opened on ${format(fromUnixTime(Number(item.open_timestamp)), 'MMM d')} by Admin`; + case 'merged': + if (item.merge_timestamp !== null) { + return `MergeRequest by Admin was merged ${formatDistance(fromUnixTime(item.merge_timestamp), new Date(), { addSuffix: true })}`; + } else { + return ""; + } + case 'closed': + return (`MR ${item.mr_link} by Admin was closed ${formatDistance(fromUnixTime(item.updated_at), new Date(), { addSuffix: true })}`) + } + } + + const onChange: PaginationProps['onChange'] = (current, pageSize) => { + fetchData(current, pageSize); + }; + return ( -
- -
+ ( + + + } + title={{`MR ${item.mr_link} open by Mega automacticlly${item.title}`}{getStatusTag(item.status)}} + description={getDescription(item)} + /> + + )} + /> ) } \ No newline at end of file diff --git a/moon/src/app/api/mr/list/route.ts b/moon/src/app/api/mr/list/route.ts index 95352c34c..f0a3270f7 100644 --- a/moon/src/app/api/mr/list/route.ts +++ b/moon/src/app/api/mr/list/route.ts @@ -3,11 +3,15 @@ export const revalidate = 0 import { type NextRequest } from 'next/server' -export async function GET(request: NextRequest) { +export async function POST(request: NextRequest) { const endpoint = process.env.MEGA_INTERNAL_HOST; - const searchParams = request.nextUrl.searchParams - const status = searchParams.get('status') - const res = await fetch(`${endpoint}/api/v1/mr/list?status=${status}`, { + const body = await request.json(); + const res = await fetch(`${endpoint}/api/v1/mr/list`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), }) const data = await res.json() diff --git a/moon/src/components/MergeList.tsx b/moon/src/components/MergeList.tsx deleted file mode 100644 index 863bc816e..000000000 --- a/moon/src/components/MergeList.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import { Avatar, List, Tag } from 'antd/lib'; -import { format, formatDistance, fromUnixTime } from 'date-fns' -import { MergeOutlined } from '@ant-design/icons'; -import Link from 'next/link'; - -interface MrInfoItem { - mr_link: string, - title: string, - status: string, - open_timestamp: number, - merge_timestamp: number | null, - updated_at: number, -} - -interface MergeListProps { - mrList: MrInfoItem[]; -} - -const MergeList: React.FC = ({ mrList }) => { - - const getStatusTag = (status: string) => { - switch (status) { - case 'open': - return open; - case 'merged': - return merged; - case 'closed': - return closed; - } - }; - - const getDescription = (item: MrInfoItem) => { - switch (item.status) { - case 'open': - return `MergeRequest opened on ${format(fromUnixTime(Number(item.open_timestamp)), 'MMM d')} by Admin`; - case 'merged': - if (item.merge_timestamp !== null) { - return `MergeRequest by Admin was merged ${formatDistance(fromUnixTime(item.merge_timestamp), new Date(), { addSuffix: true })}`; - } else { - return ""; - } - case 'closed': - return (`MR ${item.mr_link} by Admin was closed ${formatDistance(fromUnixTime(item.updated_at), new Date(), { addSuffix: true })}` ) - } - } - - return ( - ( - - - } - title={{`MR ${item.mr_link} open by Mega automacticlly${item.title}`}{getStatusTag(item.status)}} - description={getDescription(item)} - /> - - )} - /> - ); -}; - -export default MergeList; \ No newline at end of file