diff --git a/apps/frontend/README.md b/apps/frontend/README.md index c3b823d66..ecb4c9431 100644 --- a/apps/frontend/README.md +++ b/apps/frontend/README.md @@ -8,7 +8,7 @@ search labelu in [Test Pypi](https://test.pypi.org/), to find the right version ```bash # change version '0.1.220' to the version you need. -pip install -i https://test.pypi.org/simple/ labelu==0.1.220 +pip install -i https://test.pypi.org/simple/ labelu==1.0.6a5 labelu --help labelu --port 8000 ``` @@ -24,4 +24,4 @@ vim vite.config.js npm run start open http://localhost:3000/ -``` \ No newline at end of file +``` diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 15027bc86..aa0f437e7 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -1,17 +1,17 @@ { "name": "@labelu/frontend", - "version": "5.2.1", + "version": "5.3.0", "private": true, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelu/audio-annotator-react": "1.5.2", - "@labelu/components-react": "1.4.2", + "@labelu/audio-annotator-react": "1.5.3-alpha.1", + "@labelu/components-react": "1.4.3-alpha.1", "@labelu/image": "1.1.0", "@labelu/formatter": "1.0.2", - "@labelu/image-annotator-react": "2.1.1", + "@labelu/image-annotator-react": "2.1.2-alpha.1", "@labelu/interface": "1.3.1", - "@labelu/video-annotator-react": "1.3.4", - "@labelu/video-react": "1.3.3", + "@labelu/video-annotator-react": "1.3.5-alpha.1", + "@labelu/video-react": "1.3.4-alpha.1", "@tanstack/react-query": "^5.0.0", "antd": "5.10.1", "axios": "^1.3.4", diff --git a/apps/frontend/src/assets/svg/labelllm.svg b/apps/frontend/src/assets/svg/labelllm.svg new file mode 100644 index 000000000..2f1622e35 --- /dev/null +++ b/apps/frontend/src/assets/svg/labelllm.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/frontend/src/assets/svg/mineru.svg b/apps/frontend/src/assets/svg/mineru.svg new file mode 100644 index 000000000..053679aba --- /dev/null +++ b/apps/frontend/src/assets/svg/mineru.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/frontend/src/assets/svg/opendatalab.svg b/apps/frontend/src/assets/svg/opendatalab.svg new file mode 100644 index 000000000..6843772ee --- /dev/null +++ b/apps/frontend/src/assets/svg/opendatalab.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/apps/frontend/src/assets/svg/toolbox.svg b/apps/frontend/src/assets/svg/toolbox.svg new file mode 100644 index 000000000..0abc905eb --- /dev/null +++ b/apps/frontend/src/assets/svg/toolbox.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/frontend/src/components/AppPanel/index.module.css b/apps/frontend/src/components/AppPanel/index.module.css new file mode 100644 index 000000000..2fafcec27 --- /dev/null +++ b/apps/frontend/src/components/AppPanel/index.module.css @@ -0,0 +1,111 @@ +.panel { + display: flex; + flex-wrap: wrap; + width: 40rem; + min-height: 10rem; +} + +.title { + font-size: 20px; + font-weight: 600; + margin: 0.5rem 0 0.5rem 1rem; +} + +.appWrapper { + flex-basis: 50%; + border-radius: 0.25rem; + transition: all 0.2s ease-in-out; + overflow: hidden; + + &:hover { + background-color: rgba(244, 245, 249, 1); + + .links { + opacity: 1; + } + + .appContainer { + animation: wrapperSlideIn 0.2s ease-in-out forwards; + } + } + + &:not(:hover) { + .links { + opacity: 0; + } + + .appContainer { + animation: wrapperSlideOut 0.2s ease-in-out forwards; + } + } +} + +.appContainer { + display: flex; + padding: 0 1rem 1rem; + flex-direction: column; + align-items: start; + justify-content: center; +} + +.avatar { + flex-shrink: 0; +} + +.header { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.description { + color: var(--color-text-tertiary); + font-size: 0.75rem; +} + +.links { + display: flex; + gap: 1rem; + padding: 0.5rem 0; + align-items: center; + opacity: 0; + transition: all 0.2s ease-in-out; +} + +.link { + display: flex; + justify-items: center; + gap: 0.25rem; + color: var(--color-text); + + &:hover { + color: var(--color-primary); + + .arrow { + transform: translateX(0.25rem); + } + } +} + +.arrow { + transition: transform 0.2s ease-in-out; +} + +@keyframes wrapperSlideIn { + from { + transform: translateY(28px); + } + to { + transform: translateY(12px); + } +} + +@keyframes wrapperSlideOut { + from { + transform: translateY(12px); + } + to { + transform: translateY(28px); + } +} diff --git a/apps/frontend/src/components/AppPanel/index.tsx b/apps/frontend/src/components/AppPanel/index.tsx new file mode 100644 index 000000000..7ebf38c0e --- /dev/null +++ b/apps/frontend/src/components/AppPanel/index.tsx @@ -0,0 +1,88 @@ +import { ArrowRightOutlined } from '@ant-design/icons'; +import { Avatar } from 'antd'; +import _ from 'lodash'; + +import { ReactComponent as LabelLLM } from '@/assets/svg/labelllm.svg'; +import { ReactComponent as MinerU } from '@/assets/svg/mineru.svg'; +import { ReactComponent as OpenDataLab } from '@/assets/svg/opendatalab.svg'; + +import styles from './index.module.css'; + +interface AppLink { + name: string; + title: string; + links: { + name: string; + link: string; + }[]; + icon: JSX.Element; + description: string; +} + +const apps = [ + { + name: 'OpenDataLab', + links: [{ name: '立即前往', link: 'https://opendatalab.com' }], + icon: , + description: '一个引领 AI 大模型时代的开放数据平台,提供了海量的、多模态的优质数据集,助力 AI 开发落地', + }, + { + name: 'LabelLLM', + links: [ + { + name: 'Github', + link: 'https://github.com/opendatalab/LabelLLM?tab=readme-ov-file#labelllm-the-open-source-data-annotation-platform', + }, + ], + icon: , + description: '专业致力于 LLM 对话标注,通过灵活的工具配置与多种数据模态的广泛兼容,为大模型打造高质量数据', + }, + { + name: 'MinerU', + links: [ + { name: 'Github', link: 'https://github.com/opendatalab/MinerU' }, + { name: '在线体验', link: 'https://opendatalab.com/OpenSourceTools/Extractor/PDF' }, + ], + icon: , + description: '一站式开源高质量数据提取工具,支持多格式(PDF/网页/电子书),智能萃取,生成高质量语料', + }, +]; + +export default function AppPanel() { + const handleGoApp = (app: AppLink) => { + window.open(app.links[0].link, '_blank'); + }; + + return ( +
+
欢迎使用 OpenDataLab 开源工具 🎉
+
+ {_.map(apps, (app) => { + return ( +
+
+
handleGoApp(app)}> + +
+ {app.name} +
{app.description}
+
+
+
+ {_.map(app.links, (link) => { + return ( + + {link.name} + + + ); + })} +
+
+
+ ); + })} +
+
+ ); +} diff --git a/apps/frontend/src/components/Navigate/index.tsx b/apps/frontend/src/components/Navigate/index.tsx index f1b27ee92..c72c96c65 100644 --- a/apps/frontend/src/components/Navigate/index.tsx +++ b/apps/frontend/src/components/Navigate/index.tsx @@ -1,15 +1,17 @@ -import { Button, Divider, Dropdown, Tag } from 'antd'; -import { Link, useMatch, useNavigate } from 'react-router-dom'; import Icon, { BellOutlined, PoweroffOutlined } from '@ant-design/icons'; import { FlexLayout } from '@labelu/components-react'; +import { Button, Divider, Dropdown, Popover, Tag } from 'antd'; +import { Link, useMatch, useNavigate } from 'react-router-dom'; -import { ReactComponent as ProfileIcon } from '@/assets/svg/personal.svg'; import { ReactComponent as LocalDeploy } from '@/assets/svg/local-deploy.svg'; +import { ReactComponent as ProfileIcon } from '@/assets/svg/personal.svg'; +import { ReactComponent as ToolboxSvg } from '@/assets/svg/toolbox.svg'; import { goLogin } from '@/utils/sso'; -import TaskTip from './TaskTip'; +import AppPanel from '../AppPanel'; import Breadcrumb from '../Breadcrumb'; import { LabeluLogo, NavigationWrapper } from './style'; +import TaskTip from './TaskTip'; const Homepage = () => { const username = localStorage.getItem('username'); @@ -50,6 +52,15 @@ const Homepage = () => { + }> + + {window.IS_ONLINE && (