Chore: frontend infrastructure upgrade (#16420)
Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: jZonG <jzongcode@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { RiArrowDownCircleLine, RiArrowRightSLine, RiVerifiedBadgeLine } from '@remixicon/react'
|
||||
import type { FC, MouseEvent } from 'react'
|
||||
import { Fragment, useCallback } from 'react'
|
||||
@@ -76,9 +76,9 @@ const UpgradeOrDownload: FC<UpgradeOrDownloadProps> = ({ doc_name }) => {
|
||||
downloadCompliance()
|
||||
}, [downloadCompliance])
|
||||
if (isCurrentPlanCanDownload) {
|
||||
return <Button loading={isPending} disabled={isPending} size='small' variant='secondary' className='flex gap-[1px] items-center' onClick={handleDownloadClick}>
|
||||
return <Button loading={isPending} disabled={isPending} size='small' variant='secondary' className='flex items-center gap-[1px]' onClick={handleDownloadClick}>
|
||||
<RiArrowDownCircleLine className='size-[14px] text-components-button-secondary-text-disabled' />
|
||||
<span className='px-[3px] system-xs-medium text-components-button-secondary-text'>{t('common.operation.download')}</span>
|
||||
<span className='system-xs-medium px-[3px] text-components-button-secondary-text'>{t('common.operation.download')}</span>
|
||||
</Button>
|
||||
}
|
||||
const upgradeTooltip: Record<Plan, string> = {
|
||||
@@ -89,7 +89,7 @@ const UpgradeOrDownload: FC<UpgradeOrDownloadProps> = ({ doc_name }) => {
|
||||
}
|
||||
return <Tooltip asChild={false} popupContent={upgradeTooltip[plan.type]}>
|
||||
<PremiumBadge color='blue' allowHover={true} onClick={handlePlanClick}>
|
||||
<SparklesSoft className='flex items-center py-[1px] pl-[3px] w-3.5 h-3.5 text-components-premium-badge-indigo-text-stop-0' />
|
||||
<SparklesSoft className='flex h-3.5 w-3.5 items-center py-[1px] pl-[3px] text-components-premium-badge-indigo-text-stop-0' />
|
||||
<div className='system-xs-medium'>
|
||||
<span className='p-1'>
|
||||
{t('billing.upgradeBtn.encourageShort')}
|
||||
@@ -106,18 +106,18 @@ export default function Compliance() {
|
||||
`
|
||||
const { t } = useTranslation()
|
||||
|
||||
return <Menu as="div" className="relative w-full h-full">
|
||||
return <Menu as="div" className="relative h-full w-full">
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={
|
||||
cn('flex items-center pl-3 pr-2 py-2 h-9 w-full group hover:bg-state-base-hover rounded-lg gap-1',
|
||||
<MenuButton className={
|
||||
cn('group flex h-9 w-full items-center gap-1 rounded-lg py-2 pl-3 pr-2 hover:bg-state-base-hover',
|
||||
open && 'bg-state-base-hover',
|
||||
)}>
|
||||
<RiVerifiedBadgeLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow text-left system-md-regular text-text-secondary px-1'>{t('common.userProfile.compliance')}</div>
|
||||
<RiArrowRightSLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Menu.Button>
|
||||
<RiVerifiedBadgeLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-left text-text-secondary'>{t('common.userProfile.compliance')}</div>
|
||||
<RiArrowRightSLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -127,56 +127,56 @@ export default function Compliance() {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className={cn(
|
||||
`absolute top-[1px] w-[337px] max-h-[70vh] overflow-y-scroll z-10 bg-components-panel-bg-blur backdrop-blur-[5px] border-[0.5px] border-components-panel-border
|
||||
divide-y divide-divider-subtle origin-top-right rounded-xl focus:outline-none shadow-lg -translate-x-full
|
||||
`absolute top-[1px] z-10 max-h-[70vh] w-[337px] origin-top-right -translate-x-full divide-y divide-divider-subtle overflow-y-scroll
|
||||
rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-[5px] focus:outline-none
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<div className="px-1 py-1">
|
||||
<Menu.Item>
|
||||
{({ active }) => <div
|
||||
<MenuItem>
|
||||
<div
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}>
|
||||
<Soc2 className='shrink-0 size-7' />
|
||||
<div className='system-md-regular grow text-text-secondary px-1 truncate'>{t('common.compliance.soc2Type1')}</div>
|
||||
<Soc2 className='size-7 shrink-0' />
|
||||
<div className='system-md-regular grow truncate px-1 text-text-secondary'>{t('common.compliance.soc2Type1')}</div>
|
||||
<UpgradeOrDownload doc_name={DocName.SOC2_Type_I} />
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
{({ active }) => <div
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}>
|
||||
<Soc2 className='shrink-0 size-7' />
|
||||
<div className='system-md-regular grow text-text-secondary px-1 truncate'>{t('common.compliance.soc2Type2')}</div>
|
||||
<Soc2 className='size-7 shrink-0' />
|
||||
<div className='system-md-regular grow truncate px-1 text-text-secondary'>{t('common.compliance.soc2Type2')}</div>
|
||||
<UpgradeOrDownload doc_name={DocName.SOC2_Type_II} />
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
{({ active }) => <div
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}>
|
||||
<Iso className='shrink-0 size-7' />
|
||||
<div className='system-md-regular grow text-text-secondary px-1 truncate'>{t('common.compliance.iso27001')}</div>
|
||||
<Iso className='size-7 shrink-0' />
|
||||
<div className='system-md-regular grow truncate px-1 text-text-secondary'>{t('common.compliance.iso27001')}</div>
|
||||
<UpgradeOrDownload doc_name={DocName.ISO_27001} />
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
{({ active }) => <div
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}>
|
||||
<Gdpr className='shrink-0 size-7' />
|
||||
<div className='system-md-regular grow text-text-secondary px-1 truncate'>{t('common.compliance.gdpr')}</div>
|
||||
<Gdpr className='size-7 shrink-0' />
|
||||
<div className='system-md-regular grow truncate px-1 text-text-secondary'>{t('common.compliance.gdpr')}</div>
|
||||
<UpgradeOrDownload doc_name={DocName.GDPR} />
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useRouter } from 'next/navigation'
|
||||
import { useContext, useContextSelector } from 'use-context-selector'
|
||||
import { RiAccountCircleLine, RiArrowDownSLine, RiArrowRightUpLine, RiBookOpenLine, RiGithubLine, RiInformation2Line, RiLogoutBoxRLine, RiMap2Line, RiSettings3Line, RiStarLine } from '@remixicon/react'
|
||||
import Link from 'next/link'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import Indicator from '../indicator'
|
||||
import AccountAbout from '../account-about'
|
||||
import GithubStar from '../github-star'
|
||||
@@ -58,21 +58,21 @@ export default function AppSelector({ isMobile }: IAppSelector) {
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button
|
||||
<MenuButton
|
||||
className={`
|
||||
inline-flex items-center
|
||||
rounded-[20px] py-1 pr-2.5 pl-1 text-sm
|
||||
rounded-[20px] py-1 pl-1 pr-2.5 text-sm
|
||||
text-text-secondary hover:bg-state-base-hover
|
||||
mobile:px-1
|
||||
${open && 'bg-state-base-hover'}
|
||||
`}
|
||||
>
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='sm:mr-2 mr-0' size={32} />
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='mr-0 sm:mr-2' size={32} />
|
||||
{!isMobile && <>
|
||||
{userProfile.name}
|
||||
<RiArrowDownSLine className="w-3 h-3 ml-1 text-text-tertiary" />
|
||||
<RiArrowDownSLine className="ml-1 h-3 w-3 text-text-tertiary" />
|
||||
</>}
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -82,120 +82,120 @@ export default function AppSelector({ isMobile }: IAppSelector) {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className="
|
||||
absolute right-0 mt-1.5 w-60 max-w-80
|
||||
divide-y divide-divider-subtle origin-top-right rounded-lg bg-components-panel-bg-blur
|
||||
origin-top-right divide-y divide-divider-subtle rounded-lg bg-components-panel-bg-blur
|
||||
shadow-lg focus:outline-none
|
||||
"
|
||||
>
|
||||
<Menu.Item disabled>
|
||||
<div className='flex flex-nowrap items-center pl-3 pr-2 py-[13px]'>
|
||||
<MenuItem disabled>
|
||||
<div className='flex flex-nowrap items-center py-[13px] pl-3 pr-2'>
|
||||
<div className='grow'>
|
||||
<div className='system-md-medium text-text-primary break-all'>{userProfile.name}</div>
|
||||
<div className='system-xs-regular text-text-tertiary break-all'>{userProfile.email}</div>
|
||||
<div className='system-md-medium break-all text-text-primary'>{userProfile.name}</div>
|
||||
<div className='system-xs-regular break-all text-text-tertiary'>{userProfile.email}</div>
|
||||
</div>
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={36} className='mr-3' />
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
<div className="px-1 py-1">
|
||||
<Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<MenuItem>
|
||||
<Link
|
||||
className={classNames(itemClassName, 'group',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href='/account'
|
||||
target='_self' rel='noopener noreferrer'>
|
||||
<RiAccountCircleLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.account.account')}</div>
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.account.account')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</Link>}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
{({ active }) => <div className={classNames(itemClassName,
|
||||
active && 'bg-state-base-hover',
|
||||
</Link>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div className={classNames(itemClassName,
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)} onClick={() => setShowAccountSettingModal({ payload: 'members' })}>
|
||||
<RiSettings3Line className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.settings')}</div>
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.settings')}</div>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</div>
|
||||
<div className='p-1'>
|
||||
<Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<MenuItem>
|
||||
<Link
|
||||
className={classNames(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href={
|
||||
locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/`
|
||||
}
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiBookOpenLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.helpCenter')}</div>
|
||||
<RiArrowRightUpLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Link>}
|
||||
</Menu.Item>
|
||||
<RiBookOpenLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.helpCenter')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</Link>
|
||||
</MenuItem>
|
||||
<Support />
|
||||
{IS_CLOUD_EDITION && isCurrentWorkspaceOwner && <Compliance />}
|
||||
</div>
|
||||
<div className='p-1'>
|
||||
<Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<MenuItem>
|
||||
<Link
|
||||
className={classNames(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href='https://roadmap.dify.ai'
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiMap2Line className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.roadmap')}</div>
|
||||
<RiArrowRightUpLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Link>}
|
||||
</Menu.Item>
|
||||
{systemFeatures.license.status === LicenseStatus.NONE && <Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<RiMap2Line className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.roadmap')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</Link>
|
||||
</MenuItem>
|
||||
{systemFeatures.license.status === LicenseStatus.NONE && <MenuItem>
|
||||
<Link
|
||||
className={classNames(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href='https://github.com/langgenius/dify'
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiGithubLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.github')}</div>
|
||||
<div className='flex items-center gap-0.5 px-[5px] py-[3px] border border-divider-deep rounded-[5px] bg-components-badge-bg-dimm'>
|
||||
<RiStarLine className='shrink-0 size-3 text-text-tertiary' />
|
||||
<RiGithubLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.github')}</div>
|
||||
<div className='flex items-center gap-0.5 rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-[5px] py-[3px]'>
|
||||
<RiStarLine className='size-3 shrink-0 text-text-tertiary' />
|
||||
<GithubStar className='system-2xs-medium-uppercase text-text-tertiary' />
|
||||
</div>
|
||||
</Link>}
|
||||
</Menu.Item>}
|
||||
</Link>
|
||||
</MenuItem>}
|
||||
{
|
||||
document?.body?.getAttribute('data-public-site-about') !== 'hide' && (
|
||||
<Menu.Item>
|
||||
{({ active }) => <div className={classNames(itemClassName, 'justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
<MenuItem>
|
||||
<div className={classNames(itemClassName, 'justify-between',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)} onClick={() => setAboutVisible(true)}>
|
||||
<RiInformation2Line className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.about')}</div>
|
||||
<div className='shrink-0 flex items-center'>
|
||||
<div className='mr-2 system-xs-regular text-text-tertiary'>{langeniusVersionInfo.current_version}</div>
|
||||
<RiInformation2Line className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.about')}</div>
|
||||
<div className='flex shrink-0 items-center'>
|
||||
<div className='system-xs-regular mr-2 text-text-tertiary'>{langeniusVersionInfo.current_version}</div>
|
||||
<Indicator color={langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version ? 'green' : 'orange'} />
|
||||
</div>
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
</div>
|
||||
</MenuItem>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<Menu.Item>
|
||||
{({ active }) => <div className='p-1' onClick={() => handleLogout()}>
|
||||
<MenuItem>
|
||||
<div className='p-1' onClick={() => handleLogout()}>
|
||||
<div
|
||||
className={classNames(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
>
|
||||
<RiLogoutBoxRLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.logout')}</div>
|
||||
<RiLogoutBoxRLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.logout')}</div>
|
||||
</div>
|
||||
</div>}
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { RiArrowRightSLine, RiArrowRightUpLine, RiDiscordLine, RiFeedbackLine, RiMailSendLine, RiQuestionLine } from '@remixicon/react'
|
||||
import { Fragment } from 'react'
|
||||
import Link from 'next/link'
|
||||
@@ -19,18 +19,18 @@ export default function Support() {
|
||||
const { userProfile, langeniusVersionInfo } = useAppContext()
|
||||
const canEmailSupport = plan.type === Plan.professional || plan.type === Plan.team || plan.type === Plan.enterprise
|
||||
|
||||
return <Menu as="div" className="relative w-full h-full">
|
||||
return <Menu as="div" className="relative h-full w-full">
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={
|
||||
cn('flex items-center pl-3 pr-2 py-2 h-9 w-full group hover:bg-state-base-hover rounded-lg gap-1',
|
||||
<MenuButton className={
|
||||
cn('group flex h-9 w-full items-center gap-1 rounded-lg py-2 pl-3 pr-2 hover:bg-state-base-hover',
|
||||
open && 'bg-state-base-hover',
|
||||
)}>
|
||||
<RiQuestionLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow text-left system-md-regular text-text-secondary px-1'>{t('common.userProfile.support')}</div>
|
||||
<RiArrowRightSLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Menu.Button>
|
||||
<RiQuestionLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-left text-text-secondary'>{t('common.userProfile.support')}</div>
|
||||
<RiArrowRightSLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -40,52 +40,52 @@ export default function Support() {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className={cn(
|
||||
`absolute top-[1px] w-[216px] max-h-[70vh] overflow-y-scroll z-10 bg-components-panel-bg-blur backdrop-blur-[5px] border-[0.5px] border-components-panel-border
|
||||
divide-y divide-divider-subtle origin-top-right rounded-xl focus:outline-none shadow-lg -translate-x-full
|
||||
`absolute top-[1px] z-10 max-h-[70vh] w-[216px] origin-top-right -translate-x-full divide-y divide-divider-subtle overflow-y-scroll
|
||||
rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-[5px] focus:outline-none
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<div className="px-1 py-1">
|
||||
{canEmailSupport && <Menu.Item>
|
||||
{({ active }) => <a
|
||||
{canEmailSupport && <MenuItem>
|
||||
<a
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href={mailToSupport(userProfile.email, plan.type, langeniusVersionInfo.current_version)}
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiMailSendLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.emailSupport')}</div>
|
||||
<RiArrowRightUpLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</a>}
|
||||
</Menu.Item>}
|
||||
<Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<RiMailSendLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.emailSupport')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</a>
|
||||
</MenuItem>}
|
||||
<MenuItem>
|
||||
<Link
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href='https://github.com/langgenius/dify/discussions/categories/feedbacks'
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiFeedbackLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.communityFeedback')}</div>
|
||||
<RiArrowRightUpLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Link>}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
{({ active }) => <Link
|
||||
<RiFeedbackLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.communityFeedback')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</Link>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<Link
|
||||
className={cn(itemClassName, 'group justify-between',
|
||||
active && 'bg-state-base-hover',
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)}
|
||||
href='https://discord.gg/5AEfbxcd9k'
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
<RiDiscordLine className='shrink-0 size-4 text-text-tertiary' />
|
||||
<div className='grow system-md-regular text-text-secondary px-1'>{t('common.userProfile.community')}</div>
|
||||
<RiArrowRightUpLine className='shrink-0 size-[14px] text-text-tertiary' />
|
||||
</Link>}
|
||||
</Menu.Item>
|
||||
<RiDiscordLine className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.community')}</div>
|
||||
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
|
||||
</Link>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Fragment } from 'react'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react'
|
||||
import { RiArrowDownSLine } from '@remixicon/react'
|
||||
import cn from '@/utils/classnames'
|
||||
import { switchWorkspace } from '@/service/common'
|
||||
@@ -30,22 +30,22 @@ const WorkplaceSelector = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu as="div" className="relative w-full h-full">
|
||||
<Menu as="div" className="relative h-full w-full">
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={cn(
|
||||
<MenuButton className={cn(
|
||||
`
|
||||
flex items-center p-0.5 gap-1.5 w-full
|
||||
group hover:bg-state-base-hover cursor-pointer ${open && 'bg-state-base-hover'} rounded-[10px]
|
||||
group flex w-full cursor-pointer items-center
|
||||
gap-1.5 p-0.5 hover:bg-state-base-hover ${open && 'bg-state-base-hover'} rounded-[10px]
|
||||
`,
|
||||
)}>
|
||||
<div className='flex items-center justify-center w-7 h-7 bg-[#EFF4FF] rounded-lg text-xs font-medium text-primary-600'>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='flex h-7 w-7 items-center justify-center rounded-lg bg-[#EFF4FF] text-xs font-medium text-primary-600'>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='flex flex-row'>
|
||||
<div className={'truncate max-w-[80px] text-text-secondary system-sm-medium'}>{currentWorkspace?.name}</div>
|
||||
<RiArrowDownSLine className='w-4 h-4 text-text-secondary' />
|
||||
<div className={'system-sm-medium max-w-[80px] truncate text-text-secondary'}>{currentWorkspace?.name}</div>
|
||||
<RiArrowDownSLine className='h-4 w-4 text-text-secondary' />
|
||||
</div>
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -55,28 +55,28 @@ const WorkplaceSelector = () => {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className={cn(
|
||||
`
|
||||
flex w-[280px] flex-col items-start absolute left-[-15px] mt-1 rounded-xl shadows-shadow-lg
|
||||
shadows-shadow-lg absolute left-[-15px] mt-1 flex w-[280px] flex-col items-start rounded-xl
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-col p-1 pb-2 items-start self-stretch w-full rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg ">
|
||||
<div className='flex px-3 pt-1 pb-0.5 items-start self-stretch'>
|
||||
<span className='flex-1 text-text-tertiary system-xs-medium-uppercase'>{t('common.userProfile.workspace')}</span>
|
||||
<div className="flex w-full flex-col items-start self-stretch rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 pb-2 shadow-lg ">
|
||||
<div className='flex items-start self-stretch px-3 pb-0.5 pt-1'>
|
||||
<span className='system-xs-medium-uppercase flex-1 text-text-tertiary'>{t('common.userProfile.workspace')}</span>
|
||||
</div>
|
||||
{
|
||||
workspaces.map(workspace => (
|
||||
<div className='flex py-1 pl-3 pr-2 items-center gap-2 self-stretch hover:bg-state-base-hover rounded-lg' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
|
||||
<div className='flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{workspace.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='line-clamp-1 grow overflow-hidden text-text-secondary text-ellipsis system-md-regular cursor-pointer'>{workspace.name}</div>
|
||||
<div className='flex items-center gap-2 self-stretch rounded-lg py-1 pl-3 pr-2 hover:bg-state-base-hover' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
|
||||
<div className='flex h-6 w-6 items-center justify-center rounded-md bg-[#EFF4FF] text-xs font-medium text-primary-600'>{workspace.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='system-md-regular line-clamp-1 grow cursor-pointer overflow-hidden text-ellipsis text-text-secondary'>{workspace.name}</div>
|
||||
<PlanBadge plan={workspace.plan as Plan} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user