feat: move people structure tree to secondary sidebar
This commit is contained in:
parent
74ec2f0c58
commit
1481f56eb2
@ -14,6 +14,7 @@ jest.mock('@/components/organization/OrganizationWorkspace', () => ({
|
||||
data-embedded={String(props.embedded)}
|
||||
data-scope={String(props.scopeRootName)}
|
||||
data-heading={String(props.heading)}
|
||||
data-tree-as-secondary-sidebar={String(props.treeAsSecondarySidebar)}
|
||||
>
|
||||
{String(props.description)}
|
||||
</div>
|
||||
@ -28,6 +29,7 @@ describe('PeopleStructureDashboard', () => {
|
||||
expect(screen.getByTestId('organization-workspace')).toHaveAttribute('data-embedded', 'true')
|
||||
expect(screen.getByTestId('organization-workspace')).toHaveAttribute('data-scope', '品牌中心')
|
||||
expect(screen.getByTestId('organization-workspace')).toHaveAttribute('data-heading', '人员架构')
|
||||
expect(screen.getByTestId('organization-workspace')).toHaveAttribute('data-tree-as-secondary-sidebar', 'true')
|
||||
expect(screen.getByText(/公司组织架构 · 品牌中心在职人员/)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@ -15,6 +15,7 @@ export default function PeopleStructureDashboard() {
|
||||
scopeRootName="品牌中心"
|
||||
heading="人员架构"
|
||||
description="公司组织架构 · 品牌中心在职人员 · 数据源:HR 花名册(每日 02:00 自动同步)"
|
||||
treeAsSecondarySidebar
|
||||
/>
|
||||
</div>
|
||||
</DepartmentShell>
|
||||
|
||||
@ -98,6 +98,7 @@ type OrganizationWorkspaceProps = {
|
||||
scopeRootName?: string
|
||||
heading?: string
|
||||
description?: string
|
||||
treeAsSecondarySidebar?: boolean
|
||||
}
|
||||
|
||||
function findOrganizationNode(nodes: OrgNode[], name: string): OrgNode | null {
|
||||
@ -115,6 +116,7 @@ export default function OrganizationWorkspace({
|
||||
scopeRootName,
|
||||
heading = '组织架构',
|
||||
description = '品牌中心在职人员 · 数据源:HR 花名册(每日 02:00 自动同步)',
|
||||
treeAsSecondarySidebar = false,
|
||||
}: OrganizationWorkspaceProps) {
|
||||
const { data: session, status } = useSession()
|
||||
const router = useRouter()
|
||||
@ -296,10 +298,10 @@ export default function OrganizationWorkspace({
|
||||
}
|
||||
|
||||
const content = (
|
||||
<div className="max-w-[1400px] mx-auto px-5 py-6">
|
||||
<div className={treeAsSecondarySidebar ? 'w-full' : 'mx-auto max-w-[1400px] px-5 py-6'}>
|
||||
{/* direction: cloud-quarry (seed 32cb33b5) — THESIS: 部门即层叠石料块,人员是块上铭牌 */}
|
||||
{/* 页头 */}
|
||||
<div className="mb-5 flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className={`${treeAsSecondarySidebar ? 'border-b border-[#e2e8f0] bg-white px-5 py-5 sm:px-7' : 'mb-5'} flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between`}>
|
||||
<div>
|
||||
<h1 className="text-[26px] font-bold text-[#1a1c1d] tracking-tight">{heading}</h1>
|
||||
<p className="text-[13px] text-[#86898e] mt-1">{description}</p>
|
||||
@ -331,26 +333,30 @@ export default function OrganizationWorkspace({
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="bg-[#fdf6e9] border border-[#e8c98a] text-[#a0671c] rounded-lg px-4 py-3 text-[13px] mb-4">
|
||||
<div className={`${treeAsSecondarySidebar ? 'mx-5 mt-4 sm:mx-7' : 'mb-4'} rounded-lg border border-[#e8c98a] bg-[#fdf6e9] px-4 py-3 text-[13px] text-[#a0671c]`}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && !data ? (
|
||||
<div className="bg-white rounded-lg border border-[#e7e8ea] shadow-sm p-10 text-center text-[#86898e] text-sm">
|
||||
<div className={`${treeAsSecondarySidebar ? 'm-5 sm:m-7' : ''} rounded-lg border border-[#e7e8ea] bg-white p-10 text-center text-sm text-[#86898e] shadow-sm`}>
|
||||
加载中…
|
||||
</div>
|
||||
) : data ? (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[300px_1fr] gap-5 items-start">
|
||||
<div className={`grid grid-cols-1 items-start ${treeAsSecondarySidebar ? 'gap-0 lg:grid-cols-[232px_minmax(0,1fr)] lg:items-stretch' : 'gap-5 lg:grid-cols-[300px_1fr]'}`}>
|
||||
{/* 左侧:组织树 */}
|
||||
<aside className="bg-white rounded-lg border border-[#e7e8ea] shadow-sm overflow-hidden">
|
||||
<div className="px-4 py-3 border-b border-[#eef0f3] flex items-center justify-between">
|
||||
<span className="text-[12px] font-semibold text-[#1a1c1d]">
|
||||
<aside className={treeAsSecondarySidebar
|
||||
? 'overflow-hidden border-b border-[#e2e8f0] bg-[#f8fafc] lg:min-h-0 lg:border-b-0 lg:border-r'
|
||||
: 'overflow-hidden rounded-lg border border-[#e7e8ea] bg-white shadow-sm'}
|
||||
aria-label={treeAsSecondarySidebar ? '人员架构二级导航' : undefined}
|
||||
>
|
||||
<div className={`${treeAsSecondarySidebar ? 'border-b border-[#e2e8f0] px-4 py-4' : 'border-b border-[#eef0f3] px-4 py-3'} flex items-center justify-between`}>
|
||||
<span className={`${treeAsSecondarySidebar ? 'text-sm font-bold text-[#101828]' : 'text-[12px] font-semibold text-[#1a1c1d]'}`}>
|
||||
{scopeRootName ? `${scopeRootName}组织架构` : '组织架构'}
|
||||
</span>
|
||||
<span className="text-[11px] text-[#86898e]">{scopedTree.length} 顶层节点</span>
|
||||
<span className={`${treeAsSecondarySidebar ? 'text-xs text-[#66758b]' : 'text-[11px] text-[#86898e]'}`}>{scopedTree.length} 顶层节点</span>
|
||||
</div>
|
||||
<nav className="max-h-[calc(100vh-260px)] overflow-y-auto py-2" aria-label="组织树">
|
||||
<nav className={`${treeAsSecondarySidebar ? 'max-h-[42vh] p-2 lg:max-h-[calc(100dvh-188px)] lg:py-4' : 'max-h-[calc(100vh-260px)] py-2'} overflow-y-auto`} aria-label="组织树">
|
||||
{scopeRootName && scopedTree.length === 0 && (
|
||||
<p className="px-4 py-8 text-center text-[13px] leading-6 text-[#86898e]">
|
||||
未找到“{scopeRootName}”组织节点
|
||||
@ -447,7 +453,10 @@ export default function OrganizationWorkspace({
|
||||
</aside>
|
||||
|
||||
{/* 右侧:人员明细 */}
|
||||
<section className="bg-white rounded-lg border border-[#e7e8ea] shadow-sm overflow-hidden">
|
||||
<section className={treeAsSecondarySidebar
|
||||
? 'min-w-0 overflow-hidden bg-white'
|
||||
: 'overflow-hidden rounded-lg border border-[#e7e8ea] bg-white shadow-sm'}
|
||||
>
|
||||
<div className="px-5 py-4 border-b border-[#eef0f3]">
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user