mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-10 03:16:51 +08:00
feat: fe mobile responsive next (#1609)
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import s from './index.module.css'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
|
||||
type HeaderWrapperProps = {
|
||||
children: React.ReactNode
|
||||
@@ -12,22 +11,16 @@ const HeaderWrapper = ({
|
||||
children,
|
||||
}: HeaderWrapperProps) => {
|
||||
const pathname = usePathname()
|
||||
const { langeniusVersionInfo } = useAppContext()
|
||||
const isBordered = ['/apps', '/datasets'].includes(pathname)
|
||||
|
||||
return (
|
||||
<div className={classNames(
|
||||
'sticky top-0 left-0 right-0 z-20 flex bg-gray-100 grow-0 shrink-0 basis-auto h-14',
|
||||
'sticky top-0 left-0 right-0 z-20 flex flex-col bg-gray-100 grow-0 shrink-0 basis-auto min-h-[56px]',
|
||||
s.header,
|
||||
isBordered ? 'border-b border-gray-200' : '',
|
||||
)}
|
||||
>
|
||||
<div className={classNames(
|
||||
s[`header-${langeniusVersionInfo.current_env}`],
|
||||
'flex flex-1 items-center justify-between px-4',
|
||||
)}>
|
||||
{children}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,11 @@ import { ArrowUpRight, ChevronDown } from '@/app/components/base/icons/src/vende
|
||||
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
|
||||
export default function AppSelector() {
|
||||
export type IAppSelecotr = {
|
||||
isMobile: boolean
|
||||
}
|
||||
|
||||
export default function AppSelector({ isMobile }: IAppSelecotr) {
|
||||
const itemClassName = `
|
||||
flex items-center w-full h-9 px-3 text-gray-700 text-[14px]
|
||||
rounded-lg font-normal hover:bg-gray-50 cursor-pointer
|
||||
@@ -50,12 +54,15 @@ export default function AppSelector() {
|
||||
inline-flex items-center
|
||||
rounded-[20px] py-1 pr-2.5 pl-1 text-sm
|
||||
text-gray-700 hover:bg-gray-200
|
||||
mobile:px-1
|
||||
${open && 'bg-gray-200'}
|
||||
`}
|
||||
>
|
||||
<Avatar name={userProfile.name} className='mr-2' size={32} />
|
||||
{userProfile.name}
|
||||
<ChevronDown className="w-3 h-3 ml-1 text-gray-700"/>
|
||||
<Avatar name={userProfile.name} className='sm:mr-2 mr-0' size={32} />
|
||||
{!isMobile && <>
|
||||
{userProfile.name}
|
||||
<ChevronDown className="w-3 h-3 ml-1 text-gray-700"/>
|
||||
</>}
|
||||
</Menu.Button>
|
||||
</div>
|
||||
<Transition
|
||||
|
||||
@@ -70,7 +70,7 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
|
||||
)
|
||||
}
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='w-[576px] z-[11]'>
|
||||
<PortalToFollowElemContent className='w-[calc(100%-32px)] max-w-[576px] z-[11]'>
|
||||
<div className='w-full rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg z-10'>
|
||||
<div className='p-1'>
|
||||
<div className='flex items-center justify-between px-3 pt-2 pb-1'>
|
||||
|
||||
@@ -76,7 +76,7 @@ const DataSourceNotion = ({
|
||||
: (
|
||||
<div
|
||||
className={
|
||||
`flex items-center px-3 h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md
|
||||
`flex items-center px-3 py-1 min-h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md
|
||||
${isCurrentWorkspaceManager ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
|
||||
}
|
||||
onClick={handleConnectNotion}
|
||||
|
||||
@@ -23,6 +23,7 @@ import { User01 as User01Solid, Users01 as Users01Solid } from '@/app/components
|
||||
import { Globe01 } from '@/app/components/base/icons/src/vender/line/mapsAndTravel'
|
||||
import { AtSign, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
|
||||
const iconClassName = `
|
||||
w-4 h-4 ml-3 mr-2
|
||||
@@ -42,6 +43,10 @@ export default function AccountSetting({
|
||||
}: IAccountSettingProps) {
|
||||
const [activeMenu, setActiveMenu] = useState(activeTab)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const media = useBreakpoints()
|
||||
const isMobile = media === MediaType.mobile
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
key: 'workspace-group',
|
||||
@@ -130,9 +135,9 @@ export default function AccountSetting({
|
||||
wrapperClassName='!z-20 pt-[60px]'
|
||||
>
|
||||
<div className='flex'>
|
||||
<div className='w-[200px] p-4 border border-gray-100'>
|
||||
<div className='mb-8 ml-2 text-base font-medium leading-6 text-gray-900'>{t('common.userProfile.settings')}</div>
|
||||
<div>
|
||||
<div className='w-[44px] sm:w-[200px] px-[1px] py-4 sm:p-4 border border-gray-100 shrink-0 sm:shrink-1 flex flex-col items-center sm:items-start'>
|
||||
<div className='mb-8 ml-0 sm:ml-2 text-sm sm:text-base font-medium leading-6 text-gray-900'>{t('common.userProfile.settings')}</div>
|
||||
<div className='w-full'>
|
||||
{
|
||||
menuItems.map(menuItem => (
|
||||
<div key={menuItem.key} className='mb-4'>
|
||||
@@ -150,7 +155,7 @@ export default function AccountSetting({
|
||||
onClick={() => setActiveMenu(item.key)}
|
||||
>
|
||||
{activeMenu === item.key ? item.activeIcon : item.icon}
|
||||
<div className='truncate'>{item.name}</div>
|
||||
{!isMobile && <div className='truncate'>{item.name}</div>}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
@@ -167,7 +172,7 @@ export default function AccountSetting({
|
||||
<XClose className='w-4 h-4 text-gray-500' />
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-8 pt-2'>
|
||||
<div className='px-4 sm:px-8 pt-2'>
|
||||
{activeMenu === 'account' && <AccountPage />}
|
||||
{activeMenu === 'members' && <MembersPage />}
|
||||
{activeMenu === 'integrations' && <IntegrationsPage />}
|
||||
|
||||
@@ -51,13 +51,13 @@ const MembersPage = () => {
|
||||
{t('common.members.invite')}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className='flex items-center py-[7px] border-b border-gray-200'>
|
||||
<div className='overflow-x-auto'>
|
||||
<div className='flex items-center py-[7px] border-b border-gray-200 min-w-[480px]'>
|
||||
<div className='grow px-3 text-xs font-medium text-gray-500'>{t('common.members.name')}</div>
|
||||
<div className='shrink-0 w-[104px] text-xs font-medium text-gray-500'>{t('common.members.lastActive')}</div>
|
||||
<div className='shrink-0 w-[96px] px-3 text-xs font-medium text-gray-500'>{t('common.members.role')}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className='min-w-[480px]'>
|
||||
{
|
||||
accounts.map(account => (
|
||||
<div key={account.id} className='flex border-b border-gray-100'>
|
||||
|
||||
@@ -218,7 +218,7 @@ const ModelPage = () => {
|
||||
}
|
||||
<SystemModel onUpdate={() => mutateProviders()} />
|
||||
</div>
|
||||
<div className='grid grid-cols-2 gap-4 mb-6'>
|
||||
<div className='grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6'>
|
||||
{
|
||||
MODEL_CARD_LIST.map((model, index) => (
|
||||
<ModelCard
|
||||
|
||||
@@ -34,7 +34,7 @@ const ModelItem: FC<ModelItemProps> = ({
|
||||
|
||||
return (
|
||||
<div className='mb-2 bg-gray-50 rounded-xl'>
|
||||
<div className='flex justify-between items-center px-4 h-14'>
|
||||
<div className='flex justify-between items-center p-4 min-h-[56px] flex-wrap gap-y-1'>
|
||||
<div className='flex items-center'>
|
||||
{modelItem.titleIcon[locale]}
|
||||
{
|
||||
|
||||
@@ -159,7 +159,7 @@ const Form: FC<FormProps> = ({
|
||||
options?.map(option => (
|
||||
<div
|
||||
className={`
|
||||
flex items-center px-3 h-9 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer
|
||||
flex items-center px-3 py-2 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer
|
||||
${value?.[field.key] === option.key && 'bg-white border-[1.5px] border-primary-400 shadow-sm'}
|
||||
`}
|
||||
onClick={() => handleFormChange(field.key, option.key)}
|
||||
|
||||
@@ -96,7 +96,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
<PortalToFollowElem open>
|
||||
<PortalToFollowElemContent className='w-full h-full z-[60]'>
|
||||
<div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
|
||||
<div className='w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='px-8 pt-8'>
|
||||
<div className='flex justify-between items-center mb-2'>
|
||||
<div className='text-xl font-semibold text-gray-900'>{renderTitlePrefix()}</div>
|
||||
@@ -113,7 +113,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
onClearedChange={setCleared}
|
||||
onValidating={handleValidating}
|
||||
/>
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<div className='flex justify-between items-center py-6 flex-wrap gap-y-2'>
|
||||
<a
|
||||
href={modelModal?.link.href}
|
||||
target='_blank'
|
||||
|
||||
@@ -1,43 +1,90 @@
|
||||
'use client'
|
||||
|
||||
import Link from 'next/link'
|
||||
import { useSelectedLayoutSegment } from 'next/navigation'
|
||||
import classNames from 'classnames'
|
||||
import { useEffect } from 'react'
|
||||
import { Bars3Icon } from '@heroicons/react/20/solid'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import AccountDropdown from './account-dropdown'
|
||||
import AppNav from './app-nav'
|
||||
import DatasetNav from './dataset-nav'
|
||||
import EnvNav from './env-nav'
|
||||
import ExploreNav from './explore-nav'
|
||||
import GithubStar from './github-star'
|
||||
import s from './index.module.css'
|
||||
import { WorkspaceProvider } from '@/context/workspace-context'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import LogoSite from '@/app/components/base/logo/logo-site'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
|
||||
const navClassName = `
|
||||
flex items-center relative mr-3 px-3 h-8 rounded-xl
|
||||
flex items-center relative mr-3 px-3 h-9 rounded-xl
|
||||
font-medium text-sm
|
||||
cursor-pointer
|
||||
`
|
||||
|
||||
const Header = () => {
|
||||
const { isCurrentWorkspaceManager } = useAppContext()
|
||||
const selectedSegment = useSelectedLayoutSegment()
|
||||
const { isCurrentWorkspaceManager, langeniusVersionInfo } = useAppContext()
|
||||
const media = useBreakpoints()
|
||||
const isMobile = media === MediaType.mobile
|
||||
const [isShowNavMenu, { toggle, setFalse: hideNavMenu }] = useBoolean(false)
|
||||
|
||||
useEffect(() => {
|
||||
hideNavMenu()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedSegment])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex items-center'>
|
||||
<Link href="/apps" className='flex items-center mr-4'>
|
||||
<LogoSite />
|
||||
</Link>
|
||||
<GithubStar />
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<ExploreNav className={navClassName} />
|
||||
<AppNav />
|
||||
{isCurrentWorkspaceManager && <DatasetNav />}
|
||||
</div>
|
||||
<div className='flex items-center flex-shrink-0'>
|
||||
<EnvNav />
|
||||
<WorkspaceProvider>
|
||||
<AccountDropdown />
|
||||
</WorkspaceProvider>
|
||||
<div className={classNames(
|
||||
s[`header-${langeniusVersionInfo.current_env}`],
|
||||
'flex flex-1 items-center justify-between px-4',
|
||||
)}>
|
||||
<div className='flex items-center'>
|
||||
{isMobile && <div
|
||||
className='flex items-center justify-center h-8 w-8 cursor-pointer'
|
||||
onClick={toggle}
|
||||
>
|
||||
<Bars3Icon className="h-4 w-4 text-gray-500" />
|
||||
</div>}
|
||||
{!isMobile && <>
|
||||
<Link href="/apps" className='flex items-center mr-4'>
|
||||
<LogoSite />
|
||||
</Link>
|
||||
<GithubStar />
|
||||
</>}
|
||||
</div>
|
||||
{isMobile && (
|
||||
<div className='flex'>
|
||||
<Link href="/apps" className='flex items-center mr-4'>
|
||||
<LogoSite />
|
||||
</Link>
|
||||
<GithubStar />
|
||||
</div>
|
||||
)}
|
||||
{!isMobile && (
|
||||
<div className='flex items-center'>
|
||||
<ExploreNav className={navClassName} />
|
||||
<AppNav />
|
||||
{isCurrentWorkspaceManager && <DatasetNav />}
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center flex-shrink-0'>
|
||||
<EnvNav />
|
||||
<WorkspaceProvider>
|
||||
<AccountDropdown isMobile={isMobile} />
|
||||
</WorkspaceProvider>
|
||||
</div>
|
||||
</div>
|
||||
{(isMobile && isShowNavMenu) && (
|
||||
<div className='w-full flex flex-col p-2 gap-y-1'>
|
||||
<ExploreNav className={navClassName} />
|
||||
<AppNav />
|
||||
{isCurrentWorkspaceManager && <DatasetNav />}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ const Nav = ({
|
||||
|
||||
return (
|
||||
<div className={`
|
||||
flex items-center h-8 mr-3 px-0.5 rounded-xl text-sm shrink-0 font-medium
|
||||
flex items-center h-8 mr-0 sm:mr-3 px-0.5 rounded-xl text-sm shrink-0 font-medium
|
||||
${isActived && 'bg-white shadow-md font-semibold'}
|
||||
${!curNav && !isActived && 'hover:bg-gray-200'}
|
||||
`}>
|
||||
|
||||
Reference in New Issue
Block a user