123 lines
5.3 KiB
TypeScript
123 lines
5.3 KiB
TypeScript
import { t, useLocaleRender } from '../../i18n'
|
|
import { Code2, FileCode2, GitBranch, Network, Radio, Search, Settings, Terminal } from 'lucide-react'
|
|
import type React from 'react'
|
|
|
|
export type WorkspaceActivity = 'modules' | 'ros-connections' | 'workspace' | 'search' | 'logs' | 'examples' | 'git' | 'settings'
|
|
|
|
type WorkspaceNavProps = {
|
|
dark: boolean
|
|
workspaceActive: boolean
|
|
activeActivity: WorkspaceActivity
|
|
selectedModuleExists: boolean
|
|
installedGitModuleCount: number
|
|
teamProject: boolean
|
|
moduleTabCount: number
|
|
gitChangedFileCount: number
|
|
workspaceNavFlash: boolean
|
|
onSelect: (activity: WorkspaceActivity) => void
|
|
}
|
|
|
|
const WORKSPACE_NAV_ITEMS: Array<{
|
|
id: WorkspaceActivity
|
|
Icon: typeof Network
|
|
label: string
|
|
}> = [
|
|
{ id: 'modules', Icon: Network, label: '모듈 리스트' },
|
|
{ id: 'ros-connections', Icon: Radio, label: 'ROS 연결상태' },
|
|
{ id: 'workspace', Icon: Code2, label: '코드 편집' },
|
|
{ id: 'search', Icon: Search, label: '검색' },
|
|
{ id: 'logs', Icon: Terminal, label: '로그' },
|
|
{ id: 'examples', Icon: FileCode2, label: '예제 코드' },
|
|
{ id: 'git', Icon: GitBranch, label: '소스 제어' },
|
|
{ id: 'settings', Icon: Settings, label: '설정' }
|
|
]
|
|
|
|
export default function WorkspaceNav({
|
|
dark,
|
|
workspaceActive,
|
|
activeActivity,
|
|
selectedModuleExists,
|
|
installedGitModuleCount,
|
|
teamProject,
|
|
moduleTabCount,
|
|
gitChangedFileCount,
|
|
workspaceNavFlash,
|
|
onSelect
|
|
}: WorkspaceNavProps): React.JSX.Element {
|
|
useLocaleRender()
|
|
const tooltipClassName = [
|
|
'pointer-events-none absolute left-11 top-1/2 z-50 hidden -translate-y-1/2 whitespace-nowrap rounded-md border px-2 py-1 text-[11px] font-semibold shadow-[0_10px_24px_rgba(0,0,0,0.24)] group-hover:block',
|
|
dark ? 'border-white/10 bg-[#303030] text-white/78' : 'border-[#d8dee9] bg-white text-[#4f596b]'
|
|
].join(' ')
|
|
|
|
return (
|
|
<nav
|
|
data-help="workspace-nav"
|
|
className={['relative z-30 flex flex-col items-center gap-3 overflow-visible border-r py-3', dark ? 'border-white/10 bg-[#303030] text-white/65' : 'border-[#cbbdde] bg-[linear-gradient(180deg,#e6ddf1_0%,#e8e1f2_55%,#e4eef7_100%)] text-[#475569]'].join(' ')}
|
|
style={workspaceActive ? { gridColumn: 3, gridRow: '1 / span 2' } : { gridColumn: 3, gridRow: 1 }}
|
|
>
|
|
{WORKSPACE_NAV_ITEMS.map(({ id, Icon, label }) => {
|
|
const active = activeActivity === id
|
|
const selectable = id === 'modules' ||
|
|
id === 'ros-connections' ||
|
|
id === 'workspace' ||
|
|
id === 'examples' ||
|
|
id === 'settings' ||
|
|
(id === 'git' && (teamProject || installedGitModuleCount > 0)) ||
|
|
((id === 'search' || id === 'logs') && selectedModuleExists)
|
|
|
|
return (
|
|
<button
|
|
key={id}
|
|
type="button"
|
|
aria-label={t(label)}
|
|
onClick={() => {
|
|
if (!selectable) return
|
|
onSelect(id)
|
|
}}
|
|
className={[
|
|
'group relative z-0 grid h-8 w-8 place-items-center overflow-visible rounded-lg transition',
|
|
selectable ? 'cursor-pointer' : 'cursor-default opacity-55',
|
|
active
|
|
? dark
|
|
? 'bg-[#2563eb]/32 text-white'
|
|
: 'bg-[#c7d9f8] text-[#1e40af]'
|
|
: dark
|
|
? selectable ? 'hover:bg-white/10 hover:text-white' : ''
|
|
: selectable ? 'hover:bg-[#d1dae7] hover:text-[#111520]' : ''
|
|
].join(' ')}
|
|
>
|
|
{id === 'workspace' && workspaceNavFlash && (
|
|
<>
|
|
<span className={['pointer-events-none absolute inset-[-3px] rounded-xl border animate-ping', dark ? 'border-white/70 shadow-[0_0_18px_rgba(255,255,255,0.28)]' : 'border-[#7c3aed]/70 shadow-[0_0_12px_rgba(124,58,237,0.22)]'].join(' ')} />
|
|
<span className={['pointer-events-none absolute inset-0 rounded-lg animate-pulse', dark ? 'bg-[#60a5fa]/18 shadow-[0_0_18px_rgba(96,165,250,0.38)]' : 'bg-[#7c3aed]/15 shadow-[0_0_12px_rgba(124,58,237,0.18)]'].join(' ')} />
|
|
</>
|
|
)}
|
|
<Icon
|
|
size={17}
|
|
className={[
|
|
'relative z-10',
|
|
id === 'modules' ? 'translate-x-[0.5px]' : '',
|
|
id === 'workspace' && workspaceNavFlash ? (dark ? 'text-[#b8d7ff]' : 'text-[#5b21b6]') : ''
|
|
].join(' ')}
|
|
/>
|
|
{id === 'workspace' && moduleTabCount > 0 && (
|
|
<span className="absolute -right-1 -top-1 z-20 flex h-4 min-w-4 items-center justify-center rounded-full bg-[#2563eb] px-1 pt-px text-center text-[10px] font-bold leading-4 text-white shadow-[0_0_10px_rgba(37,99,235,0.42)]">
|
|
<span className="translate-x-[0.5px]">{moduleTabCount}</span>
|
|
</span>
|
|
)}
|
|
{id === 'git' && gitChangedFileCount > 0 && (
|
|
<span className="absolute -right-1 -top-1 z-20 flex h-4 min-w-4 items-center justify-center rounded-full bg-[#2563eb] px-1 pt-px text-center text-[10px] font-bold leading-4 text-white shadow-[0_0_10px_rgba(37,99,235,0.42)]">
|
|
<span className="translate-x-[0.5px]">{gitChangedFileCount > 9 ? '9+' : gitChangedFileCount}</span>
|
|
</span>
|
|
)}
|
|
<span className={tooltipClassName}>
|
|
{t(label)}
|
|
</span>
|
|
</button>
|
|
)
|
|
})}
|
|
</nav>
|
|
)
|
|
}
|