diff --git a/src/pages/repos/modules/WorkspaceDetailDialog.tsx b/src/pages/repos/modules/WorkspaceDetailDialog.tsx
index e90ea71..6da64dd 100644
--- a/src/pages/repos/modules/WorkspaceDetailDialog.tsx
+++ b/src/pages/repos/modules/WorkspaceDetailDialog.tsx
@@ -1,10 +1,15 @@
import {
Dialog,
DialogContent,
- DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+ TooltipProvider
+} from '@/components/ui/tooltip'
import { useRepoStore } from '../store'
import type { WorkspaceOpen } from '../store'
import {
@@ -19,11 +24,13 @@ import {
Zap,
Copy,
Check,
- Square
+ Square,
+ Link
} from 'lucide-react'
-import { useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'
import { useShallow } from 'zustand/shallow'
+import clsx from 'clsx'
type LinkItemKey = keyof WorkspaceOpen;
interface LinkItem {
@@ -35,7 +42,6 @@ interface LinkItem {
}
const LinkItem = ({ label, icon, url }: { label: string; icon: React.ReactNode; url?: string }) => {
- const [isHovered, setIsHovered] = useState(false)
const [isCopied, setIsCopied] = useState(false)
const handleClick = () => {
@@ -43,7 +49,7 @@ const LinkItem = ({ label, icon, url }: { label: string; icon: React.ReactNode;
copy()
return;
}
- if (url) {
+ if (url && url.startsWith('http')) {
window.open(url, '_blank')
}
}
@@ -57,41 +63,38 @@ const LinkItem = ({ label, icon, url }: { label: string; icon: React.ReactNode;
toast.error('复制失败')
}
}
- const handleCopy = async (e: React.MouseEvent) => {
- e.stopPropagation()
- if (!url) return
- copy()
- }
return (
-
+
+
+
+
+
+ {icon}
+
+
{label}
+ {url && (
+
{
+ e.stopPropagation()
+ copy()
+ }}
+ role="button"
+ className="w-6 h-6 flex items-center justify-center text-neutral-500 hover:text-neutral-900 hover:bg-neutral-100 rounded transition-colors cursor-pointer"
+ >
+ {isCopied ? : }
+
+ )}
+
+
+
+ {url}
+
+
+
)
}
@@ -124,6 +127,34 @@ const DevTabContent = ({ linkItems, workspaceLink, stopWorkspace }: {
)
}
+// Link tab 内容(暂留空)
+const LinkTabContent = () => {
+ const store = useRepoStore(useShallow((state) => ({
+ selectWorkspace: state.selectWorkspace,
+ workspaceSecretLink: state.workspaceSecretLink,
+ })))
+ const links = store.workspaceSecretLink.map(item => ({
+ label: item.title,
+ url: item.value
+ }))
+ if (links.length === 0) {
+ return (
+
+ 暂无链接, 或工作区未启动
+
+ )
+ }
+ return (
+
+
+ {links.map(link => (
+ } url={link.url} />
+ ))}
+
+
+ )
+}
+
// Work tab 内容(暂留,需要根据 business_id 做事情)
const WorkTabContent = () => {
const store = useRepoStore(useShallow((state) => ({
@@ -178,7 +209,7 @@ const WorkTabContent = () => {
}
export function WorkspaceDetailDialog() {
- const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab, selectWorkspace } = useRepoStore(useShallow((state) => ({
+ const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab, getWorkspaceSecretLink, selectWorkspace, workspaceSecretLink } = useRepoStore(useShallow((state) => ({
showWorkspaceDialog: state.showWorkspaceDialog,
setShowWorkspaceDialog: state.setShowWorkspaceDialog,
workspaceLink: state.workspaceLink,
@@ -186,6 +217,8 @@ export function WorkspaceDetailDialog() {
workspaceTab: state.workspaceTab,
setWorkspaceTab: state.setWorkspaceTab,
selectWorkspace: state.selectWorkspace,
+ getWorkspaceSecretLink: state.getWorkspaceSecretLink,
+ workspaceSecretLink: state.workspaceSecretLink
})))
const linkItems: LinkItem[] = [
{
@@ -252,6 +285,11 @@ export function WorkspaceDetailDialog() {
getUrl: (data) => data.codebuddycn
},
].sort((a, b) => (a.order || 0) - (b.order || 0))
+ useEffect(() => {
+ if (selectWorkspace) {
+ getWorkspaceSecretLink(selectWorkspace)
+ }
+ }, [selectWorkspace])
return (