102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
import {
|
|
ClipboardCheck,
|
|
FileCheck2,
|
|
type LucideIcon,
|
|
} from 'lucide-react'
|
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
import { useEffect, useState } from 'react'
|
|
import DepartmentShell from './DepartmentShell'
|
|
|
|
type AutomationWorkflowKey = 'performance-survey' | 'work-review'
|
|
|
|
type AutomationWorkflow = {
|
|
key: AutomationWorkflowKey
|
|
title: string
|
|
description: string
|
|
href: string
|
|
icon: LucideIcon
|
|
}
|
|
|
|
const AUTOMATION_WORKFLOWS: AutomationWorkflow[] = [
|
|
{
|
|
key: 'performance-survey',
|
|
title: '绩效考核调研',
|
|
description: '考核问卷、填报与结果管理',
|
|
href: '/performance-survey',
|
|
icon: ClipboardCheck,
|
|
},
|
|
{
|
|
key: 'work-review',
|
|
title: '作品过稿看板',
|
|
description: '作品提交、评审与退修流转',
|
|
href: '/work-review',
|
|
icon: FileCheck2,
|
|
},
|
|
]
|
|
|
|
function normalizeWorkflow(value: string | null): AutomationWorkflowKey {
|
|
return value === 'work-review' ? 'work-review' : 'performance-survey'
|
|
}
|
|
|
|
export default function AutomationWorkflowsDashboard() {
|
|
const router = useRouter()
|
|
const searchParams = useSearchParams()
|
|
const requestedWorkflow = normalizeWorkflow(searchParams.get('workflow'))
|
|
const [activeWorkflowKey, setActiveWorkflowKey] = useState<AutomationWorkflowKey>(requestedWorkflow)
|
|
const activeWorkflow = AUTOMATION_WORKFLOWS.find((workflow) => workflow.key === activeWorkflowKey) || AUTOMATION_WORKFLOWS[0]
|
|
|
|
useEffect(() => {
|
|
setActiveWorkflowKey(requestedWorkflow)
|
|
}, [requestedWorkflow])
|
|
|
|
const selectWorkflow = (workflow: AutomationWorkflow) => {
|
|
if (workflow.key === activeWorkflowKey) return
|
|
setActiveWorkflowKey(workflow.key)
|
|
router.replace(`/workspaces/assets/automation-workflows?workflow=${workflow.key}`, { scroll: false })
|
|
}
|
|
|
|
return (
|
|
<DepartmentShell>
|
|
<main className="flex h-[calc(100dvh-72px)] min-h-[560px] flex-col overflow-hidden bg-white lg:grid lg:grid-cols-[232px_minmax(0,1fr)]">
|
|
<aside className="shrink-0 border-b border-[#e2e8f0] bg-[#f8fafc] px-4 py-4 lg:min-h-0 lg:overflow-y-auto lg:border-b-0 lg:border-r lg:px-4 lg:py-6">
|
|
<nav aria-label="自动化工作流二级导航" className="grid grid-cols-2 gap-2 lg:grid-cols-1 lg:gap-1">
|
|
{AUTOMATION_WORKFLOWS.map((workflow) => {
|
|
const Icon = workflow.icon
|
|
const active = workflow.key === activeWorkflowKey
|
|
|
|
return (
|
|
<button
|
|
key={workflow.key}
|
|
type="button"
|
|
aria-current={active ? 'page' : undefined}
|
|
onClick={() => selectWorkflow(workflow)}
|
|
className={`group flex min-h-[58px] min-w-0 items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#5a9ce6] ${active ? 'bg-[#e6f4ff] text-[#0050cb]' : 'text-[#4f6077] hover:bg-[#eef2f6] hover:text-[#101828]'}`}
|
|
>
|
|
<Icon className={`h-4 w-4 shrink-0 ${active ? 'text-[#1677ff]' : 'text-[#087052]'}`} aria-hidden="true" />
|
|
<span className="min-w-0">
|
|
<span className="block truncate text-sm font-bold">{workflow.title}</span>
|
|
<span className={`mt-0.5 hidden truncate text-xs lg:block ${active ? 'text-[#315f91]' : 'text-[#667085]'}`}>
|
|
{workflow.description}
|
|
</span>
|
|
</span>
|
|
</button>
|
|
)
|
|
})}
|
|
</nav>
|
|
</aside>
|
|
|
|
<section aria-label={`${activeWorkflow.title}操作区`} className="relative min-h-0 min-w-0 flex-1 bg-[#f2f4f7]">
|
|
<iframe
|
|
key={activeWorkflow.key}
|
|
src={activeWorkflow.href}
|
|
title={`${activeWorkflow.title}操作界面`}
|
|
className="h-full w-full border-0 bg-white"
|
|
/>
|
|
</section>
|
|
</main>
|
|
</DepartmentShell>
|
|
)
|
|
}
|