mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-11 02:29:00 +08:00
chore: layout UI upgrade (#6577)
This commit is contained in:
parent
ad7552ea8d
commit
6a9d202414
@ -3,7 +3,7 @@ import type { ReactNode } from 'react'
|
|||||||
import SwrInitor from '@/app/components/swr-initor'
|
import SwrInitor from '@/app/components/swr-initor'
|
||||||
import { AppContextProvider } from '@/context/app-context'
|
import { AppContextProvider } from '@/context/app-context'
|
||||||
import GA, { GaType } from '@/app/components/base/ga'
|
import GA, { GaType } from '@/app/components/base/ga'
|
||||||
import HeaderWrapper from '@/app/components/header/HeaderWrapper'
|
import HeaderWrapper from '@/app/components/header/header-wrapper'
|
||||||
import Header from '@/app/components/header'
|
import Header from '@/app/components/header'
|
||||||
import { EventEmitterContextProvider } from '@/context/event-emitter'
|
import { EventEmitterContextProvider } from '@/context/event-emitter'
|
||||||
import { ProviderContextProvider } from '@/context/provider-context'
|
import { ProviderContextProvider } from '@/context/provider-context'
|
||||||
|
@ -218,7 +218,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
|
|||||||
</div>
|
</div>
|
||||||
{expand && (
|
{expand && (
|
||||||
<div className="grow w-0">
|
<div className="grow w-0">
|
||||||
<div className='flex justify-between items-center text-sm leading-5 font-medium text-gray-900'>
|
<div className='flex justify-between items-center text-sm leading-5 font-medium text-text-secondary'>
|
||||||
<div className='truncate' title={appDetail.name}>{appDetail.name}</div>
|
<div className='truncate' title={appDetail.name}>{appDetail.name}</div>
|
||||||
{isCurrentWorkspaceEditor && <RiArrowDownSLine className='shrink-0 ml-[2px] w-3 h-3 text-gray-500' />}
|
{isCurrentWorkspaceEditor && <RiArrowDownSLine className='shrink-0 ml-[2px] w-3 h-3 text-gray-500' />}
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +49,7 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`
|
||||||
shrink-0 flex flex-col bg-white border-r border-gray-200 transition-all
|
shrink-0 flex flex-col bg-background-default-subtle border-r border-divider-burn transition-all
|
||||||
${expand ? 'w-[216px]' : 'w-14'}
|
${expand ? 'w-[216px]' : 'w-14'}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
@ -60,7 +60,7 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{iconType === 'app' && (
|
{iconType === 'app' && (
|
||||||
<AppInfo expand={expand}/>
|
<AppInfo expand={expand} />
|
||||||
)}
|
)}
|
||||||
{iconType !== 'app' && (
|
{iconType !== 'app' && (
|
||||||
<AppBasic
|
<AppBasic
|
||||||
@ -74,11 +74,11 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!expand && (
|
{!expand && (
|
||||||
<div className='mt-1 mx-auto w-6 h-[1px] bg-gray-100'/>
|
<div className='mt-1 mx-auto w-6 h-[1px] bg-divider-subtle' />
|
||||||
)}
|
)}
|
||||||
<nav
|
<nav
|
||||||
className={`
|
className={`
|
||||||
grow space-y-1 bg-white
|
grow space-y-1
|
||||||
${expand ? 'p-4' : 'px-2.5 py-4'}
|
${expand ? 'p-4' : 'px-2.5 py-4'}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
|
@ -44,7 +44,7 @@ export default function NavLink({
|
|||||||
key={name}
|
key={name}
|
||||||
href={href}
|
href={href}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
isActive ? 'bg-primary-50 text-primary-600 font-semibold' : 'text-gray-700 hover:bg-gray-100 hover:text-gray-700',
|
isActive ? 'bg-state-accent-active text-text-accent font-semibold' : 'text-components-menu-item-text hover:bg-gray-100 hover:text-components-menu-item-text-hover',
|
||||||
'group flex items-center h-9 rounded-md py-2 text-sm font-normal',
|
'group flex items-center h-9 rounded-md py-2 text-sm font-normal',
|
||||||
mode === 'expand' ? 'px-3' : 'px-2.5',
|
mode === 'expand' ? 'px-3' : 'px-2.5',
|
||||||
)}
|
)}
|
||||||
@ -53,7 +53,6 @@ export default function NavLink({
|
|||||||
<NavIcon
|
<NavIcon
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'h-4 w-4 flex-shrink-0',
|
'h-4 w-4 flex-shrink-0',
|
||||||
isActive ? 'text-primary-600' : 'text-gray-700',
|
|
||||||
mode === 'expand' ? 'mr-2' : 'mr-0',
|
mode === 'expand' ? 'mr-2' : 'mr-0',
|
||||||
)}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import classNames from '@/utils/classnames'
|
import classNames from '@/utils/classnames'
|
||||||
|
import { useSelector } from '@/context/app-context'
|
||||||
|
|
||||||
type LogoSiteProps = {
|
type LogoSiteProps = {
|
||||||
className?: string
|
className?: string
|
||||||
@ -8,9 +10,16 @@ type LogoSiteProps = {
|
|||||||
const LogoSite: FC<LogoSiteProps> = ({
|
const LogoSite: FC<LogoSiteProps> = ({
|
||||||
className,
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { theme } = useSelector((s) => {
|
||||||
|
return {
|
||||||
|
theme: s.theme,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const src = theme === 'light' ? '/logo/logo-site.png' : `/logo/logo-site-${theme}.png`
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
src='/logo/logo-site.png'
|
src={src}
|
||||||
className={classNames('block w-auto h-10', className)}
|
className={classNames('block w-auto h-10', className)}
|
||||||
alt='logo'
|
alt='logo'
|
||||||
/>
|
/>
|
||||||
|
@ -22,8 +22,8 @@ const ExploreNav = ({
|
|||||||
return (
|
return (
|
||||||
<Link href="/explore/apps" className={classNames(
|
<Link href="/explore/apps" className={classNames(
|
||||||
className, 'group',
|
className, 'group',
|
||||||
actived && 'bg-white shadow-md',
|
actived && 'bg-components-main-nav-nav-button-bg-active shadow-md',
|
||||||
actived ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200',
|
actived ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text hover:bg-components-main-nav-nav-button-bg-hover',
|
||||||
)}>
|
)}>
|
||||||
{
|
{
|
||||||
actived
|
actived
|
||||||
|
@ -15,7 +15,7 @@ const HeaderWrapper = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(
|
<div className={classNames(
|
||||||
'sticky top-0 left-0 right-0 z-30 flex flex-col bg-gray-100 grow-0 shrink-0 basis-auto min-h-[56px]',
|
'sticky top-0 left-0 right-0 z-30 flex flex-col grow-0 shrink-0 basis-auto min-h-[56px]',
|
||||||
s.header,
|
s.header,
|
||||||
isBordered ? 'border-b border-gray-200' : '',
|
isBordered ? 'border-b border-gray-200' : '',
|
||||||
)}
|
)}
|
@ -39,16 +39,16 @@ const Nav = ({
|
|||||||
return (
|
return (
|
||||||
<div className={`
|
<div className={`
|
||||||
flex items-center h-8 mr-0 sm: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'}
|
${isActived && 'bg-components-main-nav-nav-button-bg-active shadow-md font-semibold'}
|
||||||
${!curNav && !isActived && 'hover:bg-gray-200'}
|
${!curNav && !isActived && 'hover:bg-components-main-nav-nav-button-bg-hover'}
|
||||||
`}>
|
`}>
|
||||||
<Link href={link}>
|
<Link href={link}>
|
||||||
<div
|
<div
|
||||||
onClick={() => setAppDetail()}
|
onClick={() => setAppDetail()}
|
||||||
className={classNames(`
|
className={classNames(`
|
||||||
flex items-center h-7 px-2.5 cursor-pointer rounded-[10px]
|
flex items-center h-7 px-2.5 cursor-pointer rounded-[10px]
|
||||||
${isActived ? 'text-primary-600' : 'text-gray-500'}
|
${isActived ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text'}
|
||||||
${curNav && isActived && 'hover:bg-primary-50'}
|
${curNav && isActived && 'hover:bg-components-main-nav-nav-button-bg-active-hover'}
|
||||||
`)}
|
`)}
|
||||||
onMouseEnter={() => setHovered(true)}
|
onMouseEnter={() => setHovered(true)}
|
||||||
onMouseLeave={() => setHovered(false)}
|
onMouseLeave={() => setHovered(false)}
|
||||||
|
@ -55,8 +55,8 @@ const NavSelector = ({ curNav, navs, createText, isApp, onCreate, onLoadmore }:
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Menu.Button className={cn(
|
<Menu.Button className={cn(
|
||||||
'group inline-flex items-center w-full h-7 justify-center rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold text-primary-600 hover:bg-primary-50',
|
'group inline-flex items-center w-full h-7 justify-center rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold text-components-main-nav-nav-button-text-active hover:hover:bg-components-main-nav-nav-button-bg-active-hover',
|
||||||
open && 'bg-primary-50',
|
open && 'bg-components-main-nav-nav-button-bg-active',
|
||||||
)}>
|
)}>
|
||||||
<div className='max-w-[180px] truncate' title={curNav?.name}>{curNav?.name}</div>
|
<div className='max-w-[180px] truncate' title={curNav?.name}>{curNav?.name}</div>
|
||||||
<RiArrowDownSLine
|
<RiArrowDownSLine
|
||||||
|
@ -8,10 +8,13 @@ import { fetchAppList } from '@/service/apps'
|
|||||||
import Loading from '@/app/components/base/loading'
|
import Loading from '@/app/components/base/loading'
|
||||||
import { fetchCurrentWorkspace, fetchLanggeniusVersion, fetchUserProfile } from '@/service/common'
|
import { fetchCurrentWorkspace, fetchLanggeniusVersion, fetchUserProfile } from '@/service/common'
|
||||||
import type { App } from '@/types/app'
|
import type { App } from '@/types/app'
|
||||||
|
import { Theme } from '@/types/app'
|
||||||
import type { ICurrentWorkspace, LangGeniusVersionResponse, UserProfileResponse } from '@/models/common'
|
import type { ICurrentWorkspace, LangGeniusVersionResponse, UserProfileResponse } from '@/models/common'
|
||||||
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
|
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
|
||||||
|
|
||||||
export type AppContextValue = {
|
export type AppContextValue = {
|
||||||
|
theme: Theme
|
||||||
|
setTheme: (theme: Theme) => void
|
||||||
apps: App[]
|
apps: App[]
|
||||||
mutateApps: VoidFunction
|
mutateApps: VoidFunction
|
||||||
userProfile: UserProfileResponse
|
userProfile: UserProfileResponse
|
||||||
@ -49,6 +52,8 @@ const initialWorkspaceInfo: ICurrentWorkspace = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AppContext = createContext<AppContextValue>({
|
const AppContext = createContext<AppContextValue>({
|
||||||
|
theme: Theme.light,
|
||||||
|
setTheme: () => { },
|
||||||
apps: [],
|
apps: [],
|
||||||
mutateApps: () => { },
|
mutateApps: () => { },
|
||||||
userProfile: {
|
userProfile: {
|
||||||
@ -112,11 +117,24 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
|||||||
setCurrentWorkspace(currentWorkspaceResponse)
|
setCurrentWorkspace(currentWorkspaceResponse)
|
||||||
}, [currentWorkspaceResponse])
|
}, [currentWorkspaceResponse])
|
||||||
|
|
||||||
|
const [theme, setTheme] = useState<Theme>(Theme.light)
|
||||||
|
const handleSetTheme = useCallback((theme: Theme) => {
|
||||||
|
setTheme(theme)
|
||||||
|
globalThis.document.documentElement.setAttribute('data-theme', theme)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
globalThis.document.documentElement.setAttribute('data-theme', theme)
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
if (!appList || !userProfile)
|
if (!appList || !userProfile)
|
||||||
return <Loading type='app' />
|
return <Loading type='app' />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider value={{
|
<AppContext.Provider value={{
|
||||||
|
theme,
|
||||||
|
setTheme: handleSetTheme,
|
||||||
apps: appList.data,
|
apps: appList.data,
|
||||||
mutateApps,
|
mutateApps,
|
||||||
userProfile,
|
userProfile,
|
||||||
@ -133,7 +151,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
|||||||
}}>
|
}}>
|
||||||
<div className='flex flex-col h-full overflow-y-auto'>
|
<div className='flex flex-col h-full overflow-y-auto'>
|
||||||
{globalThis.document?.body?.getAttribute('data-public-maintenance-notice') && <MaintenanceNotice />}
|
{globalThis.document?.body?.getAttribute('data-public-maintenance-notice') && <MaintenanceNotice />}
|
||||||
<div ref={pageContainerRef} className='grow relative flex flex-col overflow-y-auto overflow-x-hidden bg-gray-100'>
|
<div ref={pageContainerRef} className='grow relative flex flex-col overflow-y-auto overflow-x-hidden bg-background-body'>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
web/public/logo/logo-site-dark.png
Normal file
BIN
web/public/logo/logo-site-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -4,6 +4,7 @@ module.exports = {
|
|||||||
content: [
|
content: [
|
||||||
'./app/**/*.{js,ts,jsx,tsx}',
|
'./app/**/*.{js,ts,jsx,tsx}',
|
||||||
'./components/**/*.{js,ts,jsx,tsx}',
|
'./components/**/*.{js,ts,jsx,tsx}',
|
||||||
|
'./context/**/*.{js,ts,jsx,tsx}',
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
typography: require('./typography'),
|
typography: require('./typography'),
|
||||||
|
@ -3,6 +3,11 @@ import type { CollectionType } from '@/app/components/tools/types'
|
|||||||
import type { LanguagesSupported } from '@/i18n/language'
|
import type { LanguagesSupported } from '@/i18n/language'
|
||||||
import type { Tag } from '@/app/components/base/tag-management/constant'
|
import type { Tag } from '@/app/components/base/tag-management/constant'
|
||||||
|
|
||||||
|
export enum Theme {
|
||||||
|
light = 'light',
|
||||||
|
dark = 'dark',
|
||||||
|
}
|
||||||
|
|
||||||
export enum ProviderType {
|
export enum ProviderType {
|
||||||
openai = 'openai',
|
openai = 'openai',
|
||||||
anthropic = 'anthropic',
|
anthropic = 'anthropic',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user