From 20c0e05a552b2a21d0ecfb658204f5e327420a71 Mon Sep 17 00:00:00 2001 From: "benjamin.747" Date: Tue, 23 Jul 2024 20:31:12 +0800 Subject: [PATCH] update tauri client lunar for testing --- ceres/src/model/mod.rs | 29 +--- common/src/enums.rs | 17 ++- common/src/model.rs | 26 +++- gateway/src/api/api_router.rs | 11 +- gateway/src/api/mr_router.rs | 7 +- gemini/src/http/handler.rs | 12 +- gemini/src/ztm/agent.rs | 5 +- jupiter/src/storage/git_db_storage.rs | 10 -- lunar/.env.local | 2 + lunar/package.json | 1 + lunar/src-tauri/src/main.rs | 2 +- lunar/src/app/api/relay/repo_fork/route.ts | 16 ++ lunar/src/app/api/relay/repo_list/route.ts | 10 ++ lunar/src/app/page.tsx | 111 +++----------- lunar/src/components/DataList.tsx | 161 +++++++++++++++++++++ moon/src/app/blob/[...path]/page.tsx | 2 +- moon/src/app/page.tsx | 4 +- moon/src/app/tree/[...path]/page.tsx | 4 +- 18 files changed, 277 insertions(+), 153 deletions(-) create mode 100644 lunar/.env.local create mode 100644 lunar/src/app/api/relay/repo_fork/route.ts create mode 100644 lunar/src/app/api/relay/repo_list/route.ts create mode 100644 lunar/src/components/DataList.tsx diff --git a/ceres/src/model/mod.rs b/ceres/src/model/mod.rs index 5fdd343ae..c07ca9398 100644 --- a/ceres/src/model/mod.rs +++ b/ceres/src/model/mod.rs @@ -1,32 +1,5 @@ -use serde::{Deserialize, Serialize}; - pub mod create_file; pub mod mr; +pub mod publish_path; pub mod query; pub mod tree; -pub mod publish_path; - -#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] - -pub struct CommonResult { - pub req_result: bool, - pub data: Option, - pub err_message: String, -} - -impl CommonResult { - pub fn success(data: Option) -> Self { - CommonResult { - req_result: true, - data, - err_message: "".to_owned(), - } - } - pub fn failed(err_message: &str) -> Self { - CommonResult { - req_result: false, - data: None, - err_message: err_message.to_string(), - } - } -} diff --git a/common/src/enums.rs b/common/src/enums.rs index 775275236..12f21a126 100644 --- a/common/src/enums.rs +++ b/common/src/enums.rs @@ -1,11 +1,16 @@ -use clap::ValueEnum; +// src/enums.rs -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)] -pub enum DataSource { - Mysql, - Postgres, -} +//! This file is used to share enums across different modules. +//! +//! By defining enums in a separate file, we can easily import and use them +//! in multiple modules within the project. This promotes code reuse and +//! consistency, especially when multiple modules need to work with the same +//! set of enum variants. + + +use clap::ValueEnum; +/// An enum representing different ZTM types. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)] pub enum ZtmType { Agent, diff --git a/common/src/model.rs b/common/src/model.rs index 0c7354ded..c5aba44be 100644 --- a/common/src/model.rs +++ b/common/src/model.rs @@ -1,5 +1,5 @@ use clap::Args; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use crate::enums::ZtmType; @@ -38,3 +38,27 @@ pub struct GetParams { pub identifier: Option, pub port: Option, } + +#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] +pub struct CommonResult { + pub req_result: bool, + pub data: Option, + pub err_message: String, +} + +impl CommonResult { + pub fn success(data: Option) -> Self { + CommonResult { + req_result: true, + data, + err_message: "".to_owned(), + } + } + pub fn failed(err_message: &str) -> Self { + CommonResult { + req_result: false, + data: None, + err_message: err_message.to_string(), + } + } +} diff --git a/gateway/src/api/api_router.rs b/gateway/src/api/api_router.rs index 47d473af6..cb16c26eb 100644 --- a/gateway/src/api/api_router.rs +++ b/gateway/src/api/api_router.rs @@ -6,11 +6,16 @@ use axum::{ Json, Router, }; -use crate::api::mr_router; -use crate::api::ApiServiceState; use ceres::model::{ - create_file::CreateFileInfo, publish_path::PublishPathInfo, query::{BlobContentQuery, CodePreviewQuery}, tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem}, CommonResult + create_file::CreateFileInfo, + publish_path::PublishPathInfo, + query::{BlobContentQuery, CodePreviewQuery}, + tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem}, }; +use common::model::CommonResult; + +use crate::api::mr_router; +use crate::api::ApiServiceState; pub fn routers() -> Router { let router = Router::new() diff --git a/gateway/src/api/mr_router.rs b/gateway/src/api/mr_router.rs index 8098d6499..35d8c9f26 100644 --- a/gateway/src/api/mr_router.rs +++ b/gateway/src/api/mr_router.rs @@ -7,11 +7,10 @@ use axum::{ Json, Router, }; +use ceres::model::mr::{MRDetail, MrInfoItem}; +use common::model::CommonResult; + use crate::api::ApiServiceState; -use ceres::model::{ - mr::{MRDetail, MrInfoItem}, - CommonResult, -}; pub fn routers() -> Router { Router::new() diff --git a/gemini/src/http/handler.rs b/gemini/src/http/handler.rs index fea6e738d..35e033410 100644 --- a/gemini/src/http/handler.rs +++ b/gemini/src/http/handler.rs @@ -1,5 +1,5 @@ use axum::{body::Body, http::Response}; -use common::model::GetParams; +use common::model::{CommonResult, GetParams}; use jupiter::context::Context; use reqwest::StatusCode; use venus::import_repo::repo::Repo; @@ -34,7 +34,7 @@ pub async fn repo_provide( let git_model = context .services .git_db_storage - .find_git_repo_by_path(path.as_str()) + .find_git_repo_exact_match(path.as_str()) .await; let git_model = match git_model { @@ -163,8 +163,12 @@ pub async fn repo_folk( return Err((StatusCode::INTERNAL_SERVER_ERROR, s)); } } - let msg = format!("Success, you can try to clone the repo like this:\ngit clone http://localhost:{port}/{git_path}"); - Ok(Response::builder().body(Body::from(msg)).unwrap()) + let msg = format!("git clone http://localhost:{port}/{git_path}"); + let json_string = serde_json::to_string(&CommonResult::success(Some(msg))).unwrap(); + Ok(Response::builder() + .header("Content-Type", "application/json") + .body(Body::from(json_string)) + .unwrap()) } pub fn get_peer_id_from_identifier(identifier: String) -> Result { diff --git a/gemini/src/ztm/agent.rs b/gemini/src/ztm/agent.rs index 46f0c8620..73458a351 100644 --- a/gemini/src/ztm/agent.rs +++ b/gemini/src/ztm/agent.rs @@ -7,7 +7,6 @@ use std::{ use axum::async_trait; use common::config::Config; -use jupiter::context::Context; use reqwest::{header::CONTENT_TYPE, Client}; use serde::{Deserialize, Serialize}; @@ -370,12 +369,12 @@ impl ZTMAgent for LocalZTMAgent { } pub async fn run_ztm_client( bootstrap_node: String, - config: Config, + _config: Config, peer_id: String, agent: LocalZTMAgent, ) { let name = peer_id.clone(); - let _context = Context::new(config.clone()).await; + // let _context = Context::new(config.clone()).await; // let local_permit_option = read_secret(peer_id.as_str()).unwrap(); // let permit: ZTMUserPermit = match local_permit_option { diff --git a/jupiter/src/storage/git_db_storage.rs b/jupiter/src/storage/git_db_storage.rs index b9498c80f..08e9e639b 100644 --- a/jupiter/src/storage/git_db_storage.rs +++ b/jupiter/src/storage/git_db_storage.rs @@ -219,16 +219,6 @@ impl GitDbStorage { Ok(result) } - pub async fn find_git_repo_by_path( - &self, - repo_path: &str, - ) -> Result, MegaError> { - let query = git_repo::Entity::find().filter(git_repo::Column::RepoPath.eq(repo_path)); - tracing::debug!("{}", query.build(DbBackend::Postgres).to_string()); - let result = query.one(self.get_connection()).await?; - Ok(result) - } - pub async fn save_git_repo(&self, repo: Repo) -> Result<(), MegaError> { let model: git_repo::Model = repo.into(); let a_model = model.into_active_model(); diff --git a/lunar/.env.local b/lunar/.env.local new file mode 100644 index 000000000..44ffeabea --- /dev/null +++ b/lunar/.env.local @@ -0,0 +1,2 @@ +RELAY_API_URL=http://34.84.172.121 +MEGA_API_URL=http://localhost:8000 \ No newline at end of file diff --git a/lunar/package.json b/lunar/package.json index f8d9f185c..8e119f7cc 100644 --- a/lunar/package.json +++ b/lunar/package.json @@ -17,6 +17,7 @@ "@tailwindcss/forms": "^0.5.7", "@tauri-apps/api": "^1.6.0", "clsx": "^2.1.1", + "date-fns": "^3.6.0", "framer-motion": "^11.3.2", "next": "14.2.3", "react": "^18", diff --git a/lunar/src-tauri/src/main.rs b/lunar/src-tauri/src/main.rs index 71cbda462..90a777aee 100644 --- a/lunar/src-tauri/src/main.rs +++ b/lunar/src-tauri/src/main.rs @@ -7,7 +7,7 @@ fn hello_string(name: &str) -> String { } fn start_mega() { - let args_str = "service http".to_string(); + let args_str = "service http --ztm agent --bootstrap-node http://34.84.172.121/relay".to_string(); let args = args_str.split(' ').collect(); mega::cli::parse(Some(args)).expect("failed to start mega"); } diff --git a/lunar/src/app/api/relay/repo_fork/route.ts b/lunar/src/app/api/relay/repo_fork/route.ts new file mode 100644 index 000000000..83600a90e --- /dev/null +++ b/lunar/src/app/api/relay/repo_fork/route.ts @@ -0,0 +1,16 @@ +export const revalidate = 0 + +import { NextRequest } from "next/server"; + +const endpoint = process.env.MEGA_API_URL; + +export async function GET(request: NextRequest) { + const searchParams = request.nextUrl.searchParams + const identifier = searchParams.get('identifier') + const port = searchParams.get('port') + const res = await fetch(`${endpoint}/api/v1/ztm/repo_folk?identifier=${identifier}&port=${port}`, { + }) + const data = await res.json() + + return Response.json({ data }) +} \ No newline at end of file diff --git a/lunar/src/app/api/relay/repo_list/route.ts b/lunar/src/app/api/relay/repo_list/route.ts new file mode 100644 index 000000000..f6e8032ff --- /dev/null +++ b/lunar/src/app/api/relay/repo_list/route.ts @@ -0,0 +1,10 @@ +export const revalidate = 0 + +const endpoint = process.env.RELAY_API_URL; + +export async function GET(request: Request, ) { + const res = await fetch(`${endpoint}/relay/repo_list`, { + }) + const data = await res.json() + return Response.json({ data }) +} \ No newline at end of file diff --git a/lunar/src/app/page.tsx b/lunar/src/app/page.tsx index 63aae9a2f..273db7085 100644 --- a/lunar/src/app/page.tsx +++ b/lunar/src/app/page.tsx @@ -1,99 +1,34 @@ 'use client' -import React from 'react' -import { Space, Table, Tag } from 'antd' -import type { TableProps } from 'antd' -import HelloRust from '@/components/catalyst/hello' -import { GetResult } from '../../../moon/src/components/ApiResult' +import React, { useEffect, useState } from 'react' +import DataList from '@/components/DataList' -interface DataType { - key: string - name: string - age: number - address: string - tags: string[] -} -const columns: TableProps['columns'] = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - render: (text) => {text}, - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - { - title: 'Tags', - key: 'tags', - dataIndex: 'tags', - render: (_, { tags }) => ( - <> - {tags.map((tag) => { - let color = tag.length > 5 ? 'geekblue' : 'green' - if (tag === 'loser') { - color = 'volcano' - } - return ( - - {tag.toUpperCase()} - - ) - })} - - ), - }, - { - title: 'Action', - key: 'action', - render: (_, record) => ( - - Invite {record.name} - Delete - - ), - }, -] +export default function HomePage() { + const [repo_list, setRepoList] = useState([]); -const data: DataType[] = [ - { - key: '1', - name: 'John Brown', - age: 32, - address: 'New York No. 1 Lake Park', - tags: ['nice', 'developer'], - }, - { - key: '2', - name: 'Jim Green', - age: 42, - address: 'London No. 1 Lake Park', - tags: ['loser'], - }, - { - key: '3', - name: 'Joe Black', - age: 32, - address: 'Sydney No. 1 Lake Park', - tags: ['cool', 'teacher'], - }, -] + useEffect(() => { + const fetchData = async () => { + try { + let repo_list = await getRepoList(); + setRepoList(repo_list); + } catch (error) { + console.error('Error fetching data:', error); + } + }; + fetchData(); + }, []); -export default function HomePage() { return (
- - - {/* ---- */} - + ) } + +async function getRepoList() { + const res = await fetch(`api/relay/repo_list`); + const response = await res.json(); + const repo_list = response.data; + return repo_list +} \ No newline at end of file diff --git a/lunar/src/components/DataList.tsx b/lunar/src/components/DataList.tsx new file mode 100644 index 000000000..2ff03d50d --- /dev/null +++ b/lunar/src/components/DataList.tsx @@ -0,0 +1,161 @@ +'use client' + +import { Input, Modal, Space, Table, TableProps, Badge, Button } from 'antd/lib' +import { useEffect, useState } from 'react' +import { format, fromUnixTime } from 'date-fns' +import { DownloadOutlined } from '@ant-design/icons'; + + +interface DataType { + name: string; + identifier: string; + origin: string; + update_time: number; + commit: string; + peer_online: boolean +} + +const DataList = ({ data }) => { + const [open, setOpen] = useState(false); + const [confirmLoading, setConfirmLoading] = useState(false); + const [inputPort, setInputPort] = useState(""); + const [isOkButtonDisabled, setIsOkButtonDisabled] = useState(true); + const [modelRecord, setModalRecord] = useState({ + name: "", + identifier: "", + origin: "", + update_time: 0, + commit: "", + peer_online: true, + }); + const [modal, contextHolder] = Modal.useModal(); + + const handleInputChange = (e: React.ChangeEvent) => { + // console.log("value changes", e.target.value); + setInputPort(e.target.value); + setIsOkButtonDisabled(e.target.value.length < 4); + }; + + const showSuccModel = (text) => { + modal.success({ + title: 'Fork from remote success! Clone by command:', + content: `${text}`, + }); + }; + + var columns: TableProps['columns'] = [ + { + title: 'Name', + dataIndex: ['name', 'identifier'], + key: 'name', + render: (_, record) => { + return <> + + {record.name} + + + } + }, + { + title: 'Identifier', + dataIndex: 'identifier', + key: 'identifier', + ellipsis: true, + render: (text) => {text}, + }, + { + title: 'Online', + dataIndex: 'peer_online', + key: 'peer_online', + render: (_, { peer_online }) => ( + + ), + }, + { + title: 'Origin', + dataIndex: 'origin', + key: 'origin', + }, + { + title: 'Update Date', + dataIndex: 'update_time', + key: 'update_time', + render: (update_time) => ( + + + {update_time && format(fromUnixTime(update_time), 'yyyy-MM-dd HH:mm:ss')} + + + ) + }, + { + title: 'Action', + key: 'action', + render: (_, record) => ( + + + + ), + }, + ]; + + + const showModal = (record) => { + setModalRecord(record); + setOpen(true); + }; + + const handleOk = () => { + setConfirmLoading(true); + + const repoFork = async () => { + try { + let text = await getRepoFork(modelRecord.identifier, inputPort); + setOpen(false); + setConfirmLoading(false); + showSuccModel(text); + } catch (error) { + console.error('Error fetching data:', error); + } + }; + repoFork(); + + setTimeout(() => { + setOpen(false); + setConfirmLoading(false); + }, 5000); + }; + + const handleCancel = () => { + setOpen(false); + }; + + return ( +
+
+ + + + {contextHolder} + + ); +}; + + +async function getRepoFork(identifier, port) { + const res = await fetch(`api/relay/repo_fork?identifier=${identifier}&port=${port}`); + const response = await res.json(); + return response.data.data +} + +export default DataList; diff --git a/moon/src/app/blob/[...path]/page.tsx b/moon/src/app/blob/[...path]/page.tsx index 866cd41b5..590833ae3 100644 --- a/moon/src/app/blob/[...path]/page.tsx +++ b/moon/src/app/blob/[...path]/page.tsx @@ -26,7 +26,7 @@ export default function BlobPage({ params }: { params: { path: string[] } }) { ) } -export async function getReadmeContent(pathname: string) { +async function getReadmeContent(pathname: string) { const res = await fetch(`http://localhost:3000/api/blob?path=${pathname}`); const response = await res.json(); const directory = response.data.data; diff --git a/moon/src/app/page.tsx b/moon/src/app/page.tsx index 8ed17d338..a50224ae2 100644 --- a/moon/src/app/page.tsx +++ b/moon/src/app/page.tsx @@ -11,14 +11,14 @@ export default async function HomePage() { ); } -export async function getDirectory() { +async function getDirectory() { const res = await fetch(`http://localhost:3000/api/tree/commit-info?path=/`); const response = await res.json(); const directory = response.data.data; return directory } -export async function getReadmeContent(directory) { +async function getReadmeContent(directory) { var readmeContent = ''; for (const project of directory || []) { if (project.name === 'README.md' && project.content_type === 'file') { diff --git a/moon/src/app/tree/[...path]/page.tsx b/moon/src/app/tree/[...path]/page.tsx index 52cd9e854..b1293f74c 100644 --- a/moon/src/app/tree/[...path]/page.tsx +++ b/moon/src/app/tree/[...path]/page.tsx @@ -32,14 +32,14 @@ export default function Page({ params }: { params: { path: string[] } }) { ); } -export async function getDirectory(pathname: string) { +async function getDirectory(pathname: string) { const res = await fetch(`http://localhost:3000/api/tree/commit-info?path=${pathname}`); const response = await res.json(); const directory = response.data.data; return directory } -export async function getReadmeContent(pathname, directory) { +async function getReadmeContent(pathname, directory) { var readmeContent = ''; for (const project of directory || []) { if (project.name === 'README.md' && project.content_type === 'file') {