非管理员隐藏头部

This commit is contained in:
2026-01-16 18:07:42 +08:00
parent bac3a97720
commit 40305bd4ca
3 changed files with 55 additions and 4 deletions

View File

@@ -1,13 +1,15 @@
'use client' 'use client'
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
import { useSelector } from '@/context/app-context'
/** /**
* IframePostMessage * IframePostMessage
* 页面加载完成后向父页面发送一次消息,并每 5 秒发送一次。 * 页面加载完成后向父页面发送一次消息,并每 5 秒发送一次。
* 仅当当前窗口运行在 iframe 中时才发送。 * 仅当当前窗口运行在 iframe 中时才发送本地缓存消息
*/ */
const IframePostMessage = () => { const IframePostMessage = () => {
const initializedRef = useRef(false) const initializedRef = useRef(false)
const isCurrentWorkspaceManager = useSelector(s => s.isCurrentWorkspaceManager)
/** /**
* sendMessage * sendMessage
@@ -47,6 +49,27 @@ const IframePostMessage = () => {
} }
} }
/**
* applyHeaderVisibility
* 使用原生 JS 根据管理员状态隐藏或显示头部容器:
* - 非管理员owner/admin 之外)隐藏
* - 管理员显示
* 不区分是否在 iframe 中,统一处理。
*/
const applyHeaderVisibility = () => {
try {
if (typeof document === 'undefined') return
const headerEl = document.querySelector('.app-global-header') as HTMLElement | null
if (!headerEl) return
if (!isCurrentWorkspaceManager)
headerEl.style.display = 'none'
else
headerEl.style.display = ''
} catch {
// 忽略可能的运行时错误
}
}
useEffect(() => { useEffect(() => {
if (initializedRef.current) return if (initializedRef.current) return
initializedRef.current = true initializedRef.current = true
@@ -74,6 +97,13 @@ const IframePostMessage = () => {
} }
}, []) }, [])
/**
* 根据管理员状态应用头部可见性
*/
useEffect(() => {
applyHeaderVisibility()
}, [isCurrentWorkspaceManager])
return null return null
} }

View File

@@ -3,12 +3,19 @@ import React, { useState } from 'react'
import { usePathname } from 'next/navigation' import { usePathname } from 'next/navigation'
import s from './index.module.css' import s from './index.module.css'
import { useEventEmitterContextContext } from '@/context/event-emitter' import { useEventEmitterContextContext } from '@/context/event-emitter'
import { useSelector } from '@/context/app-context'
import classNames from '@/utils/classnames' import classNames from '@/utils/classnames'
type HeaderWrapperProps = { type HeaderWrapperProps = {
children: React.ReactNode children: React.ReactNode
} }
/**
* HeaderWrapper
* 负责包裹并渲染全局头部区域。
* - 在工作流画布最大化时隐藏头部
* - 当当前用户非管理员owner/admin 之外)时隐藏头部(不区分是否在 iframe
*/
const HeaderWrapper = ({ const HeaderWrapper = ({
children, children,
}: HeaderWrapperProps) => { }: HeaderWrapperProps) => {
@@ -20,6 +27,7 @@ const HeaderWrapper = ({
const workflowCanvasMaximize = localStorage.getItem('workflow-canvas-maximize') === 'true' const workflowCanvasMaximize = localStorage.getItem('workflow-canvas-maximize') === 'true'
const [hideHeader, setHideHeader] = useState(workflowCanvasMaximize) const [hideHeader, setHideHeader] = useState(workflowCanvasMaximize)
const { eventEmitter } = useEventEmitterContextContext() const { eventEmitter } = useEventEmitterContextContext()
const isCurrentWorkspaceManager = useSelector(s => s.isCurrentWorkspaceManager)
eventEmitter?.useSubscription((v: any) => { eventEmitter?.useSubscription((v: any) => {
if (v?.type === 'workflow-canvas-maximize') if (v?.type === 'workflow-canvas-maximize')
@@ -29,9 +37,10 @@ const HeaderWrapper = ({
return ( return (
<div className={classNames( <div className={classNames(
'sticky left-0 right-0 top-0 z-[30] flex min-h-[56px] shrink-0 grow-0 basis-auto flex-col', 'sticky left-0 right-0 top-0 z-[30] flex min-h-[56px] shrink-0 grow-0 basis-auto flex-col',
'app-global-header',
s.header, s.header,
isBordered ? 'border-b border-divider-regular' : '', isBordered ? 'border-b border-divider-regular' : '',
hideHeader && (inWorkflowCanvas || isPipelineCanvas) && 'hidden', ((!isCurrentWorkspaceManager) || (hideHeader && (inWorkflowCanvas || isPipelineCanvas))) && 'hidden',
)} )}
> >
{children} {children}

View File

@@ -22,6 +22,10 @@ export const useGlobalPublicStore = create<GlobalPublicStore>(set => ({
setSystemFeatures: (systemFeatures: SystemFeatures) => set(() => ({ systemFeatures })), setSystemFeatures: (systemFeatures: SystemFeatures) => set(() => ({ systemFeatures })),
})) }))
/**
* GlobalPublicStoreProvider
* 初始化并提供系统特性systemFeatures统一设置品牌标题为“智能体平台”以用于页面标题拼接
*/
const GlobalPublicStoreProvider: FC<PropsWithChildren> = ({ const GlobalPublicStoreProvider: FC<PropsWithChildren> = ({
children, children,
}) => { }) => {
@@ -32,7 +36,15 @@ const GlobalPublicStoreProvider: FC<PropsWithChildren> = ({
const { setSystemFeatures, setIsGlobalPending: setIsPending } = useGlobalPublicStore() const { setSystemFeatures, setIsGlobalPending: setIsPending } = useGlobalPublicStore()
useEffect(() => { useEffect(() => {
if (data) if (data)
setSystemFeatures({ ...defaultSystemFeatures, ...data }) setSystemFeatures({
...defaultSystemFeatures,
...data,
branding: {
...defaultSystemFeatures.branding,
...(data.branding || {}),
application_title: '智能体平台',
},
})
}, [data, setSystemFeatures]) }, [data, setSystemFeatures])
useEffect(() => { useEffect(() => {